def wrangle_sampler(obj, wrangler, now):

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

    parm_selection = {
        "sampler": SohoPBRT("sampler", "string", ["halton"], False),
        "pixelsamples": SohoPBRT("pixelsamples", "integer", [16], False),
        "jitter": SohoPBRT("jitter", "bool", [1], False),
        "samples": SohoPBRT("samples", "integer", [4, 4], False),
        "dimensions": SohoPBRT("dimensions", "integer", [4], False),
    }
    parms = obj.evaluate(parm_selection, now)

    sampler_name = parms["sampler"].Value[0]
    paramset = ParamSet()

    if sampler_name == "stratified":
        xsamples = parms["samples"].Value[0]
        ysamples = parms["samples"].Value[1]
        paramset.add(PBRTParam("integer", "xsamples", xsamples))
        paramset.add(PBRTParam("integer", "ysamples", ysamples))
        paramset.add(parms["jitter"].to_pbrt())
        paramset.add(parms["dimensions"].to_pbrt())
    else:
        paramset.add(parms["pixelsamples"].to_pbrt())

    return (sampler_name, paramset)
Example #2
0
def wrangle_sampler(obj, wrangler, now):

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

    parm_selection = {
        "sampler": SohoPBRT("sampler", "string", ["pmj02bn"], False),
        "pixelsamples": SohoPBRT("pixelsamples", "integer", [16], False),
        "randomization": SohoPBRT("randomization", "string", ["fastowen"],
                                  True),
        "jitter": SohoPBRT("jitter", "bool", [1], True),
        "samples": SohoPBRT("samples", "integer", [4, 4], False),
    }
    parms = obj.evaluate(parm_selection, now)

    sampler_name = parms["sampler"].Value[0]
    paramset = ParamSet()

    if sampler_name == "stratified":
        xsamples = parms["samples"].Value[0]
        ysamples = parms["samples"].Value[1]
        paramset.add(PBRTParam("integer", "xsamples", xsamples))
        paramset.add(PBRTParam("integer", "ysamples", ysamples))
        if "jitter" in parms:
            paramset.add(parms["jitter"].to_pbrt())
    else:
        if (sampler_name in ("sobol", "paddedsobol", "zsobol", "halton")
                and "randomization" in parms):
            # NOTE: If the halton sampler is picked, it is not compatible with the
            # randomization "fastowen".
            paramset.add(parms["randomization"].to_pbrt())
        paramset.add(parms["pixelsamples"].to_pbrt())

    return (sampler_name, paramset)
Example #3
0
def wrangle_film(obj, wrangler, now):

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

    paramset = ParamSet()

    parm_selection = {
        'filename' : SohoPBRT('filename', 'string', ['pbrt.exr'], False),
        'maxsampleluminance' : SohoPBRT('maxsampleluminance', 'float', [1e38], True),
        'diagonal' : SohoPBRT('diagonal', 'float', [35], True),
    }
    parms = obj.evaluate(parm_selection, now)
    for parm_name, parm in parms.iteritems():
        paramset.add(parm.to_pbrt())

    parm_selection = {
        'res' : SohoPBRT('res', 'integer', [1280, 720], False),
    }
    parms = obj.evaluate(parm_selection, now)
    paramset.add(PBRTParam('integer', 'xresolution', parms['res'].Value[0]))
    paramset.add(PBRTParam('integer', 'yresolution', parms['res'].Value[1]))

    crop_region = obj.getCameraCropWindow(wrangler, now)
    if crop_region != [0.0, 1.0, 0.0, 1.0]:
        paramset.add(PBRTParam('float', 'cropwindow', crop_region))

    return ('image', paramset)
Example #4
0
def wrangle_sampler(obj, wrangler, now):

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

    parm_selection = {
        'sampler' : SohoPBRT('sampler', 'string', ['halton'], False),
        'pixelsamples' : SohoPBRT('pixelsamples', 'integer', [16], False),
        'jitter' : SohoPBRT('jitter', 'bool', [1], False),
        'samples' : SohoPBRT('samples', 'integer', [4, 4], False),
        'dimensions' : SohoPBRT('dimensions', 'integer', [4], False),
    }
    parms = obj.evaluate(parm_selection, now)

    sampler_name = parms['sampler'].Value[0]
    paramset = ParamSet()

    if sampler_name == 'stratified':
        xsamples = parms['samples'].Value[0]
        ysamples = parms['samples'].Value[1]
        paramset.add(PBRTParam('integer', 'xsamples', xsamples))
        paramset.add(PBRTParam('integer', 'ysamples', ysamples))
        paramset.add(parms['jitter'].to_pbrt())
        paramset.add(parms['dimensions'].to_pbrt())
    else:
        paramset.add(parms['pixelsamples'].to_pbrt())

    return (sampler_name, paramset)
def wrangle_film(obj, wrangler, now):

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

    paramset = ParamSet()

    parm_selection = {
        "filename": SohoPBRT("filename", "string", ["pbrt.exr"], False),
        "maxsampleluminance": SohoPBRT("maxsampleluminance", "float", [1e38], True),
        "diagonal": SohoPBRT("diagonal", "float", [35], True),
    }
    parms = obj.evaluate(parm_selection, now)
    for parm_name, parm in parms.iteritems():
        paramset.add(parm.to_pbrt())

    parm_selection = {"res": SohoPBRT("res", "integer", [1280, 720], False)}
    parms = obj.evaluate(parm_selection, now)
    paramset.add(PBRTParam("integer", "xresolution", parms["res"].Value[0]))
    paramset.add(PBRTParam("integer", "yresolution", parms["res"].Value[1]))

    crop_region = obj.getCameraCropWindow(wrangler, now)
    if crop_region != [0.0, 1.0, 0.0, 1.0]:
        paramset.add(PBRTParam("float", "cropwindow", crop_region))

    return ("image", paramset)
