Пример #1
0
 def init_state(self):
     """Queries Soho to initialize the attributes of the class"""
     state_parms = {
         "rop": soho.SohoParm("object:name", "string", key="rop"),
         "soho_outputmode": soho.SohoParm(
             "soho_outputmode", "integer", skipdefault=False, key="output_mode"
         ),
         "soho_diskfile": soho.SohoParm(
             "soho_diskfile", "string", skipdefault=False, key="disk_file"
         ),
         "hip": soho.SohoParm("$HIP", "string", key="hip"),
         "hipname": soho.SohoParm("$HIPNAME", "string", key="hipname"),
         "hipfile": soho.SohoParm("$HIPFILE", "string", key="hipfile"),
         "ver": soho.SohoParm(
             "state:houdiniversion", "string", ["9.0"], False, key="ver"
         ),
         "now": soho.SohoParm("state:time", "real", [0], False, key="now"),
         "fps": soho.SohoParm("state:fps", "real", [24], False, key="fps"),
         "pbrt_nanovdb_converter": soho.SohoParm(
             "pbrt_nanovdb_converter",
             "string",
             ["nanovdb_convert -z -f {vdb} {nanovdb}"],
             False,
             key="nanovdb_converter",
         ),
     }
     rop = soho.getOutputDriver()
     parms = soho.evaluate(state_parms, None, rop)
     for parm in parms:
         setattr(self, parm, parms[parm].Value[0])
     if not self.fps:
         self.fps = 24.0
     self.inv_fps = 1.0 / self.fps
     return
Пример #2
0
def wrangle_motionblur(obj, now):
    mb_parms = [soho.SohoParm('allowmotionblur', 'int', [0], False),
                soho.SohoParm('shutter', 'float', [0.5], False),
                soho.SohoParm('shutteroffset', 'float', [None], False),
                soho.SohoParm('motionstyle', 'string', ['trailing'], False),
               ]
    eval_mb_parms = obj.evaluate(mb_parms, now)
    if not eval_mb_parms[0].Value[0]:
        return None
    shutter = eval_mb_parms[1].Value[0] * scene_state.inv_fps
    offset = eval_mb_parms[2].Value[0]
    style = eval_mb_parms[3].Value[0]
    # This logic is in part from RIBmisc.py
    # NOTE: For pbrt output we will keep this limited to just shutter and
    #       shutteroffset, if the need arises we can add in the various
    #       scaling options etc.
    if style == 'centered':
        delta = shutter * 0.5
    elif style == 'leading':
        delta = shutter
    else: # trailing
        delta = 0.0
    delta -= (offset-1.0) * 0.5 * shutter
    start_time = now - delta
    end_time = start_time + shutter
    return ShutterRange(start_time, end_time)
Пример #3
0
    def add_aovs_to_ifd(self, wrangler, cam, now):
        """Add auto_aovs to the ifd.

        :param wrangler: A SOHO wrangler.
        :type wrangler: object
        :param cam: A SOHO camera.
        :type cam: soho.SohoObject
        :param now: The evaluation time.
        :type now: float
        :return:

        """
        import IFDapi
        import IFDsettings
        import soho

        # The parameter that defines which automatic aovs to add.
        parms = {
            "enable": soho.SohoParm(
                "enable_auto_aovs",
                "int",
                [1],
                skipdefault=False
            ),
            "auto_aovs": soho.SohoParm(
                "auto_aovs",
                "str",
                [""],
                skipdefault=False
            ),
        }

        # Attempt to evaluate the parameter.
        plist = cam.wrangle(wrangler, parms, now)

        if plist:
            # Adding is disabled so bail out.
            if plist["enable_auto_aovs"].Value[0] == 0:
                return

            aov_str = plist["auto_aovs"].Value[0]

            # Parse the string to get any aovs/groups.
            aov_items = self.get_aovs_from_string(aov_str)

            # Write any found items to the ifd.
            for item in aov_items:
                item.write_to_ifd(wrangler, cam, now)

            # If we are generating the "Op_Id" plane we will need to tell SOHO
            # to generate these properties when outputting object.  Look for
            # the "Op_Id" variable being exported and if so enable operator id
            # generation.
            for aov in flatten_aov_items(aov_items):
                if aov.variable == "Op_Id":
                    IFDapi.ray_comment("Forcing object id generation")
                    IFDsettings._GenerateOpId = True

                    break
