Ejemplo n.º 1
0
def insertReference( destFile, path, reffile, primPath=None, offset=0, scale=1 ):

    if os.path.exists( destFile ):
        stage = Usd.Stage.Open( destFile )
        if not stage:
            soho.error("Could not open USD file: " + destFile)

        frameRange, defaultPrim, firstRoot = getMetaData( reffile )

        existingRefPath = None
        returnVal = None
        for p in stage.GetRootLayer().rootPrims:
            returnVal = findMatchingReference( p, reffile )
            if returnVal:
                break

        layerOffset = Sdf.LayerOffset(offset, scale)
        if returnVal:
            existingRefPath, existingPrimPath, existingLayerOffset = returnVal
            keepPrimPath = True
            if primPath:
                if primPath != existingPrimPath:
                    keepPrimPath = False
            elif defaultPrim and defaultPrim != existingPrimPath:
                keepPrimPath = False
            elif firstRoot and firstRoot.pathString  != existingPrimPath:
                keepPrimPath = False

            if ( existingRefPath == path and layerOffset == existingLayerOffset
                 and keepPrimPath ):
                # Our exact link already exists.
                sys.exit()
            else:
                # There is a existing link to our file but we want to rename it,
                # target a new prim path or add/change the layer offset.
                # Delete the old link.
                prim = stage.GetPrimAtPath( existingRefPath )
                refList = prim.GetReferences()
                existingRef = Sdf.Reference( reffile,
                                             existingPrimPath,
                                             layerOffset=existingLayerOffset )
                refList.RemoveReference(existingRef)
    else:
        frameRange, defaultPrim, firstRoot = getMetaData( reffile )
        stage = Usd.Stage.CreateNew( destFile )
        if not stage:
            soho.error( "Could not create USD file: " + destFile )

    if frameRange and not stage.HasAuthoredTimeCodeRange():
        stage.SetStartTimeCode(frameRange[0])
        stage.SetEndTimeCode(frameRange[1])

    # If the the file that we are referencing defines a default prim,
    # we can use it (targetPrim = None). Otherwise, use rootPrim. An existing
    # or provided prim path overrides either.
    if not primPath:
        primPath = firstRoot if not defaultPrim else None
    addReference( stage, path, reffile, primPath, layerOffset=layerOffset )
    stage.GetRootLayer().Save()