def wrangle_accelerator(obj, wrangler, now):

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

    parm_selection = {"accelerator": SohoPBRT("accelerator", "string", ["bvh"], False)}
    parms = obj.evaluate(parm_selection, now)
    accelerator_name = parms["accelerator"].Value[0]

    if accelerator_name == "bvh":
        parm_selection = {
            "maxnodeprims": SohoPBRT("maxnodeprims", "integer", [4], True),
            "splitmethod": SohoPBRT("splitmethod", "string", ["sah"], True),
        }
    else:
        parm_selection = {
            "intersectcost": SohoPBRT("intersectcost", "integer", [80], True),
            "traversalcostcost": SohoPBRT("traversalcost", "integer", [1], True),
            "emptybonus": SohoPBRT("emptybonus", "float", [0.2], True),
            "maxprims": SohoPBRT("maxprims", "integer", [1], True),
            "kdtree_maxdepth": SohoPBRT(
                "kdtree_maxdepth", "integer", [1], True, key="maxdepth"
            ),
        }
    parms = obj.evaluate(parm_selection, now)

    paramset = ParamSet()

    for parm in parms:
        paramset.add(parms[parm].to_pbrt())

    return (accelerator_name, paramset)
Example #7
0
def wrangle_film(obj, wrangler, now):

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

    paramset = ParamSet()

    parm_selection = {
        "filename": SohoPBRT("filename", "string", ["pbrt.exr"], False),
        "maxcomponentvalue": SohoPBRT("maxcomponentvalue", "float", [1e38],
                                      True),
        "diagonal": SohoPBRT("diagonal", "float", [35], True),
        "savefp16": SohoPBRT("savefp16", "bool", [1], True),
    }
    parms = obj.evaluate(parm_selection, now)
    for parm in parms.values():
        paramset.add(parm.to_pbrt())

    parm_selection = {
        "film": SohoPBRT("film", "string", ["rgb"], False),
        "res": SohoPBRT("res", "integer", [1280, 720], False),
    }
    parms = obj.evaluate(parm_selection, now)
    film_name = parms["film"].Value[0]
    paramset.add(PBRTParam("integer", "xresolution", parms["res"].Value[0]))
    paramset.add(PBRTParam("integer", "yresolution", parms["res"].Value[1]))

    crop_region = obj.getCameraCropWindow(wrangler, now)
    if crop_region != [0.0, 1.0, 0.0, 1.0]:
        paramset.add(PBRTParam("float", "cropwindow", crop_region))

    parm_selection = {
        "iso": SohoPBRT("iso", "float", [100], True),
        "whitebalance": SohoPBRT("whitebalance", "float", [0], True),
        "sensor": SohoPBRT("sensor", "string", ["cie1931"], True),
    }

    if film_name == "spectral":
        parm_selection["buckets"] = SohoPBRT("buckets", "integer", [16], True)

    parms = obj.evaluate(parm_selection, now)
    for parm in parms.values():
        paramset.add(parm.to_pbrt())

    return (film_name, paramset)
def wrangle_node_parm(obj, parm_name, now):

    parm_selection = {parm_name: SohoPBRT(parm_name, "string", [""], False)}
    parms = obj.evaluate(parm_selection, now)
    if not parms:
        return None
    node_path = parms[parm_name].Value[0]
    if not node_path:
        return None
    return BaseNode(node_path)
Example #9
0
def wrangle_filter(obj, wrangler, now):

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

    parm_selection = {
        'filter' : SohoPBRT('filter', 'string', ['gaussian'], False),
        'filter_width' : SohoPBRT('filter_width', 'float', [2.0, 2.0], False),
        'alpha' : SohoPBRT('gauss_alpha', 'float', [2.0], True, key='alpha'),
        'B' : SohoPBRT('mitchell_B', 'float', [0.333333], True, key='B'),
        'C' : SohoPBRT('mitchell_C', 'float', [0.333333], True, key='C'),
        'tau' : SohoPBRT('sinc_tau', 'float', [3], True, key='tau'),
    }
    parms = obj.evaluate(parm_selection, now)

    filter_name = parms['filter'].Value[0]
    paramset = ParamSet()
    xwidth = parms['filter_width'].Value[0]
    ywidth = parms['filter_width'].Value[1]
    paramset.add(PBRTParam('float', 'xwidth', xwidth))
    paramset.add(PBRTParam('float', 'ywidth', ywidth))

    if filter_name == 'gaussian' and 'alpha' in parms:
        paramset.add(parms['alpha'].to_pbrt())
    if filter_name == 'mitchell' and 'mitchell_B' in parms:
        paramset.add(parms['B'].to_pbrt())
    if filter_name == 'mitchell' and 'mitchell_C' in parms:
        paramset.add(parms['C'].to_pbrt())
    if filter_name == 'sinc' and 'tau' in parms:
        paramset.add(parms['tau'].to_pbrt())
    return (filter_name, paramset)
Example #10
0
def wrangle_filter(obj, wrangler, now):

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

    parm_selection = {
        "filter": SohoPBRT("filter", "string", ["gaussian"], False),
        "filter_width": SohoPBRT("filter_width", "float", [2.0, 2.0], False),
        "alpha": SohoPBRT("gauss_alpha", "float", [2.0], True, key="alpha"),
        "B": SohoPBRT("mitchell_B", "float", [0.333333], True, key="B"),
        "C": SohoPBRT("mitchell_C", "float", [0.333333], True, key="C"),
        "tau": SohoPBRT("sinc_tau", "float", [3], True, key="tau"),
    }
    parms = obj.evaluate(parm_selection, now)

    filter_name = parms["filter"].Value[0]
    paramset = ParamSet()
    xwidth = parms["filter_width"].Value[0]
    ywidth = parms["filter_width"].Value[1]
    paramset.add(PBRTParam("float", "xwidth", xwidth))
    paramset.add(PBRTParam("float", "ywidth", ywidth))

    if filter_name == "gaussian" and "alpha" in parms:
        paramset.add(parms["alpha"].to_pbrt())
    if filter_name == "mitchell" and "B" in parms:
        paramset.add(parms["B"].to_pbrt())
    if filter_name == "mitchell" and "C" in parms:
        paramset.add(parms["C"].to_pbrt())
    if filter_name == "sinc" and "tau" in parms:
        paramset.add(parms["tau"].to_pbrt())
    return (filter_name, paramset)