Пример #4
0
def output_materials(obj, wrangler, now):
    """Output Materials for an object

    The shop_materialpath parameter and shop_materialpath prim attribute
    are both checked for output.
    """
    # We use a shaderhandle instead of a string so Soho instances are properly
    # resolved when Full Instancing is used.
    parms = [
        soho.SohoParm('shop_materialpath', 'shaderhandle', skipdefault=False)
    ]
    eval_parms = obj.evaluate(parms, now)
    if eval_parms:
        shop = eval_parms[0].Value[0]
        if shop:
            wrangle_shading_network(shop)

    soppath = []
    if not obj.evalString('object:soppath', now, soppath):
        return
    soppath = soppath[0]

    gdp = SohoGeometry(soppath, now)
    global_material = gdp.globalValue('shop_materialpath')
    if global_material is not None:
        wrangle_shading_network(global_material[0])

    attrib_h = gdp.attribute('geo:prim', 'shop_materialpath')
    if attrib_h >= 0:
        shop_materialpaths = gdp.attribProperty(attrib_h, 'geo:allstrings')
        for shop in shop_materialpaths:
            wrangle_shading_network(shop)
    return
Пример #5
0
    def write_to_ifd(self, wrangler, cam, now):
        """Output the AOV.

        :param wrangler: A SOHO wrangler.
        :type wrangler: object
        :param cam: A SOHO camera.
        :type cam: soho.SohoObject
        :param now: The evaluation time.
        :type now: float
        :return:

        """
        import soho

        # The base data to pass along.
        data = self.as_data()

        channel = self.channel

        # If there is no explicit channel set, use the variable name.
        if channel is None:
            channel = self.variable

        # Handle exporting of multiple components
        if self.componentexport:
            components = self.components

            # If no components are explicitly set on the AOV, use the
            # vm_exportcomponents parameter from the Mantra ROP.
            if not components:
                parms = {
                    "vm_exportcomponents": soho.SohoParm(
                        "vm_exportcomponents",
                        "str",
                        [""],
                        skipdefault=False
                    ),
                }

                plist = cam.wrangle(wrangler, parms, now)

                if plist:
                    components = plist["vm_exportcomponents"].Value[0]
                    components = components.split()

            # Create a unique channel for each component and output the block.
            for component in components:
                comp_data = copy.copy(data)
                comp_data[consts.CHANNEL_KEY] = "{}_{}".format(channel, component)
                comp_data[consts.COMPONENT_KEY] = component

                self._light_export_planes(comp_data, wrangler, cam, now)

        else:
            # Update the data with the channel.
            data[consts.CHANNEL_KEY] = channel

            self._light_export_planes(data, wrangler, cam, now)
Пример #6
0
 def init_state(self):
     """Queries Soho to initialize the attributes of the class"""
     state_parms = {
         "rop":
         soho.SohoParm("object:name", "string", key="rop"),
         "hip":
         soho.SohoParm("$HIP", "string", key="hip"),
         "hipname":
         soho.SohoParm("$HIPNAME", "string", key="hipname"),
         "hipfile":
         soho.SohoParm("$HIPFILE", "string", key="hipfile"),
         "ver":
         soho.SohoParm("state:houdiniversion",
                       "string", ["9.0"],
                       False,
                       key="ver"),
         "now":
         soho.SohoParm("state:time", "real", [0], False, key="now"),
         "fps":
         soho.SohoParm("state:fps", "real", [24], False, key="fps"),
     }
     rop = soho.getOutputDriver()
     parms = soho.evaluate(state_parms, None, rop)
     for parm in parms:
         setattr(self, parm, parms[parm].Value[0])
     if not self.fps:
         self.fps = 24.0
     self.inv_fps = 1.0 / self.fps
     return
