def output_instances(obj, wrangler, now): """Define any instances referenced by the Soho Object This method takes an object and based on its parms and point attributes will iterate over any found instances and output them so they can be later referenced. """ instances = list_instances(obj) if not instances: return for instance in instances: if instance in scene_state.instanced_geo: continue scene_state.instanced_geo.add(instance) # Since a referenced geo might not be displayed, output its # mediums if any. # TODO this works but is a bit magic, rethink this and see if there # is a better approach. instance_obj = soho.getObject(instance) output_materials(instance_obj, wrangler, now) output_mediums(instance_obj, wrangler, now) with api.ObjectBlock(instance), api.AttributeBlock(): soho_obj = soho.getObject(instance) wrangle_obj(soho_obj, wrangler, now) print() return
def output_instances(obj, wrangler, now): """Define any instances referenced by the Soho Object This method takes an object and based on its parms and point attributes will iterate over any found instances and output them so they can be later referenced. """ for instance in find_referenced_instances(obj): if instance in scene_state.instanced_geo: # If we've already emitted this reference geometry # then continue so we don't have duplicate definitions # this can happen if multiple instance nodes reference # the same geo continue scene_state.instanced_geo.add(instance) # Since a referenced geo might not be displayed, output its # mediums if any. # TODO this works but is a bit magic, rethink this and see if there # is a better approach. instance_obj = soho.getObject(instance) output_materials(instance_obj, wrangler, now) output_mediums(instance_obj, wrangler, now) with api.ObjectBlock(instance), api.AttributeBlock(): soho_obj = soho.getObject(instance) wrangle_obj(soho_obj, wrangler, now) print() return
def outputMaterial(shop_path, now): if _Settings.SavedMaterials.get(shop_path, None) == None: shop = soho.getObject(shop_path) ray_start('material') outputObject(shop, now, name=shop_path, output_shader=True) if _Settings.GenerateMaterialname: ray_property('object', 'materialname', [shop_path]) ray_end() _Settings.SavedMaterials[shop_path] = True
def outputMaterial(shop_path, now, skip='default'): '''Dirty way to support at least principle (disney) material.''' if shop_path == skip: return None material = soho.getObject(shop_path) obj = hou.node(shop_path) if not obj and shop_path != skip: raise Exception("This should not happen.") # if obj.type().name().startswith('principledshader::'): return outputPrincipledShader(obj, now)
def get_full_instance_info(obj, now): tokens = obj.getName().split(":") if len(tokens) != 3: return None instancer_obj = soho.getObject(tokens[1]) instancer_sop = [] if not instancer_obj.evalString("object:soppath", now, instancer_sop): return None instancer_sop = instancer_sop[0] gdp = SohoGeometry(instancer_sop, now) if gdp is None: return None return _FullInstance(tokens[0], tokens[1], int(tokens[2]), gdp)
def output_materials(obj, wrangler, now): """Output Materials for an object The shop_materialpath parameter and shop_materialpath prim attribute are both checked for output. """ # We use a shaderhandle instead of a string so Soho instances are properly # resolved when Full Instancing is used. parms = [soho.SohoParm('shop_materialpath', 'shaderhandle', skipdefault=False)] eval_parms = obj.evaluate(parms, now) if eval_parms: shop = eval_parms[0].Value[0] if shop: wrangle_shading_network(shop) soppath = [] if not obj.evalString('object:soppath', now, soppath): return soppath = soppath[0] gdp = SohoGeometry(soppath, now) global_material = gdp.globalValue('shop_materialpath') if global_material is not None: wrangle_shading_network(global_material[0]) attrib_h = gdp.attribute('geo:prim', 'shop_materialpath') if attrib_h >= 0: shop_materialpaths = gdp.attribProperty(attrib_h, 'geo:allstrings') for shop in shop_materialpaths: wrangle_shading_network(shop) # TODO / CONSIDER, for very large number of instance objects it might speed things # up to cache the fact we've already visited a source network. Store in scenestate? # (This will avoid much of the below on a per instance basis) instance_info = get_full_instance_info(obj) if instance_info is not None: instance_source = soho.getObject(instance_info.source) sourcesop_path = [] if not instance_source.evalString('object:soppath', now, sourcesop_path): return sourcesop_path = sourcesop_path[0] gdp = SohoGeometry(sourcesop_path, now) attrib_h = gdp.attribute('geo:point', 'shop_materialpath') if attrib_h >= 0: shop_materialpaths = gdp.attribProperty(attrib_h, 'geo:allstrings') for shop in shop_materialpaths: wrangle_shading_network(shop) return
def getObjectShader(shop_path, shader_type, now): shop = soho.getObject(shop_path) print dir(shop) print shop.getDefaultedShader() skiplist = shop.evaluate(oshaderSkipParms, now) shader_prop = oshaderMap[shader_type] skip = False if skiplist and shader_prop in skiplist: skip = skiplist[shader_prop].Value[0] # if not skip: # TODO disabling it intentionally shader = [] shop_type = [] if shop.evalShaderAndType(shader_type, now, shader, shop_type): return (shader[0], shop_type[0]) return None
def process_full_pt_instance_material(obj, now): # The order of evaluation. # 1. shaders attached to the actual prims (handled in PBRTgeo.py) # 2. per point assignments on the instancer # 3. instancer's shop_materialpath # 4. object being instanced shop_materialpath # 5. nothing # The choice between 3 and 4 is handled automatically by soho full_instance_info = get_full_instance_info(obj) instancer_obj = soho.getObject(full_instance_info.source) instancer_sop = [] if not instancer_obj.evalString('object:soppath', now, instancer_sop): return False instancer_sop = instancer_sop[0] gdp = SohoGeometry(instancer_sop, now) override_attrib_h = gdp.attribute('geo:point', 'material_overrides') shop_attrib_h = gdp.attribute('geo:point', 'shop_materialpath') if shop_attrib_h < 0: return False # We can just reference a NamedMaterial since there are no overrides if shop_attrib_h >= 0 and override_attrib_h < 0: shop = gdp.value(shop_attrib_h, full_instance_info.number)[0] if shop in scene_state.shading_nodes: api.NamedMaterial(shop) else: raise ValueError('Could not find shop in scene state') return True # Fully expand shading network since there will be uniqueness #return #wrangle_shading_network(shop, # use_named=False, # saved_nodes=set() # ) return False
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
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
excludefog = objparms['excludefog'].Value[0] sololight = objparms['sololight'].Value[0] matte_objects = objparms['matte_objects'].Value[0] phantom_objects = objparms['phantom_objects'].Value[0] forcelightsparm = 'forcelights' if sololight: stdlights = excludelights = '' forcelights = sololight forcelightsparm = 'sololight' # Obtain the list of cameras through which we need to render. The main camera # may specify a few sub-cameras, for example, in the stereo camera case. camera_paths = objparms['vm_cameralist'].Value[0].split() camera_list = [] for cam_path in camera_paths: camera_list.append(soho.getObject(cam_path)) if len(camera_list) == 0: cam.storeData('NoFileSuffix', True) camera_list.append(cam) # First, we add objects based on their display flags or dimmer values soho.addObjects(now, stdobject, stdlights, stdfog, True, geo_parm='vobject', light_parm='alights', fog_parm='vfog') soho.addObjects(now, forceobject,
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