Example #11
0
def wrangle_accelerator(obj, wrangler, now):

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

    parm_selection = {
        'accelerator' : SohoPBRT('accelerator', 'string', ['bvh'], False),
    }
    parms = obj.evaluate(parm_selection, now)
    accelerator_name = parms['accelerator'].Value[0]

    if accelerator_name == 'bvh':
        parm_selection = {
            'maxnodeprims' : SohoPBRT('maxnodeprims', 'integer', [4], True),
            'splitmethod' : SohoPBRT('splitmethod', 'string', ['sah'], True),
        }
    else:
        parm_selection = {
            'intersectcost' :
                SohoPBRT('intersectcost', 'integer', [80], True),
            'traversalcostcost' :
                SohoPBRT('traversalcost', 'integer', [1], True),
            'emptybonus' :
                SohoPBRT('emptybonus', 'float', [0.2], True),
            'maxprims' :
                SohoPBRT('maxprims', 'integer', [1], True),
            'kdtree_maxdepth' :
                SohoPBRT('kdtree_maxdepth', 'integer', [1], True,
                         key='maxdepth')
        }
    parms = obj.evaluate(parm_selection, now)

    paramset = ParamSet()

    for parm in parms:
        paramset.add(parms[parm].to_pbrt())

    return (accelerator_name, paramset)