Пример #7
0
 def init_state(self):
     """Queries Soho to initialize the attributes of the class"""
     state_parms = {
         'rop':
         soho.SohoParm('object:name', 'string', key='rop'),
         'hip':
         soho.SohoParm('$HIP', 'string', key='hip'),
         'hipname':
         soho.SohoParm('$HIPNAME', 'string', key='hipname'),
         'hipfile':
         soho.SohoParm('$HIPFILE', 'string', key='hipfile'),
         'ver':
         soho.SohoParm('state:houdiniversion',
                       'string', ["9.0"],
                       False,
                       key='ver'),
         'now':
         soho.SohoParm('state:time', 'real', [0], False, key='now'),
         'fps':
         soho.SohoParm('state:fps', 'real', [24], False, key='fps'),
     }
     rop = soho.getOutputDriver()
     parms = soho.evaluate(state_parms, None, rop)
     for parm in parms:
         setattr(self, parm, parms[parm].Value[0])
     if not self.fps:
         self.fps = 24.0
     self.inv_fps = 1.0 / self.fps
     return
Пример #8
0
    def getData(self, wrangler, cam, now):
        """Get the conditional data to apply.

        Args:
            wrangler : (Object)
                A wrangler object.

            cam : (soho.SohoObject)
                The camera being rendered.

            now : (float)
                The parameter evaluation time.

        Raises:
            N/A

        Returns:
            dict
                A dictionary of plane settings.

        This function matches the pattern against the specified parameter
        value and returns the corresponding match data.

        """
        import soho

        parmName = self.parmData["name"]

        # Build a dictionary containing the required SohoParm object.  We don't
        # want to skip defaults because if the parm is at its default we won't
        # be able to check against it.
        parms = {
            parmName: soho.SohoParm(
                parmName,
                self.parmData["type"],
                default=[self.parmData["default"]],
                skipdefault=False
            )
        }

        # Attempt to evaluate the parameter.
        plist = cam.wrangle(wrangler, parms, now)

        # Parameter exists and a value was found.
        if plist:
            # Get the parameter value.
            result = plist[parmName].Value[0]

            # Match the value against the pattern.  Return the corresponding
            # data.
            if re.match(self.pattern, result) is not None:
                return self.match

            else:
                return self.nomatch

        return {}
Пример #9
0
    def addAOVsToIfd(wrangler, cam, now):
        """Add auto_aovs to the ifd."""
        import IFDapi
        import IFDsettings
        import soho

        # The parameter that defines which automatic aovs to add.
        parms = {
            "enable":
            soho.SohoParm("enable_auto_aovs", "int", [1], skipdefault=False),
            "auto_aovs":
            soho.SohoParm("auto_aovs", "str", [""], skipdefault=False),
        }

        # Attempt to evaluate the parameter.
        plist = cam.wrangle(wrangler, parms, now)

        if plist:
            # Adding is disabled so bail out.
            if plist["enable_auto_aovs"].Value[0] == 0:
                return

            aov_str = plist["auto_aovs"].Value[0]

            # Construct a manager-laf
            manager = findOrCreateSessionAOVManager()

            # Parse the string to get any aovs/groups.
            aovs = manager.getAOVsFromString(aov_str)

            # Write any found items to the ifd.
            for aov in aovs:
                aov.writeToIfd(wrangler, cam, now)

            # If we are generating the "Op_Id" plane we will need to tell SOHO
            # to generate these properties when outputting object.  Look for
            # the "Op_Id" variable being exported and if so enable operator id
            # generation
            for aov in flattenedList(aovs):
                if aov.variable == "Op_Id":
                    IFDapi.ray_comment("Forcing object id generation")
                    IFDsettings._GenerateOpId = True

                    break
Пример #10
0
def addRenderPlanes(wrangler, cam, now):
    """Adds deep rasters as defined by a json file.

    Args:
        wrangler : (Object)
            A wrangler object, if any.

        cam : (soho.SohoObject)
            The camera being rendered.

        now : (float)
            The parameter evaluation time.

    Raises:
        N/A

    Returns:
        None

    """
    import soho

    # Check if automatic planes should be disabled.
    if _disablePlanes(wrangler, cam, now):
        return

    # The parameter that defines which automatic planes to add.
    parms = {"auto_planes": soho.SohoParm("auto_planes", "str", [""])}

    # Attempt to evaluate the parameter.
    plist = cam.wrangle(wrangler, parms, now)

    # Parameter exists.
    if plist:
        # Get the string value.
        planeStr = plist["auto_planes"].Value[0]

        if planeStr:
            # Split the string to get the group names.
            planeList = planeStr.split()

            # Build all existing groups.
            groups = buildPlaneGroups()

            # For each group available, if it matches the selection of groups
            # to add, write the planes to the ifd.
            for group in groups:
                if group.name in planeList:
                    group.writePlanesToIfd(wrangler, cam, now)