Ejemplo n.º 2
0
def _write_light(light, base_channel, data, wrangler, cam, now):
    """Write a light to the ifd.

    :param light: The light to write.
    :type light: soho.SohoObject
    :param base_channel: The channel name.
    :type base_channel: str
    :param data: AOV data.
    :type data: dict
    :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

    # Try and find the suffix using the 'vm_export_suffix'
    # parameter.  If it doesn't exist, use an empty string.
    suffix = light.getDefaultedString("vm_export_suffix", now, [''])[0]

    prefix = []

    # Look for the prefix parameter.  If it doesn't exist, use
    # the light's name and replace the '/' with '_'.  The
    # default value of 'vm_export_prefix' is usually $OS.
    if not light.evalString("vm_export_prefix", now, prefix):
        prefix = [light.getName()[1:].replace('/', '_')]

    # If there is a prefix we construct the channel name using
    # it and the suffix.
    if prefix:
        channel = "{}_{}{}".format(prefix[0], base_channel, suffix)

    # If not and there is a valid suffix, add it to the channel
    # name.
    elif suffix:
        channel = "{}{}".format(base_channel, suffix)

    # Throw an error because all the per-light channels will
    # have the same name.
    else:
        soho.error("Empty suffix for per-light exports.")
        channel = base_channel

    data[consts.CHANNEL_KEY] = channel
    data[consts.LIGHTEXPORT_KEY] = light.getName()

    # Write this light export to the ifd.
    _write_data_to_ifd(data, wrangler, cam, now)
Ejemplo n.º 3
0
def main():

    parameters = soho.evaluate(parameterDefines)

    #
    # init soho
    #
    logger = logging.getLogger()
    oldHandlers = logger.handlers
    handler = logging.StreamHandler( stream = sys.__stderr__ )
    logger.handlers = [handler]

    ropName = parameters['ropname'].Value[0]
    node = hou.node( ropName )
    vStr = node.type().nameComponents()[-1]
    version = 0 if not vStr else int( vStr )

    now = parameters['now'].Value[0]

    soho.initialize(now, '')
    soho.lockObjects(now)

    if parameters['trange'].Value[0] == 0:
        ff = lf = int(now * parameters['fps'].Value[0] + 1)
    else:
        ff = int(parameters['f'].Value[0])
        lf = int(parameters['f'].Value[1])
    stride = int(parameters['f'].Value[2])

    sourcefiles = parameters['sourcefiles'].Value[0]
    outfile = parameters['outfile'].Value[0]

    try:

        coalesceFiles( outfile, sourcefiles, range(ff,lf+1), stride )

    except Exception as e:
        soho.error( 'Failed to stitch USD files: ' + str(e) + '\n' + traceback.format_exc())

    finally:
        logger.handlers = oldHandlers
Ejemplo n.º 4
0
def insertReference( destFile, path, reffile ):

    if os.path.exists( destFile ):

        stage = Usd.Stage.Open( destFile )
        if not stage:
            soho.error("Could not open USD file: " + destFile)

        existingRefPath = None
        for p in stage.GetRootLayer().rootPrims:
            existingRefPath = findMatchingReference( p, reffile )
            if existingRefPath:
                break

        if existingRefPath:
            if existingRefPath == path:
                # Our link already exists. 
                sys.exit()
            else:
                # There is a existing link to our file but we want to rename it.
                # Delete the old link
                stage.RemovePrim(existingRefPath)

        frameRange, defaultPrim, firstRoot = getMetaData( reffile )

    else:

        frameRange, defaultPrim, firstRoot = getMetaData( reffile )

        stage = Usd.Stage.CreateNew( destFile )
        if not stage:
            soho.error( "Could not create USD file: " + destFile )

    if frameRange and not stage.HasAuthoredTimeCodeRange():
        stage.SetStartTimeCode(frameRange[0])
        stage.SetEndTimeCode(frameRange[1])

    # If the the file that we are referencing defines a default prim,
    # we can use it (targetPrim = None). Otherwise, use rootPrim.
    addReference( stage, path, reffile, firstRoot if not defaultPrim else None )
    stage.GetRootLayer().Save()
Ejemplo n.º 5
0
    def _lightExportPlanes(self, data, wrangler, cam, now):
        """Handle exporting the image planes based on their export settings."""
        import soho

        base_channel = data["channel"]

        # Handle any light exporting.
        if self.lightexport is not None:
            # Get a list of lights matching our mask and selection.
            lights = cam.objectList("objlist:light", now,
                                    self.lightexport_scope,
                                    self.lightexport_select)

            if self.lightexport == "per-light":
                # Process each light.
                for light in lights:
                    # Try and find the suffix using the 'vm_export_suffix'
                    # parameter.  If it doesn't exist, use an emptry string.
                    suffix = light.getDefaultedString("vm_export_suffix", now,
                                                      [''])[0]

                    prefix = []

                    # Look for the prefix parameter.  If it doesn't exist, use
                    # the light's name and replace the '/' with '_'.  The
                    # default value of 'vm_export_prefix' is usually $OS.
                    if not light.evalString("vm_export_prefix", now, prefix):
                        prefix = [light.getName()[1:].replace('/', '_')]

                    # If there is a prefix we construct the channel name using
                    # it and the suffix.
                    if prefix:
                        channel = "{}_{}{}".format(prefix[0], base_channel,
                                                   suffix)

                    # If not and there is a valid suffix, add it to the channel
                    # name.
                    elif suffix:
                        channel = "{}{}".format(base_channel, suffix)

                    # Throw an error because all the per-light channels will
                    # have the same name.
                    else:
                        soho.error("Empty suffix for per-light exports.")
                        channel = base_channel

                    data["channel"] = channel
                    data["lightexport"] = light.getName()

                    # Write this light export to the ifd.
                    self.writeDataToIfd(data, wrangler, cam, now)

            elif self.lightexport == "single":
                # Take all the light names and join them together.
                lightexport = ' '.join([light.getName() for light in lights])

                # If there are no lights, we can't pass in an empty string
                # since then mantra will think that light exports are
                # disabled.  So pass down an string that presumably doesn't
                # match any light name.
                if not lightexport:
                    lightexport = "__nolights__"

                data["lightexport"] = lightexport

                # Write the combined light export to the ifd.
                self.writeDataToIfd(data, wrangler, cam, now)

            elif self.lightexport == "per-category":
                # A mapping between category names and their member lights.
                category_map = {}

                # Process each selected light.
                for light in lights:
                    # Get the category for the light.
                    categories = []
                    light.evalString("categories", now, categories)

                    # Light doesn't have a 'categories' parameter.
                    if not categories:
                        continue

                    # Get the raw string.
                    categories = categories[0]

                    # Since the categories value can be space or comma
                    # separated we replace the commas with spaces then split.
                    categories = categories.replace(',', ' ')
                    categories = categories.split()

                    # If the categories list was empty, put the light in a fake
                    # category.
                    if not categories:
                        no_category_lights = category_map.setdefault(None, [])
                        no_category_lights.append(light)

                    else:
                        # For each category the light belongs to, add it to
                        # the list.
                        for category in categories:
                            category_lights = category_map.setdefault(
                                category, [])
                            category_lights.append(light)

                # Process all the found categories and their member lights.
                for category, lights in category_map.iteritems():
                    # Construct the export string to contain all the member
                    # lights.
                    lightexport = ' '.join(
                        [light.getName() for light in lights])

                    data["lightexport"] = lightexport

                    if category is not None:
                        # The channel is the regular channel named prefixed with
                        # the category name.
                        data["channel"] = "{}_{}".format(
                            category, base_channel)

                    else:
                        data["channel"] = base_channel

                    # Write the per-category light export to the ifd.
                    self.writeDataToIfd(data, wrangler, cam, now)

        else:
            # Write a normal AOV definition.
            self.writeDataToIfd(data, wrangler, cam, now)
Ejemplo n.º 6
0
def soho_render():
    control_parms = {
        # The time at which the scene is being rendered
        "now": SohoParm("state:time", "real", [0], False, key="now"),
        "camera": SohoParm("camera", "string", ["/obj/cam1"], False),
    }

    parms = soho.evaluate(control_parms)

    now = parms["now"].Value[0]
    camera = parms["camera"].Value[0]

    options = {}
    if not soho.initialize(now, camera, options):
        soho.error("Unable to initialize rendering module with given camera")

    object_selection = {
        # Candidate object selection
        "vobject": SohoParm("vobject", "string", ["*"], False),
        "alights": SohoParm("alights", "string", ["*"], False),
        "forceobject": SohoParm("forceobject", "string", [""], False),
        "forcelights": SohoParm("forcelights", "string", [""], False),
        "excludeobject": SohoParm("excludeobject", "string", [""], False),
        "excludelights": SohoParm("excludelights", "string", [""], False),
        "sololight": SohoParm("sololight", "string", [""], False),
    }

    for cam in soho.objectList("objlist:camera"):
        break
    else:
        soho.error("Unable to find viewing camera for render")

    objparms = cam.evaluate(object_selection, now)

    stdobject = objparms["vobject"].Value[0]
    stdlights = objparms["alights"].Value[0]
    forceobject = objparms["forceobject"].Value[0]
    forcelights = objparms["forcelights"].Value[0]
    excludeobject = objparms["excludeobject"].Value[0]
    excludelights = objparms["excludelights"].Value[0]
    sololight = objparms["sololight"].Value[0]
    forcelightsparm = "forcelights"

    if sololight:
        stdlights = excludelights = ""
        forcelights = sololight
        forcelightsparm = "sololight"

    # First, we add objects based on their display flags or dimmer values
    soho.addObjects(
        now,
        stdobject,
        stdlights,
        "",
        True,
        geo_parm="vobject",
        light_parm="alights",
        fog_parm="",
    )
    soho.addObjects(
        now,
        forceobject,
        forcelights,
        "",
        False,
        geo_parm="forceobject",
        light_parm=forcelightsparm,
        fog_parm="",
    )
    soho.removeObjects(
        now,
        excludeobject,
        excludelights,
        "",
        geo_parm="excludeobject",
        light_parm="excludelights",
        fog_parm="",
    )

    # Lock off the objects we've selected
    soho.lockObjects(now)

    with hou.undos.disabler(), scene_state:
        if "SOHO_PBRT_DEV" in os.environ:  # pragma: no coverage
            import cProfile

            pr = cProfile.Profile()
            pr.enable()
            try:
                PBRTscene.render(cam, now)
            finally:
                pr.disable()
                pr.dump_stats("hou-prbt.stats")
        else:
            PBRTscene.render(cam, now)
    return
Ejemplo n.º 7
0
project = bool(parmlist['render_viewcamera'].Value[0])
projection_attribute = parmlist['projection_attribute'].Value[0]
attribute_rendering_resolution = [
    parmlist['attribute_rendering_resolution'].Value[0],
    parmlist['attribute_rendering_resolution'].Value[1]
]
attribute_scale_by_resolution = bool(
    parmlist['attribute_scale_by_resolution'].Value[0])

now = parmlist['now'].Value[0]
camera = parmlist['camera'].Value[0]
fps = parmlist['fps'].Value[0]
options = {"state:autoheadlight": False}

if not soho.initialize(now=now, camera=camera, options=options):
    soho.error('Unable to initialize rendering module with camera: {0}'.format(
        repr(camera)))

for cam in soho.objectList('objlist:camera'):
    break
else:
    soho.error("Unable to find viewing camera for render")

camParms = {
    'space:world':
    soho.SohoParm('space:world', 'real',
                  [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], False),
    'focal':
    soho.SohoParm('focal', 'real', [0.050], False),
    'aperture':
    soho.SohoParm('aperture', 'real', [0.0414214], False),
    'orthowidth':
Ejemplo n.º 8
0
# Evaluate the 'camera' parameter as a string.
# If the 'camera' parameter # doesn't exist, use ['/obj/cam1'].
# SOHO always returns lists of values.
camera = soho.getDefaultedString('camera', ['/obj/cam1'])[0]

# However, for our purposes, we don't actually need a camera, so...
camera = None

# Evaluate an intrinsic parameter (see HDK_SOHO_API::evaluate())
# The 'state:time' parameter evaluates the time from the ROP.
evaltime = soho.getDefaultedFloat('state:time', [0.0])[0]

# Initialize SOHO with the camera.
if not soho.initialize(evaltime, camera):
    soho.error('Unable to initialize rendering module with camera: %s' %
               repr(camera))

# Now, add objects to our scene
#   addObjects(time, geometry, light, fog, use_display_flags)
soho.addObjects(evaltime, "*", "*", "*", True)

# Before we can evaluate the scene from SOHO, we need to lock the object lists.
soho.lockObjects(evaltime)


# Now, traverse all the objects
def outputObjects(fp, prefix, list):
    fp.write('%s = {' % prefix)
    for obj in list:
        fp.write('"%s",' % obj.getName())
    fp.write('}\n')
Ejemplo n.º 9
0
    def outputPlanes(self, wrangler, cam, now):
        """Output all necessary planes.

        Args:
            wrangler : (Object)
                A wrangler object.

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

            now : (float)
                The parameter evaluation time.

        Raises:
            N/A

        Returns:
            None

        """
        import soho

        # The base data to pass along.
        data = {
            "variable": self.variable,
            "vextype": self.vextype,
            "channel": self.channel,
            "quantize": self.quantize,
            "planefile": self.planefile
        }

        if self.pfilter:
            data["pfilter"] = self.pfilter

        if self.sfilter:
            data["sfilter"] = self.sfilter

        # Apply any conditionals before the light export phase.
        if self.conditionals:
            for conditional in self.conditionals:
                data.update(conditional.getData(wrangler, cam, now))

        # Handle any light exporting.
        if self.lightexport is not None:
            # Get a list of lights matching out mask and selection.
            lights = cam.objectList(
                "objlist:light",
                now,
                self.lightmask,
                self.lightselection
            )

            if self.lightexport == "per-light":
                # Process each light.
                for light in lights:
                    # Try and find the suffix using the 'vm_export_suffix'
                    # parameter.  If it doesn't exist, use an emptry string.
                    suffix = light.getDefaultedString(
                        "vm_export_suffix", now, ['']
                    )[0]

                    prefix = []

                    # Look for the prefix parameter.  If it doesn't exist, use
                    # the light's name and replace the '/' with '_'.  The
                    # default value of 'vm_export_prefix' is usually $OS.
                    if not light.evalString("vm_export_prefix", now, prefix):
                        prefix = [light.getName()[1:].replace('/', '_')]

                    # If there is a prefix we construct the channel name using
                    # it and the suffix.
                    if prefix:
                        channel = "{0}_{1}{2}".format(
                            prefix[0],
                            self.channel,
                            suffix
                        )

                    # If not and there is a valid suffix, add it to the channel
                    # name.
                    elif suffix:
                        channel = "{0}{1}".format(self.channel, suffix)

                    # Throw an error because all the per-light channels will
                    # have the same name.
                    else:
                        soho.error("Empty suffix for per-light exports.")

                    data["channel"] = channel
                    data["lightexport"] = light.getName()

                    # Write this light export to the ifd.
                    self.writeToIfd(data, wrangler, cam, now)

            elif self.lightexport == "single":
                # Take all the light names and join them together.
                lightexport = ' '.join([light.getName() for light in lights])

                # If there are no lights, we can't pass in an empty string
                # since then mantra will think that light exports are
                # disabled.  So pass down an string that presumably doesn't
                # match any light name.
                if not lightexport:
                    lightexport = "__nolights__"

                data["lightexport"] = lightexport

                # Write the combined light export to the ifd.
                self.writeToIfd(data, wrangler, cam, now)

            elif self.lightexport == "per-category":
                # A mapping between category names and their member lights.
                categoryMap = {}

                # Process each selected light.
                for light in lights:
                    # Get the category for the light.
                    categories = []
                    light.evalString("categories", now, categories)

                    # Light doesn't have a 'categories' parameter.
                    if not categories:
                        continue

                    # Get the raw string.
                    categories = categories[0]

                    # Since the categories value can be space or comma
                    # separated we replace the commas with spaces then split.
                    categories = categories.replace(',', ' ')
                    categories = categories.split()

                    # If the categories list was empty, put the light in a fake
                    # category.
                    if not categories:
                        noCatLights = categoryMap.setdefault("__none__", [])
                        noCatLights.append(light)

                    else:
                        # For each category the light belongs to, add it to
                        # the list.
                        for category in categories:
                            catLights = categoryMap.setdefault(category, [])
                            catLights.append(light)

                # Process all the found categories and their member lights.
                for category, lights in categoryMap.iteritems():
                    # Construct the export string to contain all the member
                    # lights.
                    lightexport = ' '.join(
                        [light.getName() for light in lights]
                    )

                    data["lightexport"] = lightexport

                    # The channel is the regular channel named prefixed with
                    # the category name.
                    data["channel"] = "{0}_{1}".format(category, self.channel)

                    # Write the per-category light export to the ifd.
                    self.writeToIfd(data, wrangler, cam, now)

        else:
            # Write a normal plane definition.
            self.writeToIfd(data, wrangler, cam, now)
Ejemplo n.º 10
0
###############################################################################

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)

destFile = parameters['destfile'].Value[0]
path = parameters['path'].Value[0]
reffile = parameters['reffile'].Value[0]

try:

    insertReference(destFile, path, reffile)

except Exception as e:

    soho.error('Failed to add USD file reference: ' + str(e))
Ejemplo n.º 11
0
def wrangle_camera(obj, wrangler, now):

    node = wrangle_node_parm(obj, "camera_node", now)
    if node is not None:
        output_cam_xform(obj, node.directive_type, now)
        return node.type_and_paramset

    paramset = ParamSet()

    window = obj.getCameraScreenWindow(wrangler, now)
    parm_selection = {
        "projection": SohoPBRT("projection", "string", ["perspective"], False),
        "focal": SohoPBRT("focal", "float", [50], False),
        "focalunits": SohoPBRT("focalunits", "string", ["mm"], False),
        "aperture": SohoPBRT("aperture", "float", [41.4214], False),
        "orthowidth": SohoPBRT("orthowidth", "float", [2], False),
        "res": SohoPBRT("res", "integer", [1280, 720], False),
        "aspect": SohoPBRT("aspect", "float", [1], False),
        "fstop": SohoPBRT("fstop", "float", [5.6], False),
        "focaldistance": SohoPBRT("focus", "float", [5], False, key="focaldistance"),
        "pbrt_dof": SohoPBRT("pbrt_dof", "integer", [0], False),
    }

    parms = obj.evaluate(parm_selection, now)
    aspect = parms["aspect"].Value[0]
    aspectfix = aspect * float(parms["res"].Value[0]) / float(parms["res"].Value[1])

    projection = parms["projection"].Value[0]

    if parms["pbrt_dof"].Value[0]:
        paramset.add(parms["focaldistance"].to_pbrt())
        # to convert from f-stop to lens radius
        # FStop = FocalLength / (Radius * 2)
        # Radius = FocalLength/(FStop * 2)
        focal = parms["focal"].Value[0]
        fstop = parms["fstop"].Value[0]
        units = parms["focalunits"].Value[0]
        focal = soho.houdiniUnitLength(focal, units)
        lens_radius = focal / (fstop * 2.0)
        paramset.add(PBRTParam("float", "lensradius", lens_radius))

    if projection == "perspective":
        projection_name = "perspective"

        focal = parms["focal"].Value[0]
        aperture = parms["aperture"].Value[0]
        fov = 2.0 * focal / aperture
        fov = 2.0 * math.degrees(math.atan2(1.0, fov))
        paramset.add(PBRTParam("float", "fov", [fov]))

        screen = [
            (window[0] - 0.5) * 2.0,
            (window[1] - 0.5) * 2.0,
            (window[2] - 0.5) * 2.0 / aspectfix,
            (window[3] - 0.5) * 2.0 / aspectfix,
        ]
        paramset.add(PBRTParam("float", "screenwindow", screen))

    elif projection == "ortho":
        projection_name = "orthographic"

        width = parms["orthowidth"].Value[0]
        screen = [
            (window[0] - 0.5) * width,
            (window[1] - 0.5) * width,
            (window[2] - 0.5) * width / aspectfix,
            (window[3] - 0.5) * width / aspectfix,
        ]
        paramset.add(PBRTParam("float", "screenwindow", screen))

    elif projection == "sphere":
        projection_name = "environment"
    else:
        soho.error("Camera projection setting of %s not supported by PBRT" % projection)

    output_cam_xform(obj, projection_name, now)

    return (projection_name, paramset)
Ejemplo n.º 12
0
    for sourcefile, operation, destfile in zip(sourcefiles, operations,
                                               destfiles):

        sourcefile = sourcefile.replace('%d', str(i))
        destfile = destfile.replace('%d', str(i))

        if not sourcefile or not destfile:
            continue

        inserting = operation == 0
        appending = operation == 1
        removing = operation == 2

        # check parms
        if not os.path.exists(destfile):
            soho.error("destfile does not exist: " + destfile)

        # modify the sublayers if needed
        from pxr import Sdf
        destLayer = Sdf.Layer.FindOrOpen(destfile)
        if not destLayer:
            soho.error("could not open destfile: " + destfile)

        if inserting:
            if sourcefile not in destLayer.subLayerPaths:
                if not os.access(destfile, os.W_OK):
                    soho.error("destfile is not writable: " + destfile)

                destLayer.subLayerPaths.insert(0, sourcefile)
                if not destLayer.Save():
                    soho.error("could not save destfile: " + destfile)
Ejemplo n.º 13
0
    def override_paramset(self, overrides):
        """Get a paramset with overrides applied

        Args:
            override_str (str): A string with the overrides (material_override)

        Returns:
            ParamSet with matching overrides applied
        """

        paramset = ParamSet()
        if not overrides:
            return paramset

        for override_name, override in overrides.iteritems():
            # The override can have a node_name/parm format which allows for point
            # instance overrides to override parms in a network.

            cached_override = self.override_cache.get(override_name, None)
            if cached_override is not None:
                if isinstance(cached_override, PBRTParam):
                    # textures which can't be overridden
                    paramset.add(cached_override)
                    continue
                elif cached_override == -1:
                    # Hint to just skip
                    continue
                pbrt_name, pbrt_type, tuple_names = cached_override
                if tuple_names:
                    value = [overrides[x] for x in tuple_names]
                else:
                    value = override
                pbrt_param = PBRTParam(pbrt_type, pbrt_name, value)
                paramset.add(pbrt_param)
                continue

            override_match = self.override_pat.match(override_name)
            if override_match is None:
                soho.error(
                    "{} is not a valid override parm".format(override_name))

            spectrum_type = override_match.group("spectrum")
            parm_name = override_match.group("parm")
            override_node = override_match.group("node")
            if override_node is not None and override_node != self.name:
                self.override_cache[override_name] = -1
                continue

            # There can be two style of "overrides" one is a straight parm override
            # which is similar to what Houdini does. The other style of override is
            # for the spectrum type parms. Since spectrum parms can be of different
            # types and the Material Overrides only support "rgb" we are limited
            # in the types of spectrum overrides we can do. To work around this we'll
            # support a different style, override_parm:spectrum_type. If the parm name
            # ends in one of the "rgb/color" types then we'll handle it differently.
            # TODO add a comment as to what the value would look like

            # NOTE: The material SOP will use a parm style dictionary if there
            #       parm name matches exactly
            #       ie) if there is a color parm you will get
            #       {'colorb':0.372511,'colorg':0.642467,'colorr':0.632117,}
            #       But if the parm name doesn't match (which we are allowing
            #       for you will get something like this -
            #       {'colora':(0.632117,0.642467,0.372511),}

            # Once we have a parm name, we need to determine what "style" it is.
            # Whether its a hou.ParmTuple or hou.Parm style.
            tuple_names = tuple()
            parm_tuple = self.node.parmTuple(parm_name)
            if parm_tuple is None:
                # We couldn't find a tuple of that name, so let's try a parm
                parm = self.node.parm(parm_name)
                if parm is None:
                    # Nope, not valid either, let's move along
                    self.override_cache[override_name] = -1
                    continue
                # if its a parm but not a parmtuple it must be a split.
                parm_tuple = parm.tuple()
                # we need to "combine" these and process them all at once and
                # then skip any other occurances. The skipping is handled by
                # the overall caching mechanism. self.override_cache
                tuple_names = tuple([x.name() for x in parm_tuple])

            # This is for wrangling parm names of texture nodes due to having a
            # signature parm.
            pbrt_name = self.pbrt_parm_name(parm_tuple)

            if spectrum_type is None and tuple_names:
                # This is a "traditional" override, no spectrum or node name prefix
                value = [overrides[x] for x in tuple_names]
                pbrt_param = self._hou_parm_to_pbrt_param(
                    parm_tuple, pbrt_name, value)
            elif spectrum_type is None and not tuple_names:
                pbrt_param = self._hou_parm_to_pbrt_param(
                    parm_tuple, pbrt_name, override)
            elif spectrum_type in PBRTParam.spectrum_types:
                pbrt_param = PBRTParam(spectrum_type, pbrt_name, override)
            else:
                raise ValueError("Unable to wrangle override name: %s" %
                                 override_name)

            paramset.add(pbrt_param)

            # From here to the end of the loop is to allow for caching

            if pbrt_param.type == "texture":
                self.override_cache[override_name] = pbrt_param
                continue

            # we are making an assumption a split parm will never be a spectrum
            # or have a node prefix. The Material SOP doesn't allow for it as well.
            for name in tuple_names:
                # The -1 means "continue"
                self.override_cache[name] = -1
            # Sanity check
            if tuple_names and override_name not in tuple_names:
                raise ValueError(
                    "Override name: %s, not valid for a parmTuple" %
                    override_name)
            # override_name must match one of the tuple_names
            self.override_cache[override_name] = (
                pbrt_param.name,
                pbrt_param.param_type,
                tuple_names,
            )
        return paramset
Ejemplo n.º 14
0
def soho_render():
    control_parms = {
        # The time at which the scene is being rendered
        "now": SohoParm("state:time", "real", [0], False, key="now")
    }

    parms = soho.evaluate(control_parms)

    now = parms["now"].Value[0]
    camera = None

    options = {}
    if not soho.initialize(now, camera, options):
        soho.error("Unable to initialize rendering module with given camera")

    object_selection = {
        # Candidate object selection
        "vobject": SohoParm("vobject", "string", ["*"], False),
        "forceobject": SohoParm("forceobject", "string", [""], False),
        "excludeobject": SohoParm("excludeobject", "string", [""], False),
    }

    objparms = soho.evaluate(object_selection, now)

    stdobject = objparms["vobject"].Value[0]
    forceobject = objparms["forceobject"].Value[0]
    excludeobject = objparms["excludeobject"].Value[0]

    # First, we add objects based on their display flags or dimmer values
    soho.addObjects(now,
                    stdobject,
                    "",
                    "",
                    True,
                    geo_parm="vobject",
                    light_parm="",
                    fog_parm="")
    soho.addObjects(
        now,
        forceobject,
        "",
        "",
        False,
        geo_parm="forceobject",
        light_parm="",
        fog_parm="",
    )
    soho.removeObjects(now,
                       excludeobject,
                       "",
                       "",
                       geo_parm="excludeobject",
                       light_parm="",
                       fog_parm="")

    # Lock off the objects we've selected
    soho.lockObjects(now)

    with hou.undos.disabler(), scene_state:
        if "SOHO_PBRT_DEV" in os.environ:  # pragma: no coverage
            import cProfile

            pr = cProfile.Profile()
            pr.enable()
            try:
                PBRTscene.archive(now)
            finally:
                pr.disable()
                pr.dump_stats("hou-prbtarchive.stats")
        else:
            PBRTscene.archive(now)
    return
Ejemplo n.º 15
0
    def outputPlanes(self, wrangler, cam, now):
        """Output all necessary planes.

        Args:
            wrangler : (Object)
                A wrangler object.

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

            now : (float)
                The parameter evaluation time.

        Raises:
            N/A

        Returns:
            None

        """
        import soho

        # The base data to pass along.
        data = {
            "variable": self.variable,
            "vextype": self.vextype,
            "channel": self.channel,
            "quantize": self.quantize,
            "planefile": self.planefile
        }

        if self.pfilter:
            data["pfilter"] = self.pfilter

        if self.sfilter:
            data["sfilter"] = self.sfilter

        # Apply any conditionals before the light export phase.
        if self.conditionals:
            for conditional in self.conditionals:
                data.update(conditional.getData(wrangler, cam, now))

        # Handle any light exporting.
        if self.lightexport is not None:
            # Get a list of lights matching out mask and selection.
            lights = cam.objectList("objlist:light", now, self.lightmask,
                                    self.lightselection)

            if self.lightexport == "per-light":
                # Process each light.
                for light in lights:
                    # Try and find the suffix using the 'vm_export_suffix'
                    # parameter.  If it doesn't exist, use an emptry string.
                    suffix = light.getDefaultedString("vm_export_suffix", now,
                                                      [''])[0]

                    prefix = []

                    # Look for the prefix parameter.  If it doesn't exist, use
                    # the light's name and replace the '/' with '_'.  The
                    # default value of 'vm_export_prefix' is usually $OS.
                    if not light.evalString("vm_export_prefix", now, prefix):
                        prefix = [light.getName()[1:].replace('/', '_')]

                    # If there is a prefix we construct the channel name using
                    # it and the suffix.
                    if prefix:
                        channel = "{0}_{1}{2}".format(prefix[0], self.channel,
                                                      suffix)

                    # If not and there is a valid suffix, add it to the channel
                    # name.
                    elif suffix:
                        channel = "{0}{1}".format(self.channel, suffix)

                    # Throw an error because all the per-light channels will
                    # have the same name.
                    else:
                        soho.error("Empty suffix for per-light exports.")

                    data["channel"] = channel
                    data["lightexport"] = light.getName()

                    # Write this light export to the ifd.
                    self.writeToIfd(data, wrangler, cam, now)

            elif self.lightexport == "single":
                # Take all the light names and join them together.
                lightexport = ' '.join([light.getName() for light in lights])

                # If there are no lights, we can't pass in an empty string
                # since then mantra will think that light exports are
                # disabled.  So pass down an string that presumably doesn't
                # match any light name.
                if not lightexport:
                    lightexport = "__nolights__"

                data["lightexport"] = lightexport

                # Write the combined light export to the ifd.
                self.writeToIfd(data, wrangler, cam, now)

            elif self.lightexport == "per-category":
                # A mapping between category names and their member lights.
                categoryMap = {}

                # Process each selected light.
                for light in lights:
                    # Get the category for the light.
                    categories = []
                    light.evalString("categories", now, categories)

                    # Light doesn't have a 'categories' parameter.
                    if not categories:
                        continue

                    # Get the raw string.
                    categories = categories[0]

                    # Since the categories value can be space or comma
                    # separated we replace the commas with spaces then split.
                    categories = categories.replace(',', ' ')
                    categories = categories.split()

                    # If the categories list was empty, put the light in a fake
                    # category.
                    if not categories:
                        noCatLights = categoryMap.setdefault("__none__", [])
                        noCatLights.append(light)

                    else:
                        # For each category the light belongs to, add it to
                        # the list.
                        for category in categories:
                            catLights = categoryMap.setdefault(category, [])
                            catLights.append(light)

                # Process all the found categories and their member lights.
                for category, lights in categoryMap.iteritems():
                    # Construct the export string to contain all the member
                    # lights.
                    lightexport = ' '.join(
                        [light.getName() for light in lights])

                    data["lightexport"] = lightexport

                    # The channel is the regular channel named prefixed with
                    # the category name.
                    data["channel"] = "{0}_{1}".format(category, self.channel)

                    # Write the per-category light export to the ifd.
                    self.writeToIfd(data, wrangler, cam, now)

        else:
            # Write a normal plane definition.
            self.writeToIfd(data, wrangler, cam, now)
Ejemplo n.º 16
0
def export():
	"""Main export function."""

	is_last = False

	try:
		T = timer('FrameExport')

		ps = soho.evaluate({
			'now':		SohoParm('state:time',			'real', [0],  False, key='now'),
			'fps':		SohoParm('state:fps',			'real', [24],  False, key='fps'),
			'hver':		SohoParm('state:houdiniversion',	'string', [''],  False, key='hver'),
			'objpath':	SohoParm('objpath',		'string',	[''], False),
			'abcoutput':	SohoParm('abcoutput',		'string',	[''], False),
			'camera':	SohoParm('camera',		'string',	[None], False),
			'trange':	SohoParm('trange',		'int',		[0], False),
			'f':		SohoParm('f',			'int',		None, False)
		})
		
		now = ps['now'].Value[0]
		fps = ps['fps'].Value[0]
		hver = ps['hver'].Value[0]
		camera = ps['camera'].Value[0]

		dbg("now=%.3f fps=%.3f" % (now, fps))

		if not soho.initialize(now, camera):
			soho.error("couldn't initialize soho (make sure camera is set)")
			abc_cleanup()
			return

		# NOTE: this is prone to float inaccuracies
		frame = now*fps + 1.0

		objpath   = ps['objpath'].Value[0]
		abc_file  = ps['abcoutput'].Value[0]
		trange    = ps['trange'].Value[0]
		f         = ps['f'].Value

		is_first  = frame < f[0]+0.5 # working around float funniness
		is_last   = frame > f[1]-0.5

		if trange==0:
			is_first= is_last= True

		dbg("is_first=%d is_last=%d" % (is_first, is_last))
		dbg("now=%.3f fps=%.3f -> %f" % (now, fps, frame))

		dbg("objpath=%s camera=%s abcoutput=%s trange=%d f=%s" % \
			(objpath, camera, abc_file, trange, str(f)))

		T.lap('init')

		# collect hierarchy to be exported
		# (read from scene directly, ie. not containing instances, etc.)
		# results in array [ (parentname, objname) [, ...]  ] -- (full pathnames)
		#
		#dbg("COLLECTING ARCHY:")
		archy = collect_archy(objpath)
		archy_objs = [ n[1] for n in archy ]
		#dbg("DONE.")


		# collect geometry to be exported and their render SOPS
		# (including point- and other instances, etc)
		# (NOTE: the entire scene is to be searched, unfortunately)
		#
		soho.addObjects(now, '*', '*', '', do_culling=False)
		soho.lockObjects(now)

		soho_objs = {} # {objname: soho_obj}
		soho_only = {} # soho-only objects (can't be accessed directly with hdk)

		obj_list = []
		sop_dict = {} # {objname: sopname}
		objs = soho.objectList('objlist:instance')

		#dbg("COLLECT soho instance/sop pairs ------------------")
		for obj in objs:
			n = obj.getName() # full pathname
			obj_list.append(n)
			soho_objs[n] = obj
			path = obj.getDefaultedString('object:soppath', now, [None])[0]
			#dbg(" -- %s (sop:%s)" % (n, str(path)) )
			if path and path!="":
				sop_dict[n] = path

		T.lap('collect-objs')

		if False:
			dbg( '-' * 40 )
			dbg("sop_dict: %s" % str(sop_dict))

		# extend hierarchy with per-point instances
		#
		p1 = re.compile(":[^:]+:")
		for obj in obj_list:
			if re.search(p1, obj):
				m = obj.split(":")
				p = m[-2] # parent: 2nd from right
				if p in archy_objs:
					archy.append( ( p, obj, "%s__%s" % (m[-2], m[-1]) )  )
					soho_only[obj]=p
					#dbg(" -+- %s %s" % (p, obj))


		# fill rest of the archy array
		# elem: (parentpath, objpath, exportname, soppath)
		#
		archy2 = []
		for a in archy:
			N = list(a)
			if len(N)<3: N.append(N[1]) # N = [ N[0], N[1], N[1] ]
			if N[1] in sop_dict:
				N = [ N[0], N[1], N[2], sop_dict[N[1]] ]
			else:
				# empty xform (no sop)
				N = [ N[0], N[1], N[1], None ]
			
			N[2] = re.search("[^/]+$", N[2]).group(0)
			archy2.append(N)
		archy = archy2

		if False:
			dbg( '-' * 40 )
			dbg("COLLECTED ARCHY:")
			for a in archy:
				dbg("- %s: " % (a[1], ))

		dbg("COLLECTED ARCHY: %d elems" % len(archy))

		T.lap('got-archy')

		# we now have a list of all objects to be exported
		# (parentname, objname, exportname, soppath)
		#
		archy_objs = [ n[1] for n in archy ]
		skip_frame = False

		now_out = now+(1.0/fps)

		# check for user abort
		#
		if False: # TODO: check for user abort!
			skip_frame = True
			is_last = True
			warn("user abort")


		# first frame: init all internal stuff
		#
		if is_first:
			dbg("\n\n\n")
			dbg("IS_FIRST--INIT")
			G.archy = archy[:]
			G.archy_objs = archy_objs[:]

			s = abc_init(abc_file, tstep=1.0/fps, tstart=now_out)
			if s:
				# build objects for oarchive
				#
				for E in archy:
					objname = E[1]
					parent  = E[0]
					outname = E[2]
					soppath = E[3]
					if parent is None: parent="-"
					if soppath is None: soppath="-"

					# TODO: if instance, objname should be the base obj name
					obj_src = objname
					if objname in soho_only:
						obj_src = soho_only[objname]

					#dbg("-- new xform\n\toutname= %s\n\tobj    = %s\n\tparent = %s\n\tsop    = %s" % (outname, objname, parent, soppath))

					hou.hscript('%s newobject "%s" "%s" "%s" "%s" "%s"' % \
						(CCMD, objname, obj_src, parent, outname, soppath))

					# set object flags (static, etc.)
					#
					if objname in soho_objs:
						ps = soho_objs[objname].evaluate({
							'abc_staticgeo': SohoParm('abc_staticgeo', 'int', [0], False)
						}, now)

						if ps['abc_staticgeo'].Value[0]!=0:
							hou.hscript('%s objset "%s" static' % (CCMD, objname))

			else:
				warn("couldn't output to file %s--aborting" % abc_file)
				skip_frame = True
				is_last = True

		T.lap('frame-first')


		# frame export: collect xforms, geoms, and export them
		#
		if archy_objs==G.archy_objs  and  not skip_frame:

			dbg("\n")
			dbg(" -- EXPORTING frame %.1f" % frame)

			for E in archy:
				#dbg("\n-")
				#dbg("- OBJ: %s" % str(E))
				objname = E[1]
				soppath = E[3]
				#dbg("- OBJ: %s" % E[1])

				# get xform matrix (TODO: get pretransform too!)
				#
				xform = ''

				# TODO: use this only for instances!
				#if objname in soho_objs:
				if objname in soho_only:
					# get matrix from soho
					#dbg(" --- (mtx from soho)")
					xform = []
					soho_objs[objname].evalFloat('space:local', now, xform)
					xform = hou.Matrix4(xform)
					xform = ' '.join([ str(n) for n in xform.asTuple() ])

				# perform sample write
				# (c++ code decides if geom is to be written)
				#
				if True:
					hou.hscript('%s writesample %f "%s" %s' % \
						(CCMD, now_out, objname, xform))

		else:
			#soho.error("couldn't export frame %.1f--no. of objects changed" % frame)
			warn("couldn't export frame %.1f--no. of objects changed" % frame)


		T.lap('frame-export')

	except:
		dbg("INTERRUPTED BY EXCEPTION")
		is_last=True


	# last frame: cleanup all internal stuff,
	# finish export
	#
	if is_last:
		dbg("\n\n\n")
		dbg("IS_LAST--FINISHING...")
		abc_cleanup()

	T.lap('frame-last')

	T.stats()
Ejemplo n.º 17
0
parmlist = soho.evaluate(controlParameters)

now     = parmlist['now'].Value[0]
IFDapi.ForceEmbedVex = parmlist['embedvex'].Value[0]
decl_shops = parmlist['decl'].Value[0]

inheritedproperties = parmlist['vm_inheritproperties'].Value[0]

options = {}
if inheritedproperties:
    # Turn off object->output driver inheritance
    options['state:inheritance'] = '-rop'

    
if not soho.initialize(now, None):
    soho.error("Unable to initialize rendering module")
    
#
# Add objects to the scene, we check for parameters on the viewing
# camera.  If the parameters don't exist there, they will be picked up
# by the output driver.
#
objectSelection = {
    # Candidate object selection
    # Candidate object selection
    'vobject'     : SohoParm('vobject', 'string',       ['*'], False),
    'alights'     : SohoParm('alights', 'string',       ['*'], False),
    'vfog'        : SohoParm('vfog',    'string',       ['*'], False),

    'forceobject' : SohoParm('forceobject',     'string',       [''], False),
    'forcelights' : SohoParm('forcelights',     'string',       [''], False),
Ejemplo n.º 18
0
# Extract the values from the evaluation
now     = parmlist['now'].Value[0]
camera  = parmlist['camera'].Value[0]
fps     = parmlist['fps'].Value[0]
picture = parmlist['vm_picture'].Value[0]
samples = parmlist['vm_samples'].Value[0]
sampler = parmlist['vm_sampler'].Value[0]
reflectlimit = parmlist['vm_reflectlimit'].Value[0]
integrator   = parmlist['vm_integrator'].Value[0]
camera       = parmlist['camera'].Value[0]
skip_geo_export = parmlist['skip_geo_export'].Value[0]


if not soho.initialize(now, camera):
    soho.error("Unable to initialize rendering module with given camera")

objectSelection = {
    # Candidate object selection
    'vobject'     : SohoParm('vobject', 'string',       ['*'], False),
    'alights'     : SohoParm('alights', 'string',       ['*'], False),
    'vfog'        : SohoParm('vfog',    'string',       ['*'], False),

    'forceobject' : SohoParm('forceobject',     'string',       [''], False),
    'forcelights' : SohoParm('forcelights',     'string',       [''], False),
    'forcefog'    : SohoParm('forcefog',        'string',       [''], False),

    'excludeobject' : SohoParm('excludeobject', 'string',       [''], False),
    'excludelights' : SohoParm('excludelights', 'string',       [''], False),
    'excludefog'    : SohoParm('excludefog',    'string',       [''], False),
Ejemplo n.º 19
0
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)

destFile =  parameters['destfile'].Value[0]
path     =  parameters['path'].Value[0]
reffile  =  parameters['reffile'].Value[0]

try:

    insertReference( destFile, path, reffile )

except Exception as e:

    soho.error( 'Failed to add USD file reference: ' + str(e) )


Ejemplo n.º 20
0
    for sourcefile, operation, destfile in zip(sourcefiles, operations, destfiles):

        sourcefile = sourcefile.replace('%d',str(i) )
        destfile = destfile.replace('%d',str(i) )

        if not sourcefile or not destfile:
            continue
        
        inserting = operation == 0
        appending = operation == 1
        removing  = operation == 2
        
        # check parms
        if not os.path.exists(destfile):
            soho.error("destfile does not exist: " + destfile)
        
        # modify the sublayers if needed
        from pxr import Sdf
        destLayer = Sdf.Layer.FindOrOpen(destfile)
        if not destLayer:
            soho.error("could not open destfile: " + destfile)
        
        if inserting:
           if sourcefile not in destLayer.subLayerPaths:
                if not os.access(destfile, os.W_OK):
                    soho.error("destfile is not writable: " + destfile)
               
                destLayer.subLayerPaths.insert(0,sourcefile)
                if not destLayer.Save():
                    soho.error("could not save destfile: " + destfile)
Ejemplo n.º 21
0
def soho_render():
    control_parms = {
        # The time at which the scene is being rendered
        'now': SohoParm('state:time', 'real', [0], False, key='now'),
        'fps': SohoParm('state:fps', 'real', [24], False, key='fps'),
        'camera': SohoParm('camera', 'string', ['/obj/cam1'], False),
    }

    parms = soho.evaluate(control_parms)

    now = parms['now'].Value[0]
    camera = parms['camera'].Value[0]
    fps = parms['fps'].Value[0]

    options = {'state:precision': 6}
    if not soho.initialize(now, camera, options):
        soho.error("Unable to initialize rendering module with given camera")

    object_selection = {
        # Candidate object selection
        'vobject': SohoParm('vobject', 'string', ['*'], False),
        'alights': SohoParm('alights', 'string', ['*'], False),
        'forceobject': SohoParm('forceobject', 'string', [''], False),
        'forcelights': SohoParm('forcelights', 'string', [''], False),
        'excludeobject': SohoParm('excludeobject', 'string', [''], False),
        'excludelights': SohoParm('excludelights', 'string', [''], False),
        'sololight': SohoParm('sololight', 'string', [''], False),
    }

    for cam in soho.objectList('objlist:camera'):
        break
    else:
        soho.error('Unable to find viewing camera for render')

    objparms = cam.evaluate(object_selection, now)

    stdobject = objparms['vobject'].Value[0]
    stdlights = objparms['alights'].Value[0]
    forceobject = objparms['forceobject'].Value[0]
    forcelights = objparms['forcelights'].Value[0]
    excludeobject = objparms['excludeobject'].Value[0]
    excludelights = objparms['excludelights'].Value[0]
    sololight = objparms['sololight'].Value[0]
    forcelightsparm = 'forcelights'

    if sololight:
        stdlights = excludelights = None
        forcelights = sololight
        forcelightsparm = 'sololight'

    # First, we add objects based on their display flags or dimmer values
    soho.addObjects(now, stdobject, stdlights, '', True)
    soho.addObjects(now, forceobject, forcelights, '', False)
    soho.removeObjects(now, excludeobject, excludelights, '')

    # Lock off the objects we've selected
    soho.lockObjects(now)

    with hou.undos.disabler(), scene_state:
        PBRTscene.render(cam, now)
    return
Ejemplo n.º 22
0
def export():
    """Main export function."""

    is_last = False

    try:
        T = timer('FrameExport')

        ps = soho.evaluate({
            'now':
            SohoParm('state:time', 'real', [0], False, key='now'),
            'fps':
            SohoParm('state:fps', 'real', [24], False, key='fps'),
            'hver':
            SohoParm('state:houdiniversion', 'string', [''], False,
                     key='hver'),
            'objpath':
            SohoParm('objpath', 'string', [''], False),
            'abcoutput':
            SohoParm('abcoutput', 'string', [''], False),
            'camera':
            SohoParm('camera', 'string', [None], False),
            'trange':
            SohoParm('trange', 'int', [0], False),
            'f':
            SohoParm('f', 'int', None, False)
        })

        now = ps['now'].Value[0]
        fps = ps['fps'].Value[0]
        hver = ps['hver'].Value[0]
        camera = ps['camera'].Value[0]

        dbg("now=%.3f fps=%.3f" % (now, fps))

        if not soho.initialize(now, camera):
            soho.error("couldn't initialize soho (make sure camera is set)")
            abc_cleanup()
            return

        # NOTE: this is prone to float inaccuracies
        frame = now * fps + 1.0

        objpath = ps['objpath'].Value[0]
        abc_file = ps['abcoutput'].Value[0]
        trange = ps['trange'].Value[0]
        f = ps['f'].Value

        is_first = frame < f[0] + 0.5  # working around float funniness
        is_last = frame > f[1] - 0.5

        if trange == 0:
            is_first = is_last = True

        dbg("is_first=%d is_last=%d" % (is_first, is_last))
        dbg("now=%.3f fps=%.3f -> %f" % (now, fps, frame))

        dbg("objpath=%s camera=%s abcoutput=%s trange=%d f=%s" % \
         (objpath, camera, abc_file, trange, str(f)))

        T.lap('init')

        # collect hierarchy to be exported
        # (read from scene directly, ie. not containing instances, etc.)
        # results in array [ (parentname, objname) [, ...]  ] -- (full pathnames)
        #
        #dbg("COLLECTING ARCHY:")
        archy = collect_archy(objpath)
        archy_objs = [n[1] for n in archy]
        #dbg("DONE.")

        # collect geometry to be exported and their render SOPS
        # (including point- and other instances, etc)
        # (NOTE: the entire scene is to be searched, unfortunately)
        #
        soho.addObjects(now, '*', '*', '', do_culling=False)
        soho.lockObjects(now)

        soho_objs = {}  # {objname: soho_obj}
        soho_only = {
        }  # soho-only objects (can't be accessed directly with hdk)

        obj_list = []
        sop_dict = {}  # {objname: sopname}
        objs = soho.objectList('objlist:instance')

        #dbg("COLLECT soho instance/sop pairs ------------------")
        for obj in objs:
            n = obj.getName()  # full pathname
            obj_list.append(n)
            soho_objs[n] = obj
            path = obj.getDefaultedString('object:soppath', now, [None])[0]
            #dbg(" -- %s (sop:%s)" % (n, str(path)) )
            if path and path != "":
                sop_dict[n] = path

        T.lap('collect-objs')

        if False:
            dbg('-' * 40)
            dbg("sop_dict: %s" % str(sop_dict))

        # extend hierarchy with per-point instances
        #
        p1 = re.compile(":[^:]+:")
        for obj in obj_list:
            if re.search(p1, obj):
                m = obj.split(":")
                p = m[-2]  # parent: 2nd from right
                if p in archy_objs:
                    archy.append((p, obj, "%s__%s" % (m[-2], m[-1])))
                    soho_only[obj] = p
                    #dbg(" -+- %s %s" % (p, obj))

        # fill rest of the archy array
        # elem: (parentpath, objpath, exportname, soppath)
        #
        archy2 = []
        for a in archy:
            N = list(a)
            if len(N) < 3: N.append(N[1])  # N = [ N[0], N[1], N[1] ]
            if N[1] in sop_dict:
                N = [N[0], N[1], N[2], sop_dict[N[1]]]
            else:
                # empty xform (no sop)
                N = [N[0], N[1], N[1], None]

            N[2] = re.search("[^/]+$", N[2]).group(0)
            archy2.append(N)
        archy = archy2

        if False:
            dbg('-' * 40)
            dbg("COLLECTED ARCHY:")
            for a in archy:
                dbg("- %s: " % (a[1], ))

        dbg("COLLECTED ARCHY: %d elems" % len(archy))

        T.lap('got-archy')

        # we now have a list of all objects to be exported
        # (parentname, objname, exportname, soppath)
        #
        archy_objs = [n[1] for n in archy]
        skip_frame = False

        now_out = now + (1.0 / fps)

        # check for user abort
        #
        if False:  # TODO: check for user abort!
            skip_frame = True
            is_last = True
            warn("user abort")

        # first frame: init all internal stuff
        #
        if is_first:
            dbg("\n\n\n")
            dbg("IS_FIRST--INIT")
            G.archy = archy[:]
            G.archy_objs = archy_objs[:]

            s = abc_init(abc_file, tstep=1.0 / fps, tstart=now_out)
            if s:
                # build objects for oarchive
                #
                for E in archy:
                    objname = E[1]
                    parent = E[0]
                    outname = E[2]
                    soppath = E[3]
                    if parent is None: parent = "-"
                    if soppath is None: soppath = "-"

                    # TODO: if instance, objname should be the base obj name
                    obj_src = objname
                    if objname in soho_only:
                        obj_src = soho_only[objname]

                    #dbg("-- new xform\n\toutname= %s\n\tobj    = %s\n\tparent = %s\n\tsop    = %s" % (outname, objname, parent, soppath))

                    hou.hscript('%s newobject "%s" "%s" "%s" "%s" "%s"' % \
                     (CCMD, objname, obj_src, parent, outname, soppath))

                    # set object flags (static, etc.)
                    #
                    if objname in soho_objs:
                        ps = soho_objs[objname].evaluate(
                            {
                                'abc_staticgeo':
                                SohoParm('abc_staticgeo', 'int', [0], False)
                            }, now)

                        if ps['abc_staticgeo'].Value[0] != 0:
                            hou.hscript('%s objset "%s" static' %
                                        (CCMD, objname))

            else:
                warn("couldn't output to file %s--aborting" % abc_file)
                skip_frame = True
                is_last = True

        T.lap('frame-first')

        # frame export: collect xforms, geoms, and export them
        #
        if archy_objs == G.archy_objs and not skip_frame:

            dbg("\n")
            dbg(" -- EXPORTING frame %.1f" % frame)

            for E in archy:
                #dbg("\n-")
                #dbg("- OBJ: %s" % str(E))
                objname = E[1]
                soppath = E[3]
                #dbg("- OBJ: %s" % E[1])

                # get xform matrix (TODO: get pretransform too!)
                #
                xform = ''

                # TODO: use this only for instances!
                #if objname in soho_objs:
                if objname in soho_only:
                    # get matrix from soho
                    #dbg(" --- (mtx from soho)")
                    xform = []
                    soho_objs[objname].evalFloat('space:local', now, xform)
                    xform = hou.Matrix4(xform)
                    xform = ' '.join([str(n) for n in xform.asTuple()])

                # perform sample write
                # (c++ code decides if geom is to be written)
                #
                if True:
                    hou.hscript('%s writesample %f "%s" %s' % \
                     (CCMD, now_out, objname, xform))

        else:
            #soho.error("couldn't export frame %.1f--no. of objects changed" % frame)
            warn("couldn't export frame %.1f--no. of objects changed" % frame)

        T.lap('frame-export')

    except:
        dbg("INTERRUPTED BY EXCEPTION")
        is_last = True

    # last frame: cleanup all internal stuff,
    # finish export
    #
    if is_last:
        dbg("\n\n\n")
        dbg("IS_LAST--FINISHING...")
        abc_cleanup()

    T.lap('frame-last')

    T.stats()
Ejemplo n.º 23
0
# -*- coding: utf-8 -*-

import hou
import soho

import afanasy

current_afnode = hou.pwd()

submit_afnode_parm = current_afnode.parm('submit_afnode')
if submit_afnode_parm is None:
	soho.error(
		'Can\'t find "submit_afnode" parameter on "%s"' % current_afnode.path()
	)

submit_afnode_path = submit_afnode_parm.eval()
if submit_afnode_path is None:
	soho.error(
		'Can\'t eval "submit_afnode" parameter on "%s"' % current_afnode.path()
	)

if submit_afnode_path == '':
	soho.error(
		'Empty "submit_afnode" parameter on "%s"' % current_afnode.path()
	)

submit_afnode = hou.node(submit_afnode_path)
if submit_afnode is None:
	soho.error(
		'Can\'t find "%s" node specified in "%s"' %
		(submit_afnode_path, current_afnode.path())
Ejemplo n.º 24
0
def main():
    import sys
    import hou

    import soho
    import sohoglue
    import SOHOcommon

    import sys
    import ctypes
    if hasattr(sys, 'setdlopenflags'):
        sys.setdlopenflags(sys.getdlopenflags() | ctypes.RTLD_GLOBAL)

    import _vfh_ipr

    from soho import SohoParm

    LogLevel = type('Enum', (), {
        'Msg': 0,
        'Info': 1,
        'Progress': 2,
        'Warning': 3,
        'Error': 4,
        'Debug': 5
    })

    def logMessage(level, fmt, *args):
        _vfh_ipr.logMessage(level, fmt % args)

    def printDebug(fmt, *args):
        logMessage(LogLevel.Debug, fmt, *args)

    def dumpObjects(listName):
        printDebug("Checking \"%s\"" % listName)
        for obj in soho.objectList(listName):
            printDebug("   %s", obj.getName())

    def exportObjects(listName):
        for obj in soho.objectList(listName):
            _vfh_ipr.exportOpNode(opNode=obj.getName())

    def deleteObjects(listName):
        for obj in soho.objectList(listName):
            _vfh_ipr.deleteOpNode(opNode=obj.getName())

    def getViewParams(camera, sohoCam, t):
        camParms = {
            'space:world': SohoParm('space:world', 'real', [], False),
            'focal': SohoParm('focal', 'real', [0.050], False),
            'aperture': SohoParm('aperture', 'real', [0.0414214], False),
            'orthowidth': SohoParm('orthowidth', 'real', [2], False),
            'near': SohoParm('near', 'real', [0.001], False),
            'far': SohoParm('far', 'real', [1000], False),
            'res': SohoParm('res', 'int', [640, 480], False),
            'projection': SohoParm('projection', 'string', ["perspective"],
                                   False),
            'cropl': SohoParm('cropl', 'real', [-1], False),
            'cropr': SohoParm('cropr', 'real', [-1], False),
            'cropb': SohoParm('cropb', 'real', [-1], False),
            'cropt': SohoParm('cropt', 'real', [-1], False),
            'camera': SohoParm('camera', 'string', ['/obj/cam1'], False),
        }

        camParmsEval = sohoCam.evaluate(camParms, t)
        if not camParmsEval:
            return {}

        viewParams = {}
        for key in camParmsEval:
            viewParams[key] = camParmsEval[key].Value[0]

        viewParams['transform'] = camParmsEval['space:world'].Value
        viewParams['ortho'] = 1 if camParmsEval['projection'].Value[0] in {
            'ortho'
        } else 0
        viewParams['res'] = camParmsEval['res'].Value

        cropX = viewParams['res'][0] * viewParams['cropl']
        cropY = viewParams['res'][1] * (1.0 - viewParams['cropt'])
        cropW = viewParams['res'][0] * (viewParams['cropr'] -
                                        viewParams['cropl'])
        cropH = viewParams['res'][1] * (viewParams['cropt'] -
                                        viewParams['cropb'])

        printDebug("  Res: %s" % viewParams['res'])
        printDebug("  Crop: %i-%i %i x %i" % (cropX, cropY, cropW, cropH))
        printDebug("  Camera: %s" % camera)

        return viewParams

    def exportView(rop, camera, sohoCam, t):
        printDebug("exportView()")

        _vfh_ipr.exportView(viewParams=getViewParams(camera, sohoCam, t))

    mode = soho.getDefaultedString('state:previewmode', ['default'])[0]

    # Evaluate an intrinsic parameter (see HDK_SOHO_API::evaluate())
    # The 'state:time' parameter evaluates the time from the ROP.
    now = soho.getDefaultedFloat('state:time', [0.0])[0]

    # Evaluate the 'camera' parameter as a string.
    # If the 'camera' parameter doesn't exist, use ['/obj/cam1'].
    # SOHO always returns lists of values.
    camera = soho.getDefaultedString('camera', ['/obj/cam1'])[0]

    # MPlay / Render View port.
    port = soho.getDefaultedInt("vm_image_mplay_socketport", [0])[0]

    # ROP node.
    ropPath = soho.getOutputDriver().getName()
    ropNode = hou.node(ropPath)

    printDebug("Initialize SOHO...")

    # Initialize SOHO with the camera.
    # XXX: This doesn't work for me, but it should according to the documentation...
    #   soho.initialize(now, camera)
    if not sohoglue.initialize(now, camera, None):
        soho.error("Unable to initialize rendering module with given camera")

    # Now, add objects to our scene
    soho.addObjects(now, "*", "*", "*", True)

    # Before we can evaluate the scene from SOHO, we need to lock the object lists.
    soho.lockObjects(now)

    for sohoCam in soho.objectList('objlist:camera'):
        break
    else:
        soho.error("Unable to find viewing camera for render")

    sohoOverride = soho.getDefaultedString('soho_overridefile', ['Unknown'])[0]

    printDebug("Processing Mode: \"%s\"" % mode)

    if mode in {"generate"}:
        # generate: Generation phase of IPR rendering
        # In generate mode, SOHO will keep the pipe (soho_pipecmd)
        # command open between invocations of the soho_program.
        #   objlist:all
        #   objlist:camera
        #   objlist:light
        #   objlist:instance
        #   objlist:fog
        #   objlist:space
        #   objlist:mat
        #
        printDebug("IPR Port: %s" % port)
        printDebug("Driver: %s" % ropPath)
        printDebug("Camera: %s" % camera)
        printDebug("Now: %.3f" % now)

        _vfh_ipr.init(rop=ropPath,
                      port=port,
                      now=now,
                      viewParams=getViewParams(camera, sohoCam, now))

    elif mode in {"update"}:
        # update: Send updated changes from previous generation
        #
        # In this rendering mode, the special object list parameters:
        #   objlist:dirtyinstance
        #   objlist:dirtylight
        #   objlist:dirtyspace
        #   objlist:dirtyfog
        # will contain the list of all objects modified since the last render
        # (whether a generate or update).
        #
        # As well, the parameters:
        #   objlist:deletedinstance
        #   objlist:deletedlight
        #   objlist:deletedspace
        #   objlist:deletedfog
        # will list all objects which have been deleted from the scene.
        #

        if not _vfh_ipr.isRopValid():
            _vfh_ipr.init(rop=ropPath,
                          port=port,
                          now=now,
                          viewParams=getViewParams(camera, sohoCam, now))
        else:
            if _vfh_ipr.setTime(now):
                # Have to handle "time" event manually here.
                exportObjects("objlist:dirtyinstance")
                exportObjects("objlist:dirtylight")

            # Update view.
            exportView(ropPath, camera, sohoCam, now)
Ejemplo n.º 25
0
def wrangle_camera(obj, wrangler, now):

    node = wrangle_node_parm(obj, 'camera_node', now)
    if node is not None:
        output_cam_xform(obj, node.directive_type, now)
        return node.type_and_paramset

    paramset = ParamSet()

    window = obj.getCameraScreenWindow(wrangler, now)
    parm_selection = {
        'projection' : SohoPBRT('projection', 'string', ['perspective'], False),
        'focal' : SohoPBRT('focal', 'float', [50], False),
        'focalunits' : SohoPBRT('focalunits', 'string', ['mm'], False),
        'aperture' : SohoPBRT('aperture', 'float', [41.4214], False),
        'orthowidth' : SohoPBRT('orthowidth', 'float', [2], False),
        'res' : SohoPBRT('res', 'integer', [1280, 720], False),
        'aspect' : SohoPBRT('aspect', 'float', [1], False),
        'fstop' : SohoPBRT('fstop', 'float', [5.6], False),
        'focaldistance' : SohoPBRT('focus', 'float', [5], False, key='focaldistance'),
        'pbrt_dof' : SohoPBRT('pbrt_dof', 'integer', [0], False),
    }

    parms = obj.evaluate(parm_selection, now)
    aspect = parms['aspect'].Value[0]
    aspectfix = aspect * float(parms['res'].Value[0]) / float(parms['res'].Value[1])

    projection = parms['projection'].Value[0]

    if parms['pbrt_dof'].Value[0]:
        paramset.add(parms['focaldistance'].to_pbrt())
        # to convert from f-stop to lens radius
        # FStop = FocalLength / (Radius * 2)
        # Radius = FocalLength/(FStop * 2)
        focal = parms['focal'].Value[0]
        fstop = parms['fstop'].Value[0]
        units = parms['focalunits'].Value[0]
        focal = soho.houdiniUnitLength(focal, units)
        lens_radius = focal/(fstop*2.0)
        paramset.add(PBRTParam('float', 'lensradius', lens_radius))

    if projection == 'perspective':
        projection_name = 'perspective'

        focal = parms['focal'].Value[0]
        aperture = parms['aperture'].Value[0]
        fov = 2.0 * focal / aperture
        fov = 2.0 * math.degrees(math.atan2(1.0, fov))
        paramset.add(PBRTParam('float', 'fov', [fov]))

        screen = [(window[0] - 0.5) * 2.0,
                  (window[1] - 0.5) * 2.0,
                  (window[2] - 0.5) * 2.0 / aspectfix,
                  (window[3] - 0.5) * 2.0 / aspectfix]
        paramset.add(PBRTParam('float', 'screenwindow', screen))

    elif projection == 'ortho':
        projection_name = 'orthographic'

        width = parms['orthowidth'].Value[0]
        screen = [(window[0] - 0.5) * width,
                  (window[1] - 0.5) * width,
                  (window[2] - 0.5) * width / aspectfix,
                  (window[3] - 0.5) * width / aspectfix]
        paramset.add(PBRTParam('float', 'screenwindow', screen))

    elif projection == 'sphere':
        projection_name = 'environment'
    else:
        soho.error('Camera projection setting of %s not supported by PBRT' %
                   projection)

    output_cam_xform(obj, projection_name, now)

    return (projection_name, paramset)
Ejemplo n.º 26
0
Archivo: APS.py Proyecto: symek/haps
if mode != 'default':
    # Don't allow for nested evaluation in IPR mode
    inheritedproperties = False
else:
    inheritedproperties = parmlist['vm_inheritproperties'].Value[0]

options = {}
if inheritedproperties:
    # Turn off object->output driver inheritance
    options['state:inheritance'] = '-rop'
if propdefs and propdefs != 'stdin':
    options['defaults_file'] = propdefs

if not soho.initialize(now, camera, options):
    soho.error("Unable to initialize rendering module with given camera")

#
# Add objects to the scene, we check for parameters on the viewing
# camera.  If the parameters don't exist there, they will be picked up
# by the output driver.
#
objectSelection = {
    # Candidate object selection
    'vobject': SohoParm('vobject', 'string', ['*'], False),
    'alights': SohoParm('alights', 'string', ['*'], False),
    'vfog': SohoParm('vfog', 'string', ['*'], False),
    'forceobject': SohoParm('forceobject', 'string', [''], False),
    'forcelights': SohoParm('forcelights', 'string', [''], False),
    'forcefog': SohoParm('forcefog', 'string', [''], False),
    'excludeobject': SohoParm('excludeobject', 'string', [''], False),
Ejemplo n.º 27
0
    def _lightExportPlanes(self, data, wrangler, cam, now):
        """Handle exporting the image planes based on their export settings."""
        import soho

        base_channel = data["channel"]

        # Handle any light exporting.
        if self.lightexport is not None:
            # Get a list of lights matching our mask and selection.
            lights = cam.objectList(
                "objlist:light",
                now,
                self.lightexport_scope,
                self.lightexport_select
            )

            if self.lightexport == "per-light":
                # Process each light.
                for light in lights:
                    # Try and find the suffix using the 'vm_export_suffix'
                    # parameter.  If it doesn't exist, use an emptry string.
                    suffix = light.getDefaultedString(
                        "vm_export_suffix", now, ['']
                    )[0]

                    prefix = []

                    # Look for the prefix parameter.  If it doesn't exist, use
                    # the light's name and replace the '/' with '_'.  The
                    # default value of 'vm_export_prefix' is usually $OS.
                    if not light.evalString("vm_export_prefix", now, prefix):
                        prefix = [light.getName()[1:].replace('/', '_')]

                    # If there is a prefix we construct the channel name using
                    # it and the suffix.
                    if prefix:
                        channel = "{}_{}{}".format(
                            prefix[0],
                            base_channel,
                            suffix
                        )

                    # If not and there is a valid suffix, add it to the channel
                    # name.
                    elif suffix:
                        channel = "{}{}".format(base_channel, suffix)

                    # Throw an error because all the per-light channels will
                    # have the same name.
                    else:
                        soho.error("Empty suffix for per-light exports.")
                        channel = base_channel

                    data["channel"] = channel
                    data["lightexport"] = light.getName()

                    # Write this light export to the ifd.
                    self.writeDataToIfd(data, wrangler, cam, now)

            elif self.lightexport == "single":
                # Take all the light names and join them together.
                lightexport = ' '.join([light.getName() for light in lights])

                # If there are no lights, we can't pass in an empty string
                # since then mantra will think that light exports are
                # disabled.  So pass down an string that presumably doesn't
                # match any light name.
                if not lightexport:
                    lightexport = "__nolights__"

                data["lightexport"] = lightexport

                # Write the combined light export to the ifd.
                self.writeDataToIfd(data, wrangler, cam, now)

            elif self.lightexport == "per-category":
                # A mapping between category names and their member lights.
                category_map = {}

                # Process each selected light.
                for light in lights:
                    # Get the category for the light.
                    categories = []
                    light.evalString("categories", now, categories)

                    # Light doesn't have a 'categories' parameter.
                    if not categories:
                        continue

                    # Get the raw string.
                    categories = categories[0]

                    # Since the categories value can be space or comma
                    # separated we replace the commas with spaces then split.
                    categories = categories.replace(',', ' ')
                    categories = categories.split()

                    # If the categories list was empty, put the light in a fake
                    # category.
                    if not categories:
                        no_category_lights = category_map.setdefault("__none__", [])
                        no_category_lights.append(light)

                    else:
                        # For each category the light belongs to, add it to
                        # the list.
                        for category in categories:
                            category_lights = category_map.setdefault(category, [])
                            category_lights.append(light)

                # Process all the found categories and their member lights.
                for category, lights in category_map.iteritems():
                    # Construct the export string to contain all the member
                    # lights.
                    lightexport = ' '.join(
                        [light.getName() for light in lights]
                    )

                    data["lightexport"] = lightexport

                    # The channel is the regular channel named prefixed with
                    # the category name.
                    data["channel"] = "{}_{}".format(category, base_channel)

                    # Write the per-category light export to the ifd.
                    self.writeDataToIfd(data, wrangler, cam, now)

        else:
            # Write a normal AOV definition.
            self.writeDataToIfd(data, wrangler, cam, now)
Ejemplo n.º 28
0
import hou
import soho

import afanasy

current_afnode = hou.pwd()

submit_afnode_parm = current_afnode.parm('submit_afnode')
if submit_afnode_parm is None: soho.error('Can\'t find "submit_afnode" parameter on "%s"' % current_afnode.path())

submit_afnode_path = submit_afnode_parm.eval()
if submit_afnode_path is None: soho.error('Can\'t eval "submit_afnode" parameter on "%s"' % current_afnode.path())
if submit_afnode_path == '': soho.error('Empty "submit_afnode" parameter on "%s"' % current_afnode.path())

submit_afnode = hou.node( submit_afnode_path)
if submit_afnode is None: soho.error('Can\'t find "%s" node specified in "%s"' % (submit_afnode_path, current_afnode.path()))
if submit_afnode.type().name() != 'afanasy': soho.error('Node "%s" specified in "%s" is not of "afanasy" type' % (submit_afnode_path, current_afnode.path()))

afanasy.render( submit_afnode)