Example #12
0
def wrangle_geo(obj, wrangler, now):

    parm_selection = {
        'object:soppath' : SohoPBRT('object:soppath', 'string', [''], 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'
        # TODO: However this does not seem to apply to shop_materialpaths on the instance points.
        'shop_materialpath' : SohoPBRT('shop_materialpath', 'shaderhandle', skipdefault=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),
        # 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'),
        # We don't use the key=type since its a bit too generic of a name
        'pbrt_curvetype' : SohoPBRT('pbrt_curvetype', 'string', ['flat'], True),
        'pbrt_include' : SohoPBRT('pbrt_include', 'string', [''], False),
        'pbrt_alpha_texture' : SohoPBRT('pbrt_alpha_texture', 'string', [''],
                                         skipdefault=False, key='alpha'),
        'pbrt_shadowalpha_texture' : SohoPBRT('pbrt_shadowalpha_texture', 'string', [''],
                                              skipdefault=False, key='shadowalpha'),
        # TODO, Tesselation options?
    }
    properties = obj.evaluate(parm_selection, now)

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

    if shop and shop in scene_state.shading_nodes:
        api.NamedMaterial(shop)

    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]

    # 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)

    for prop in ('alpha', 'shadowalpha'):
        alpha_tex = properties[prop].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:
                wrangle_shading_network(alpha_node.path, saved_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[prop].Value[0] = ''

    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

    Geo.output_geo(soppath, now, properties)
    return
Example #13
0
def wrangle_light(light, wrangler, now):


    # NOTE: Lights do not support motion blur so we disable it when
    #       outputs the xforms

    node = wrangle_node_parm(light, 'light_node', now)

    parm_selection = {
        'light_wrangler' : SohoPBRT('light_wrangler', 'string', [''], False),
        'light_color' : SohoPBRT('light_color', 'float', [1, 1, 1], False),
        'light_intensity' : SohoPBRT('light_intensity', 'float', [1], False),
        'light_exposure' : SohoPBRT('light_exposure', 'float', [0], False),
    }
    parms = light.evaluate(parm_selection, now)
    light_wrangler = parms['light_wrangler'].Value[0]

    paramset = ParamSet()
    paramset.add(_to_light_scale(parms))

    if light_wrangler == 'HoudiniEnvLight':
        env_map = []
        paramset.add(PBRTParam('rgb', 'L', parms['light_color'].Value))
        if light.evalString('env_map', now, env_map):
            paramset.add(PBRTParam('string', 'mapname', env_map))
        output_xform(light, now, no_motionblur=True)
        api.Scale(1, 1, -1)
        api.Rotate(90, 0, 0, 1)
        api.Rotate(90, 0, 1, 0)
        _light_api_wrapper('infinite', paramset, node)
        return
    elif light_wrangler != 'HoudiniLight':
        api.Comment('This light type, %s, is unsupported' % light_wrangler)
        return

    # We are dealing with a standard HoudiniLight type.

    light_type = light.wrangleString(wrangler, 'light_type', now, ['point'])[0]

    if light_type in ('sphere', 'disk', 'grid', 'tube', 'geo'):

        single_sided = light.wrangleInt(wrangler, 'singlesided', now, [0])[0]
        visible = light.wrangleInt(wrangler, 'light_contribprimary', now, [0])[0]
        size = light.wrangleFloat(wrangler, 'areasize', now, [1, 1])
        paramset.add(PBRTParam('rgb', 'L', parms['light_color'].Value))
        paramset.add(PBRTParam('bool', 'twosided', [not single_sided]))

        # TODO, Possibly get the xform's scale and scale the geo, not the light.
        #       (for example, further multiplying down the radius)
        xform = get_transform(light, now)
        xform_to_api_srt(xform, scale=False)

        _light_api_wrapper('diffuse', paramset, node)

        api.AttributeBegin()

        # PBRT only supports uniform scales for non-mesh area lights
        # this is in part due to explicit light's area scaling factor.
        if light_type in ('grid', 'geo'):
            api.Scale(size[0], size[1], size[0])

        # The visibility only applies to hits on the non-emissive side of the light.
        # the emissive side will still be rendered
        if not visible:
            api.Material('none')

        if light_type == 'sphere':
            # We apply the scale to the radius instead of using a api.Scale
            api.Shape('sphere', [PBRTParam('float', 'radius', 0.5*size[0])])
        elif light_type == 'tube':
            api.Rotate(90, 0, 1, 0)
            api.Shape('cylinder', [PBRTParam('float', 'radius', 0.075*size[1]),
                                   PBRTParam('float', 'zmin', -0.5*size[0]),
                                   PBRTParam('float', 'zmax', 0.5*size[0])])
        elif light_type == 'disk':
            # A bug was introduced with Issue #154 which requires a -z scale
            # on disk area lights
            # See issue #183
            # api.Scale(1,1,-1)
            api.Shape('disk', [PBRTParam('float', 'radius', 0.5*size[0])])
        elif light_type == 'grid':
            api.Shape('trianglemesh', [PBRTParam('integer', 'indices', [0, 3, 1,
                                                                        0, 2, 3]),
                                       PBRTParam('point', 'P', [-0.5, -0.5, 0,
                                                                0.5, -0.5, 0,
                                                                -0.5, 0.5, 0,
                                                                0.5, 0.5, 0])])
        elif light_type == 'geo':
            areageo_parm = hou.node(light.getName()).parm('areageometry')
            if not areageo_parm:
                api.Comment('No "areageometry" parm on light')
                return
            area_geo_node = areageo_parm.evalAsNode()
            if not area_geo_node:
                api.Comment('Skipping, no geometry object specified')
                return
            obj = soho.getObject(area_geo_node.path())
            api.Comment('Light geo from %s' % obj.getName())
            # TODO: The area light scale ('areasize') happens *after* the wrangle_obj's xform
            #       when 'intothisobject' is enabled.
            into_this_obj = light.wrangleInt(wrangler, 'intothisobject', now, [0])[0]
            ignore_xform = not into_this_obj
            wrangle_obj(obj, None, now, ignore_xform=ignore_xform)

        api.AttributeEnd()

        return

    cone_enable = light.wrangleInt(wrangler, 'coneenable', now, [0])[0]
    projmap = light.wrangleString(wrangler, 'projmap', now, [''])[0]
    areamap = light.wrangleString(wrangler, 'areamap', now, [''])[0]

    api_calls = []
    api_calls.append(_apiclosure(output_xform, light, now, no_motionblur=True))
    api_calls.append(_apiclosure(api.Scale, 1, 1, -1))
    api_calls.append(_apiclosure(api.Scale, 1, -1, 1))

    if light_type == 'point':
        paramset.add(PBRTParam('rgb', 'I', parms['light_color'].Value))
        if areamap:
            light_name = 'goniometric'
            paramset.add(PBRTParam('string', 'mapname', [areamap]))
            api_calls = []
            api_calls.append(_apiclosure(output_xform, light, now, no_motionblur=True))
            api_calls.append(_apiclosure(api.Scale, 1, -1, 1))
            api_calls.append(_apiclosure(api.Rotate, 90, 0, 1, 0))
        elif not cone_enable:
            light_name = 'point'
        else:
            conedelta = light.wrangleFloat(wrangler, 'conedelta', now, [10])[0]
            coneangle = light.wrangleFloat(wrangler, 'coneangle', now, [45])[0]
            if projmap:
                light_name = 'projection'
                paramset.add(PBRTParam('float', 'fov', [coneangle]))
                paramset.add(PBRTParam('string', 'mapname', [projmap]))
            else:
                light_name = 'spot'
                coneangle *= 0.5
                coneangle += conedelta
                paramset.add(PBRTParam('float', 'coneangle', [coneangle]))
                paramset.add(PBRTParam('float', 'conedeltaangle', [conedelta]))
    elif light_type == 'distant':
        light_name = light_type
        paramset.add(PBRTParam('rgb', 'L', parms['light_color'].Value))
    else:
        api.Comment('Light Type, %s, not supported' % light_type)
        return

    for api_call in api_calls:
        api_call()
    _light_api_wrapper(light_name, paramset, node)

    return
Example #14
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)
Example #15
0
def wrangle_integrator(obj, wrangler, now):

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

    parm_selection = {
        'integrator' : SohoPBRT('integrator', 'string', ['path'], False),
        'maxdepth' : SohoPBRT('maxdepth', 'integer', [5], False),
        'rrthreshold' : SohoPBRT('rrthreshold', 'float', [1], True),
        'lightsamplestrategy' :
            SohoPBRT('lightsamplestrategy', 'string', ['spatial'], True),
        'visualizestrategies' :
            SohoPBRT('visualizestrategies', 'toggle', [False], True),
        'visualizeweights' :
            SohoPBRT('visualizeweights', 'toggle', [False], True),
        'iterations' :
            SohoPBRT('iterations', 'integer', [64], True),
        'photonsperiterations' :
            SohoPBRT('photonsperiterations', 'integer', [-1], True),
        'imagewritefrequency' :
            SohoPBRT('imagewritefrequency', 'integer', [2.14748e+09], True),
        'radius' :
            SohoPBRT('radius', 'float', [1], True),
        'bootstrapsamples' :
            SohoPBRT('bootstrapsamples', 'integer', [100000], True),
        'chains' :
            SohoPBRT('chains', 'integer', [1000], True),
        'mutationsperpixel' :
            SohoPBRT('mutataionsperpixel', 'integer', [100], True),
        'largestepprobability' :
            SohoPBRT('largestepprobability', 'float', [0.3], True),
        'sigma' :
            SohoPBRT('sigma', 'float', [0.01], True),
        'strategy' :
            SohoPBRT('strategy', 'string', ['all'], True),
        'nsamples' :
            SohoPBRT('nsamples', 'integer', ['64'], True),
        'cossample' :
            SohoPBRT('cossample', 'toggle', [True], True),
    }

    integrator_parms = {
        'ao' : ['nsamples', 'cossample'],
        'path' : ['maxdepth', 'rrthreshold', 'lightsamplestrategy'],
        'bdpt' : ['maxdepth', 'rrthreshold', 'lightsamplestrategy',
                  'visualizestrategies', 'visualizeweights'],
        'mlt' : ['maxdepth', 'bootstrapsamples', 'chains', 'mutationsperpixel',
                 'largestepprobability', 'sigma'],
        'sppm' : ['maxdepth', 'iterations', 'photonsperiteration',
                  'imagewritefrequency', 'radius'],
        'whitted' : ['maxdepth'],
        'volpath' : ['maxdepth', 'rrthreshold', 'lightsamplestrategy'],
        'directlighting' : ['maxdepth', 'strategy'],
        }
    parms = obj.evaluate(parm_selection, now)

    integrator_name = parms['integrator'].Value[0]
    paramset = ParamSet()
    for parm_name in integrator_parms[integrator_name]:
        if parm_name not in parms:
            continue
        paramset.add(parms[parm_name].to_pbrt())

    return (integrator_name, paramset)