Пример #11
0
def output_materials(obj, wrangler, now):
    """Output Materials for an object

    The shop_materialpath parameter and shop_materialpath prim attribute
    are both checked for output.
    """
    # We use a shaderhandle instead of a string so Soho instances are properly
    # resolved when Full Instancing is used.
    parms = [soho.SohoParm('shop_materialpath', 'shaderhandle', skipdefault=False)]
    eval_parms = obj.evaluate(parms, now)
    if eval_parms:
        shop = eval_parms[0].Value[0]
        if shop:
            wrangle_shading_network(shop)

    soppath = []
    if not obj.evalString('object:soppath', now, soppath):
        return
    soppath = soppath[0]

    gdp = SohoGeometry(soppath, now)
    global_material = gdp.globalValue('shop_materialpath')
    if global_material is not None:
        wrangle_shading_network(global_material[0])

    attrib_h = gdp.attribute('geo:prim', 'shop_materialpath')
    if attrib_h >= 0:
        shop_materialpaths = gdp.attribProperty(attrib_h, 'geo:allstrings')
        for shop in shop_materialpaths:
            wrangle_shading_network(shop)

    # TODO / CONSIDER, for very large number of instance objects it might speed things
    #   up to cache the fact we've already visited a source network. Store in scenestate?
    #   (This will avoid much of the below on a per instance basis)
    instance_info = get_full_instance_info(obj)
    if instance_info is not None:
        instance_source = soho.getObject(instance_info.source)
        sourcesop_path = []
        if not instance_source.evalString('object:soppath', now, sourcesop_path):
            return
        sourcesop_path = sourcesop_path[0]
        gdp = SohoGeometry(sourcesop_path, now)
        attrib_h = gdp.attribute('geo:point', 'shop_materialpath')
        if attrib_h >= 0:
            shop_materialpaths = gdp.attribProperty(attrib_h, 'geo:allstrings')
            for shop in shop_materialpaths:
                wrangle_shading_network(shop)
    return
Пример #12
0
def _disablePlanes(wrangler, cam, now):
    import soho

    # The parameter that defines if planes should be disabled or not.
    parms = {"disable": soho.SohoParm("disable_auto_planes", "int", [False])}

    # Attempt to evaluate the parameter.
    plist = cam.wrangle(wrangler, parms, now)

    # Parameter exists.
    if plist:
        # If the parameter is set, return True to disable the planes.
        if plist["disable"].Value[0] == 1:
            return True

    return False
Пример #13
0
    def writeToIfd(self, wrangler, cam, now):
        """Output the AOV."""
        import soho

        # The base data to pass along.
        data = self.getData()

        channel = self.channel

        # If there is no explicit channel set, use the variable name.
        if channel is None:
            channel = self.variable

        # Handle exporting of multiple components
        if self.componentexport:
            components = self.components

            # If no components are explicitly set on the AOV, use the
            # vm_exportcomponents parameter from the Mantra ROP.
            if not components:
                parms = {
                    "components":
                    soho.SohoParm("vm_exportcomponents",
                                  "str", [""],
                                  skipdefault=False),
                }

                plist = cam.wrangle(wrangler, parms, now)

                if plist:
                    components = plist["vm_exportcomponents"].Value[0]
                    components = components.split()

            # Create a unique channel for each component and output the block.
            for component in components:
                data["channel"] = "{}_{}".format(channel, component)
                data["component"] = component

                self._lightExportPlanes(data, wrangler, cam, now)

        else:
            # Update the data with the channel.
            data["channel"] = channel

            self._lightExportPlanes(data, wrangler, cam, now)
Пример #14
0
    P *= cam_matrix.inverted()
    P *= projection_matrix
    P[0] = (P[0] / (P[3] * 2)) + .5
    P[1] = (P[1] / (P[3] * 2)) + .5
    P[2] /= P[3]
    P[3] = 1.0
    P = hou.Vector3(P)
    return P


node = hou.pwd()
module = node.hm()