Example #16
0
def wrangle_options(obj, wrangler, now):
    parm_selection = {
        "disabletexturefiltering": SohoPBRT(
            "disabletexturefiltering", "bool", [False], True
        ),
        "disablepixeljitter": SohoPBRT("disablepixeljitter", "bool", [False], True),
        "disablewavelengthjitter": SohoPBRT(
            "disablewavelengthjitter", "bool", [False], True
        ),
        "msereferenceimage": SohoPBRT("msereferenceimage", "string", [""], True),
        "msereferenceout": SohoPBRT("msereferenceout", "string", [""], True),
        # NOTE:
        # The PBRT default is "cameraworld" but this can cause instancing interpolation issues
        # For now we'll use the PBRT default and expect the user to switch to world, but depending
        # on the resolution of https://github.com/mmp/pbrt-v4/issues/206 we may need to default
        # this to "world"
        "rendercoordsys": SohoPBRT("rendercoordsys", "string", ["cameraworld"], True),
        "seed": SohoPBRT("seed", "integer", [0], True),
        "displacementedgescale": SohoPBRT(
            "displacementedgescale", "float", [1.0], True
        ),
        "forcediffuse": SohoPBRT("forcediffuse", "bool", [False], True),
        "pixelstats": SohoPBRT("pixelstats", "bool", [False], True),
        "wavefront": SohoPBRT("wavefront", "bool", [False], True),
    }
    parms = obj.evaluate(parm_selection, now)

    for parm in parms:
        yield (parm, parms[parm].to_pbrt())
Example #17
0
def wrangle_integrator(obj, wrangler, now):

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

    parm_selection = {
        "integrator": SohoPBRT("integrator", "string", ["path"], False),
        "maxdepth": SohoPBRT("maxdepth", "integer", [5], False),
        "regularize": SohoPBRT("regularize", "bool", [False], True),
        "lightsampler": SohoPBRT("lightsampler", "string", ["bvh"], True),
        "visualizestrategies": SohoPBRT("visualizestrategies", "bool", [False], True),
        "visualizeweights": SohoPBRT("visualizeweights", "bool", [False], True),
        "iterations": SohoPBRT("iterations", "integer", [64], True),
        "photonsperiteration": SohoPBRT("photonsperiteration", "integer", [-1], True),
        "seed": SohoPBRT("sppm_seed", "integer", [6502], True, key="seed"),
        "radius": SohoPBRT("radius", "float", [1], True),
        "bootstrapsamples": SohoPBRT("bootstrapsamples", "integer", [100000], True),
        "chains": SohoPBRT("chains", "integer", [1000], True),
        "mutationsperpixel": SohoPBRT("mutationsperpixel", "integer", [100], True),
        "largestepprobability": SohoPBRT("largestepprobability", "float", [0.3], True),
        "sigma": SohoPBRT("sigma", "float", [0.01], True),
        "maxdistance": SohoPBRT("maxdistance", "float", ["1e38"], True),
        "cossample": SohoPBRT("cossample", "bool", [True], True),
        "samplelights": SohoPBRT("samplelights", "bool", [True], True),
        "samplebsdf": SohoPBRT("samplebsdf", "bool", [True], True),
    }

    integrator_parms = {
        "ambientocclusion": ["maxdistance", "cossample"],
        "path": ["maxdepth", "regularize", "lightsampler"],
        "bdpt": ["maxdepth", "regularize", "visualizestrategies", "visualizeweights"],
        "mlt": [
            "maxdepth",
            "bootstrapsamples",
            "chains",
            "mutationsperpixel",
            "largestepprobability",
            "sigma",
            "regularize",
        ],
        "sppm": [
            "maxdepth",
            "iterations",
            "photonsperiteration",
            "seed",
            "radius",
            "regularize",
        ],
        "lightpath": ["maxdepth"],
        "randomwalk": ["maxdepth"],
        "simplepath": ["maxdepth", "samplelights", "samplebsdf"],
        "simplevolpath": ["maxdepth"],
        "volpath": ["maxdepth", "lightsampler", "regularize"],
    }
    parms = obj.evaluate(parm_selection, now)

    integrator_name = parms["integrator"].Value[0]
    paramset = ParamSet()
    for parm_name in integrator_parms[integrator_name]:
        if parm_name not in parms:
            continue
        paramset.add(parms[parm_name].to_pbrt())

    return (integrator_name, paramset)
Example #18
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
        ),
        "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
        ),
        # 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"
        ),
        # We don't use the key=type since its a bit too generic of a name
        "pbrt_curvetype": SohoPBRT("pbrt_curvetype", "string", ["flat"], True),
        "pbrt_include": SohoPBRT("pbrt_include", "string", [""], False),
        "pbrt_alpha_texture": SohoPBRT(
            "pbrt_alpha_texture", "string", [""], skipdefault=False, key="alpha"
        ),
        "pbrt_shadowalpha_texture": SohoPBRT(
            "pbrt_shadowalpha_texture",
            "string",
            [""],
            skipdefault=False,
            key="shadowalpha",
        ),
        # TODO, Tesselation options?
    }
    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 = Instancing.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)

    for prop in ("alpha", "shadowalpha"):
        alpha_tex = properties[prop].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:
                wrangle_shading_network(alpha_node.path, saved_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[prop].Value[0] = ""

    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

    Geo.output_geo(soppath, now, properties)
    return
Example #19
0
def wrangle_light(light, wrangler, now):

    # NOTE: Lights do not support motion blur so we disable it when
    #       outputs the xforms

    node = wrangle_node_parm(light, "light_node", now)

    parm_selection = {
        "light_wrangler": SohoPBRT("light_wrangler", "string", [""], False),
        "light_color": SohoPBRT("light_color", "float", [1, 1, 1], False),
        "light_intensity": SohoPBRT("light_intensity", "float", [1], False),
        "light_exposure": SohoPBRT("light_exposure", "float", [0], False),
    }
    parms = light.evaluate(parm_selection, now)
    light_wrangler = parms["light_wrangler"].Value[0]

    paramset = ParamSet()
    paramset.add(_to_light_scale(parms))

    if light_wrangler == "HoudiniEnvLight":
        env_map = []
        paramset.add(PBRTParam("rgb", "L", parms["light_color"].Value))
        if light.evalString("env_map", now, env_map):
            paramset.add(PBRTParam("string", "mapname", env_map))
        output_xform(light, now, no_motionblur=True)
        api.Scale(1, 1, -1)
        api.Rotate(90, 0, 0, 1)
        api.Rotate(90, 0, 1, 0)
        _light_api_wrapper("infinite", paramset, node)
        return
    elif light_wrangler != "HoudiniLight":
        api.Comment("This light type, %s, is unsupported" % light_wrangler)
        return

    # We are dealing with a standard HoudiniLight type.

    light_type = light.wrangleString(wrangler, "light_type", now, ["point"])[0]

    if light_type in ("sphere", "disk", "grid", "tube", "geo"):

        single_sided = light.wrangleInt(wrangler, "singlesided", now, [0])[0]
        visible = light.wrangleInt(wrangler, "light_contribprimary", now, [0])[0]
        size = light.wrangleFloat(wrangler, "areasize", now, [1, 1])
        paramset.add(PBRTParam("rgb", "L", parms["light_color"].Value))
        paramset.add(PBRTParam("bool", "twosided", [not single_sided]))

        # TODO, Possibly get the xform's scale and scale the geo, not the light.
        #       (for example, further multiplying down the radius)
        xform = get_transform(light, now)
        xform_to_api_srt(xform, scale=False)

        _light_api_wrapper("diffuse", paramset, node)

        api.AttributeBegin()

        # PBRT only supports uniform scales for non-mesh area lights
        # this is in part due to explicit light's area scaling factor.
        if light_type in ("grid", "geo"):
            api.Scale(size[0], size[1], size[0])

        # The visibility only applies to hits on the non-emissive side of the light.
        # the emissive side will still be rendered
        if not visible:
            api.Material("none")

        if light_type == "sphere":
            # We apply the scale to the radius instead of using a api.Scale
            api.Shape("sphere", [PBRTParam("float", "radius", 0.5 * size[0])])
        elif light_type == "tube":
            api.Rotate(90, 0, 1, 0)
            api.Shape(
                "cylinder",
                [
                    PBRTParam("float", "radius", 0.075 * size[1]),
                    PBRTParam("float", "zmin", -0.5 * size[0]),
                    PBRTParam("float", "zmax", 0.5 * size[0]),
                ],
            )
        elif light_type == "disk":
            # After pbrt-v3 commit #2f0852ce api.ReverseOrientation() is needed,
            # prior that it was a api.Scale(1,1,-1)
            # (see issue #183 in pbrt-v3)
            api.ReverseOrientation()
            api.Shape("disk", [PBRTParam("float", "radius", 0.5 * size[0])])
        elif light_type == "grid":
            api.Shape(
                "trianglemesh",
                [
                    PBRTParam("integer", "indices", [0, 3, 1, 0, 2, 3]),
                    PBRTParam(
                        "point",
                        "P",
                        [-0.5, -0.5, 0, 0.5, -0.5, 0, -0.5, 0.5, 0, 0.5, 0.5, 0],
                    ),
                ],
            )
        elif light_type == "geo":
            areageo_parm = hou.node(light.getName()).parm("areageometry")
            if not areageo_parm:
                api.Comment('No "areageometry" parm on light')
                return
            area_geo_node = areageo_parm.evalAsNode()
            if not area_geo_node:
                api.Comment("Skipping, no geometry object specified")
                return
            obj = soho.getObject(area_geo_node.path())
            api.Comment("Light geo from %s" % obj.getName())
            # TODO: The area light scale ('areasize') happens *after* the wrangle_obj's
            #       xform when 'intothisobject' is enabled.
            into_this_obj = light.wrangleInt(wrangler, "intothisobject", now, [0])[0]
            ignore_xform = not into_this_obj
            wrangle_obj(obj, None, now, ignore_xform=ignore_xform)

        api.AttributeEnd()

        return

    cone_enable = light.wrangleInt(wrangler, "coneenable", now, [0])[0]
    projmap = light.wrangleString(wrangler, "projmap", now, [""])[0]
    areamap = light.wrangleString(wrangler, "areamap", now, [""])[0]

    api_calls = []
    api_calls.append(_apiclosure(output_xform, light, now, no_motionblur=True))
    api_calls.append(_apiclosure(api.Scale, 1, 1, -1))
    api_calls.append(_apiclosure(api.Scale, 1, -1, 1))

    if light_type == "point":
        paramset.add(PBRTParam("rgb", "I", parms["light_color"].Value))
        if areamap:
            light_name = "goniometric"
            paramset.add(PBRTParam("string", "mapname", [areamap]))
            api_calls = []
            api_calls.append(_apiclosure(output_xform, light, now, no_motionblur=True))
            api_calls.append(_apiclosure(api.Scale, 1, -1, 1))
            api_calls.append(_apiclosure(api.Rotate, 90, 0, 1, 0))
        elif not cone_enable:
            light_name = "point"
        else:
            conedelta = light.wrangleFloat(wrangler, "conedelta", now, [10])[0]
            coneangle = light.wrangleFloat(wrangler, "coneangle", now, [45])[0]
            if projmap:
                light_name = "projection"
                paramset.add(PBRTParam("float", "fov", [coneangle]))
                paramset.add(PBRTParam("string", "mapname", [projmap]))
            else:
                light_name = "spot"
                coneangle *= 0.5
                coneangle += conedelta
                paramset.add(PBRTParam("float", "coneangle", [coneangle]))
                paramset.add(PBRTParam("float", "conedeltaangle", [conedelta]))
    elif light_type == "distant":
        light_name = light_type
        paramset.add(PBRTParam("rgb", "L", parms["light_color"].Value))
    else:
        api.Comment("Light Type, %s, not supported" % light_type)
        return

    for api_call in api_calls:
        api_call()
    _light_api_wrapper(light_name, paramset, node)

    return
Example #20
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)
Example #21
0
def wrangle_light(light, wrangler, now):

    # NOTE: Lights do not support motion blur so we disable it when
    #       outputs the xforms

    node = wrangle_node_parm(light, "light_node", now)

    # We skip the light_color if its at default so we avoid setting rgb values
    # if at all possible, that way we get a constant spectrum instead
    parm_selection = {
        "light_wrangler": SohoPBRT("light_wrangler", "string", [""], False),
        "light_color": SohoPBRT("light_color", "float", [1, 1, 1], True),
        "light_intensity": SohoPBRT("light_intensity", "float", [1], False),
        "light_exposure": SohoPBRT("light_exposure", "float", [0], False),
    }
    parms = light.evaluate(parm_selection, now)
    light_wrangler = parms["light_wrangler"].Value[0]

    exterior = light.wrangleString(wrangler, "pbrt_exterior", now, [None])[0]
    exterior = wrangle_medium(exterior)
    if exterior:
        api.MediumInterface("", exterior)
        print()

    paramset = ParamSet()
    paramset.add(_to_light_scale(parms))

    if light_wrangler == "HoudiniEnvLight":
        env_map = []
        light.evalString("env_map", now, env_map)
        # evalString will return [""] if the parm exists yet at its default
        env_map = env_map[0] if env_map else ""
        if env_map:
            paramset.add(PBRTParam("string", "filename", env_map))
        elif "light_color" in parms:
            paramset.add(PBRTParam("rgb", "L", parms["light_color"].Value))

        portal = light.wrangleString(wrangler, "env_portal", now, [""])[0]
        portal_enabled = light.wrangleInt(wrangler, "env_portalenable", now, [0])[0]
        if portal_enabled and portal:
            portal_pts = _portal_helper(now, portal)
            if portal_pts is not None:
                # TODO pbrt-v4 we may need to invert the Houdini -> PBRT xform
                paramset.add(PBRTParam("point", "portal", portal_pts))

        output_xform(light, now, no_motionblur=True)
        api.Scale(1, 1, -1)
        api.Rotate(90, 0, 0, 1)
        api.Rotate(90, 0, 1, 0)
        _light_api_wrapper("infinite", paramset, node)
        return
    elif light_wrangler != "HoudiniLight":
        api.Comment("This light type, %s, is unsupported" % light_wrangler)
        return

    # We are dealing with a standard HoudiniLight type.

    light_type = light.wrangleString(wrangler, "light_type", now, ["point"])[0]

    if light_type in ("sphere", "disk", "grid", "tube", "geo"):

        single_sided = light.wrangleInt(wrangler, "singlesided", now, [0])[0]
        reverse = light.wrangleInt(wrangler, "reverse", now, [0])[0]
        visible = light.wrangleInt(wrangler, "light_contribprimary", now, [0])[0]
        size = light.wrangleFloat(wrangler, "areasize", now, [1, 1])
        paramset.add(PBRTParam("bool", "twosided", [not single_sided]))

        texmap = light.wrangleString(wrangler, "light_texture", now, [""])[0]
        if texmap:
            paramset.add(PBRTParam("string", "filename", texmap))
        elif "light_color" in parms:
            paramset.add(PBRTParam("rgb", "L", parms["light_color"].Value))

        # TODO, Possibly get the xform's scale and scale the geo, not the light.
        #       (for example, further multiplying down the radius)
        xform = get_transform(light, now)
        xform_to_api_srt(xform, scale=False)

        _light_api_wrapper("diffuse", paramset, node)

        api.AttributeBegin()

        if single_sided and reverse:
            api.ReverseOrientation()

        shape_paramset = ParamSet()
        if not visible:
            shape_paramset.add(PBRTParam("float", "alpha", 0.0))

        # PBRT only supports uniform scales for non-mesh area lights
        # this is in part due to explicit light's area scaling factor.
        if light_type in ("grid", "geo"):
            api.Scale(size[0], size[1], size[0])

        if light_type == "sphere":
            # NOTE:
            # To match the UVs we need a api.Scale(1, 1, -1)
            # However doing this screws up the direction of emission.
            # When rendering as one sided, the emissive side will be the opposite
            # side from which is used to illuminate. Unfortunately an
            # api.ReverseOrientation() does not fix this.

            # We apply the scale to the radius instead of using a api.Scale
            shape_paramset.add(PBRTParam("float", "radius", 0.5 * size[0]))
            api.Shape("sphere", shape_paramset)
        elif light_type == "tube":
            api.Rotate(90, 0, 1, 0)
            api.Rotate(90, 0, 0, 1)
            # NOTE:
            # To match UVs we need a api.Scale(1, 1, -1)
            # see note above about spheres.
            shape_paramset.add(PBRTParam("float", "radius", 0.075 * size[1]))
            shape_paramset.add(PBRTParam("float", "zmin", -0.5 * size[0]))
            shape_paramset.add(PBRTParam("float", "zmax", 0.5 * size[0]))
            api.Shape("cylinder", shape_paramset)
        elif light_type == "disk":
            # NOTE this should match mantra now, unlike in pbrt-v3
            api.Scale(-1, 1, -1)
            shape_paramset.add(PBRTParam("float", "radius", 0.5 * size[0]))
            api.Shape("disk", shape_paramset)
        elif light_type == "grid":
            api.ReverseOrientation()
            shape_paramset.add(
                PBRTParam(
                    "point",
                    "P",
                    [-0.5, -0.5, 0, 0.5, -0.5, 0, -0.5, 0.5, 0, 0.5, 0.5, 0],
                )
            )
            api.Shape("bilinearmesh", shape_paramset)
        elif light_type == "geo":
            areageo_parm = hou.node(light.getName()).parm("areageometry")
            if not areageo_parm:
                api.Comment('No "areageometry" parm on light')
                return
            area_geo_node = areageo_parm.evalAsNode()
            if not area_geo_node:
                api.Comment("Skipping, no geometry object specified")
                return
            obj = soho.getObject(area_geo_node.path())
            api.Comment("Light geo from %s" % obj.getName())
            # TODO: The area light scale ('areasize') happens *after* the wrangle_obj's
            #       xform when 'intothisobject' is enabled.

            # TODO: the Light visiblity paramset ("alpha") can't be easily passed
            #       with this current interface. It can be worked aroudn by setting
            #       the referenced object's "alpha" property
            into_this_obj = light.wrangleInt(wrangler, "intothisobject", now, [0])[0]
            ignore_xform = not into_this_obj
            wrangle_obj(obj, None, now, ignore_xform=ignore_xform)

        api.AttributeEnd()

        return

    cone_enable = light.wrangleInt(wrangler, "coneenable", now, [0])[0]
    projmap = light.wrangleString(wrangler, "projmap", now, [""])[0]
    areamap = light.wrangleString(wrangler, "areamap", now, [""])[0]

    api_calls = []
    api_calls.append(_apiclosure(output_xform, light, now, no_motionblur=True))
    api_calls.append(_apiclosure(api.Scale, 1, 1, -1))
    api_calls.append(_apiclosure(api.Scale, 1, -1, 1))

    if light_type == "point":
        if areamap:
            light_name = "goniometric"
            if "light_color" in parms:
                paramset.add(PBRTParam("rgb", "I", parms["light_color"].Value))
            paramset.add(PBRTParam("string", "filename", [areamap]))
            api_calls = []
            api_calls.append(_apiclosure(output_xform, light, now, no_motionblur=True))
            api_calls.append(_apiclosure(api.Scale, 1, -1, 1))
            api_calls.append(_apiclosure(api.Rotate, 90, 0, 1, 0))
        elif not cone_enable:
            light_name = "point"
            if "light_color" in parms:
                paramset.add(PBRTParam("rgb", "I", parms["light_color"].Value))
        elif projmap:
            light_name = "projection"
            coneangle = light.wrangleFloat(wrangler, "coneangle", now, [45])[0]
            paramset.add(PBRTParam("float", "fov", [coneangle]))
            paramset.add(PBRTParam("string", "filename", [projmap]))
        else:
            light_name = "spot"
            if "light_color" in parms:
                paramset.add(PBRTParam("rgb", "I", parms["light_color"].Value))
            conedelta = light.wrangleFloat(wrangler, "conedelta", now, [10])[0]
            coneangle = light.wrangleFloat(wrangler, "coneangle", now, [45])[0]
            coneangle *= 0.5
            coneangle += conedelta
            paramset.add(PBRTParam("float", "coneangle", [coneangle]))
            paramset.add(PBRTParam("float", "conedeltaangle", [conedelta]))
    elif light_type == "distant":
        light_name = light_type
        if "light_color" in parms:
            paramset.add(PBRTParam("rgb", "L", parms["light_color"].Value))
    else:
        api.Comment("Light Type, %s, not supported" % light_type)
        return

    for api_call in api_calls:
        api_call()
    _light_api_wrapper(light_name, paramset, node)

    return