controlParameters = {
    'now':
    soho.SohoParm('state:time', 'real', [0], False, key='now'),
    'fps':
    soho.SohoParm('state:fps', 'real', [24], False, key='fps'),
    'camera':
    soho.SohoParm('camera', 'string', ['/obj/cam1'], False),
    'vm_picture':
    soho.SohoParm('vm_picture', 'string', ['$HIP/render/$HIPNAME.$OS.$F4.svg'],
                  False),
    'render_viewcamera':
    soho.SohoParm('render_viewcamera', 'bool', [True], False),
    'projection_attribute':
    soho.SohoParm('projection_attribute', 'string', ['uv'], False),
    'attribute_rendering_resolution':
    soho.SohoParm('attribute_rendering_resolution', 'int', [1024, 1024],
                  False),
    'attribute_scale_by_resolution':
Пример #15
0
#
#
# \file pxh_usdlayeringROP.py
# \brief soho script to insert/remove usd sublayers
#

import hou
import os
import soho

################################################################################
# parameters
################################################################################

parameterDefines = {
    'trange': soho.SohoParm('trange', 'int', [0], False),
    'f': soho.SohoParm('f', 'real', [1, 1, 1], False),
    'irange': soho.SohoParm('irange', 'int', [0, 0, 1], False),
    'now': soho.SohoParm('state:time', 'real', [0], False, key='now'),
    'fps': soho.SohoParm('state:fps', 'real', [24.0], False, key='fps'),
}
for i in range(1, 6):
    parameterDefines['sourcefile' + str(i)] = soho.SohoParm(
        'sourcefile' + str(i), 'string', [''], False)
    parameterDefines['operation' + str(i)] = soho.SohoParm(
        'operation' + str(i), 'int', [0], False)
    parameterDefines['destfile' + str(i)] = soho.SohoParm(
        'destfile' + str(i), 'string', [''], False)

################################################################################
# main
Пример #16
0
        if refLayer.HasDefaultPrim():
            defaultPrim = refLayer.defaultPrim
        if len(refLayer.rootPrims) > 0:
            firstRoot = refLayer.rootPrims[0].path
    else:
        print("opening %s failed" % fileName)

    return (frameRange, defaultPrim, firstRoot)


###############################################################################
# parameters
###############################################################################

parameterDefines = {
    'f': soho.SohoParm('f', 'real', [1, 1, 1], False),
    'now': soho.SohoParm('state:time', 'real', [0], False, key='now'),
    'destfile': soho.SohoParm('destfile', 'string', [''], False),
    'path': soho.SohoParm('path', 'string', [''], False),
    'reffile': soho.SohoParm('reffile', 'string', [''], False),
}

parameters = soho.evaluate(parameterDefines)

#
# init soho
#
now = parameters['now'].Value[0]
soho.initialize(now, '')
soho.lockObjects(now)
Пример #17
0
def output_materials(obj, wrangler, now, skip_included=False):
    """Output Materials for an object

    The shop_materialpath parameter and shop_materialpath prim attribute
    are both checked for output.
    """
    # We use a shaderhandle instead of a string so Soho instances are properly
    # resolved when Full Instancing is used.
    parms = {
        "shop_materialpath":
        soho.SohoParm("shop_materialpath", "shaderhandle", skipdefault=False),
        "pbrt_include":
        soho.SohoParm("pbrt_include", "string", [""], skipdefault=True),
        "pbrt_import":
        soho.SohoParm("pbrt_import", "string", [""], skipdefault=True),
    }

    eval_parms = obj.evaluate(parms, now)

    if "shop_materialpath" in eval_parms:
        shop = eval_parms["shop_materialpath"].Value[0]
        if shop:
            wrangle_shading_network(shop)

    # If this object uses either an include or import statement then we assume internal
    # material definitions are already resolved through other means.
    if skip_included and ("pbrt_include" in eval_parms
                          or "pbrt_import" in eval_parms):
        return

    soppath = []
    if not obj.evalString("object:soppath", now, soppath):
        return

    soppath = soppath[0]

    gdp = SohoGeometry(soppath, now)
    global_material = gdp.globalValue("shop_materialpath")
    if global_material is not None:
        wrangle_shading_network(global_material[0])

    attrib_h = gdp.attribute("geo:prim", "shop_materialpath")
    if attrib_h >= 0:
        shop_materialpaths = gdp.attribProperty(attrib_h, "geo:allstrings")
        for shop in shop_materialpaths:
            wrangle_shading_network(shop)

    # TODO / CONSIDER, for very large number of instance objects it might speed things
    #   up to cache the fact we've already visited a source network.
    #   Store in scenestate?
    #   (This will avoid much of the below on a per instance basis)
    instance_info = get_full_instance_info(obj, now)
    if instance_info is None:
        return
    attrib_h = instance_info.gdp.attribute("geo:point", "shop_materialpath")
    if attrib_h >= 0:
        shop_materialpaths = instance_info.gdp.attribProperty(
            attrib_h, "geo:allstrings")
        for shop in shop_materialpaths:
            wrangle_shading_network(shop)
    return
Пример #18
0
    p1 = s1.split('/')
    p2 = s2.split('/')

    for i, c in enumerate(p1):
        if c != p2[i]:
            return '/'.join(p1[:i])

    return s1


###############################################################################
# parameters
###############################################################################

parameterDefines = {
    'ropname': soho.SohoParm('object:name', 'string', key='ropname'),
    'trange': soho.SohoParm('trange', 'int', [0], False),
    'f': soho.SohoParm('f', 'real', [1, 1, 1], False),
    'fps': soho.SohoParm('state:fps', 'real', [24.0], False, key='fps'),
    'now': soho.SohoParm('state:time', 'real', [0], False, key='now'),
    'sourcefiles': soho.SohoParm('sourcefiles', 'string', [], False),
    'outfile': soho.SohoParm('outfile', 'string', [''], False),
}


def main():

    parameters = soho.evaluate(parameterDefines)

    #
    # init soho
Пример #19
0
def wrangle_geo(obj, wrangler, now):
    parm_selection = {
        "object:soppath": SohoPBRT("object:soppath", "string", [""], skipdefault=False),
        "ptinstance": SohoPBRT("ptinstance", "integer", [0], skipdefault=False),
        # NOTE: In order for shop_materialpath to evaluate correctly when using
        #       (full) instancing shop_materialpath needs to be a 'shaderhandle'
        #       and not a 'string'
        # NOTE: However this does not seem to apply to shop_materialpaths on the
        #       instance points and has to be done manually
        "shop_materialpath": SohoPBRT(
            "shop_materialpath", "shaderhandle", skipdefault=False
        ),
        "soho_precision": SohoPBRT("soho_precision", "integer", [9], False),
        "pbrt_rendersubd": SohoPBRT("pbrt_rendersubd", "bool", [False], False),
        "pbrt_subdlevels": SohoPBRT(
            "pbrt_subdlevels", "integer", [3], False, key="levels"
        ),
        "pbrt_computeN": SohoPBRT("pbrt_computeN", "bool", [True], False),
        "pbrt_reverseorientation": SohoPBRT(
            "pbrt_reverseorientation", "bool", [False], True
        ),
        "pbrt_matchhoudiniuv": SohoPBRT("pbrt_matchhoudiniuv", "bool", [True], False),
        # The combination of None as a default as well as ignore defaults being False
        # is important. 'None' implying the parm is missing and not available,
        # and '' meaning a vacuum medium.
        # We can't ignore defaults since a default might be the only way to set a
        # medium back to a vacuum.
        "pbrt_interior": SohoPBRT("pbrt_interior", "string", [None], False),
        "pbrt_exterior": SohoPBRT("pbrt_exterior", "string", [None], False),
        "pbrt_ignorevolumes": SohoPBRT("pbrt_ignorevolumes", "bool", [False], True),
        "pbrt_ignorematerials": SohoPBRT("pbrt_ignorematerials", "bool", [False], True),
        "pbrt_splitdepth": SohoPBRT(
            "pbrt_splitdepth", "integer", [3], True, key="splitdepth"
        ),
        "pbrt_emissionfilename": SohoPBRT(
            "pbrt_emissionfilename", "string", [""], True
        ),
        "pbrt_curvetype": SohoPBRT("pbrt_curvetype", "string", ["flat"], True),
        "pbrt_include": SohoPBRT("pbrt_include", "string", [""], False),
        "pbrt_import": SohoPBRT("pbrt_import", "string", [""], False),
        "pbrt_alpha_texture": SohoPBRT(
            "pbrt_alpha_texture", "string", [""], False, key="alpha"
        ),
        "pbrt_allow_geofiles": soho.SohoParm(
            "pbrt_allow_geofiles", "integer", [1], False
        ),
        "pbrt_geo_location": soho.SohoParm(
            "pbrt_geo_location", "string", ["geometry"], False
        ),
        "pbrt_geofile_threshold": soho.SohoParm(
            "pbrt_geofile_threshold", "integer", [10000], False
        ),
        "pbrt_renderpoints": soho.SohoParm("pbrt_renderpoints", "bool", [False], False),
    }
    properties = obj.evaluate(parm_selection, now)

    if "shop_materialpath" not in properties:
        shop = ""
    else:
        shop = properties["shop_materialpath"].Value[0]

    # NOTE: Having to track down shop_materialpaths does not seem to be a requirement
    #       with Mantra or RenderMan. Either its because I'm missing some
    #       logic/initialization either in Soho or in the Shading HDAs. Or there is
    #       some hardcoding in the Houdini libs that know how to translate
    #       shop_materialpath point aassignments to shaders directly through a
    #       SohoParm. Until that is figured out, we'll have to do it manually.

    interior = None
    exterior = None
    if "pbrt_interior" in properties:
        interior = properties["pbrt_interior"].Value[0]
    if "pbrt_exterior" in properties:
        exterior = properties["pbrt_exterior"].Value[0]

    if "pbrt_reverseorientation" in properties:
        if properties["pbrt_reverseorientation"].Value[0]:
            api.ReverseOrientation()

    pt_shop_found = False
    if properties["ptinstance"].Value[0] == 1:
        instance_info = PBRTinstancing.get_full_instance_info(obj, now)
        properties[".instance_info"] = instance_info
        if instance_info is not None:
            pt_shop_found = process_full_pt_instance_material(instance_info)
            interior, interior_paramset = process_full_pt_instance_medium(
                instance_info, "interior"
            )
            exterior, exterior_paramset = process_full_pt_instance_medium(
                instance_info, "exterior"
            )
            if interior_paramset is not None:
                properties[".interior_overrides"] = interior_paramset

    # If we found a point shop, don't output the default one here.
    if shop in scene_state.shading_nodes and not pt_shop_found:
        api.NamedMaterial(shop)

    # We only output a MediumInterface if one or both of the parms exist
    if interior is not None or exterior is not None:
        interior = "" if interior is None else interior
        exterior = "" if exterior is None else exterior
        api.MediumInterface(interior, exterior)

    alpha_tex = properties["alpha"].Value[0]
    alpha_node = BaseNode.from_node(alpha_tex)
    if (
        alpha_node
        and alpha_node.directive == "texture"
        and alpha_node.output_type == "float"
    ):
        if alpha_node.path not in scene_state.shading_nodes:
            suffix = ":%s" % obj.getName()
            alpha_tex = "%s%s" % (alpha_tex, suffix)
            properties["alpha"].Value[0] = alpha_tex
            wrangle_shading_network(
                alpha_node.path, name_suffix=suffix, exported_nodes=set()
            )
    else:
        # If the passed in alpha_texture wasn't valid, clear it so we don't add
        # it to the geometry
        if alpha_tex:
            api.Comment("%s is an invalid float texture" % alpha_tex)
        properties["alpha"].Value[0] = ""

    if properties["pbrt_import"].Value[0]:
        # If we have included a file, skip output any geo.
        api.Import(properties["pbrt_import"].Value[0])
        return

    if properties["pbrt_include"].Value[0]:
        # If we have included a file, skip output any geo.
        api.Include(properties["pbrt_include"].Value[0])
        return

    soppath = properties["object:soppath"].Value[0]
    if not soppath:
        api.Comment("Can not find soppath for object")
        return

    shutter_times = wrangle_motionblur(obj, now)
    if shutter_times is not None:
        times = (shutter_times.open, shutter_times.close)
    else:
        times = (now,)

    if properties["pbrt_renderpoints"].Value[0]:
        PBRTgeo.output_pts(soppath, times, properties)
    else:
        PBRTgeo.output_geo(soppath, now, properties)

    return