Example #22
0
def wrangle_integrator(obj, wrangler, now):

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

    parm_selection = {
        "integrator": SohoPBRT("integrator", "string", ["path"], False),
        "maxdepth": SohoPBRT("maxdepth", "integer", [5], False),
        "rrthreshold": SohoPBRT("rrthreshold", "float", [1], True),
        "lightsamplestrategy": SohoPBRT(
            "lightsamplestrategy", "string", ["spatial"], True
        ),
        "visualizestrategies": SohoPBRT("visualizestrategies", "toggle", [False], True),
        "visualizeweights": SohoPBRT("visualizeweights", "toggle", [False], True),
        "iterations": SohoPBRT("iterations", "integer", [64], True),
        "photonsperiterations": SohoPBRT("photonsperiterations", "integer", [-1], True),
        "imagewritefrequency": SohoPBRT(
            "imagewritefrequency", "integer", [2.14748e09], True
        ),
        "radius": SohoPBRT("radius", "float", [1], True),
        "bootstrapsamples": SohoPBRT("bootstrapsamples", "integer", [100000], True),
        "chains": SohoPBRT("chains", "integer", [1000], True),
        "mutationsperpixel": SohoPBRT("mutataionsperpixel", "integer", [100], True),
        "largestepprobability": SohoPBRT("largestepprobability", "float", [0.3], True),
        "sigma": SohoPBRT("sigma", "float", [0.01], True),
        "strategy": SohoPBRT("strategy", "string", ["all"], True),
        "nsamples": SohoPBRT("nsamples", "integer", ["64"], True),
        "cossample": SohoPBRT("cossample", "toggle", [True], True),
    }

    integrator_parms = {
        "ao": ["nsamples", "cossample"],
        "path": ["maxdepth", "rrthreshold", "lightsamplestrategy"],
        "bdpt": [
            "maxdepth",
            "rrthreshold",
            "lightsamplestrategy",
            "visualizestrategies",
            "visualizeweights",
        ],
        "mlt": [
            "maxdepth",
            "bootstrapsamples",
            "chains",
            "mutationsperpixel",
            "largestepprobability",
            "sigma",
        ],
        "sppm": [
            "maxdepth",
            "iterations",
            "photonsperiteration",
            "imagewritefrequency",
            "radius",
        ],
        "whitted": ["maxdepth"],
        "volpath": ["maxdepth", "rrthreshold", "lightsamplestrategy"],
        "directlighting": ["maxdepth", "strategy"],
    }
    parms = obj.evaluate(parm_selection, now)

    integrator_name = parms["integrator"].Value[0]
    paramset = ParamSet()
    for parm_name in integrator_parms[integrator_name]:
        if parm_name not in parms:
            continue
        paramset.add(parms[parm_name].to_pbrt())

    return (integrator_name, paramset)
Example #23
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),
        '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),
        # 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'),
        # We don't use the key=type since its a bit too generic of a name
        'pbrt_curvetype':
        SohoPBRT('pbrt_curvetype', 'string', ['flat'], True),
        'pbrt_include':
        SohoPBRT('pbrt_include', 'string', [''], False),
        'pbrt_alpha_texture':
        SohoPBRT('pbrt_alpha_texture',
                 'string', [''],
                 skipdefault=False,
                 key='alpha'),
        'pbrt_shadowalpha_texture':
        SohoPBRT('pbrt_shadowalpha_texture',
                 'string', [''],
                 skipdefault=False,
                 key='shadowalpha'),
        # TODO, Tesselation options?
    }
    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.

    pt_shop_found = False
    if properties['ptinstance'].Value[0] == 1:
        pt_shop_found = Instancing.process_full_pt_instance_material(obj, now)

    # 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)

    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]

    # 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)

    for prop in ('alpha', 'shadowalpha'):
        alpha_tex = properties[prop].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:
                wrangle_shading_network(alpha_node.path, saved_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[prop].Value[0] = ''

    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

    Geo.output_geo(soppath, now, properties)
    return