def packeddisk_wrangler(gdp, paramset=None, properties=None, override_node=None): """Outputs "ply" Shapes for the input geometry Args: gdp (hou.Geometry): Input geo paramset (ParamSet): Any base params to add to the shape. (Optional) properties (dict): Dictionary of SohoParms (Optional) Returns: None """ alpha_paramset = mesh_alpha_texs(properties) for prim in gdp.prims(): shape_paramset = ParamSet(paramset) shape_paramset |= prim_override(prim, override_node) filename = prim.intrinsicValue("filename") if not filename: continue if os.path.splitext(filename)[1].lower() != ".ply": continue shape_paramset.replace(PBRTParam("string", "filename", filename)) shape_paramset.update(alpha_paramset) with api.TransformBlock(): xform = prim_transform(prim) api.ConcatTransform(xform) api.Shape("plymesh", shape_paramset) return
def medium_prim_paramset(prim, paramset=None): """Build a ParamSet of medium values based off of hou.Prim attribs""" medium_paramset = ParamSet(paramset) # NOTE: # Testing for prim attribs on each prim is a bit redundat but # in general its not an issue as you won't have huge numbers of # volumes. If this does become an issue, attribs can be stored in # a dict and searched from there. (This includes evaluating the # pbrt_interior node. # Initialize with the interior shader on the prim, if it exists. try: interior = prim.stringAttribValue("pbrt_interior") interior = BaseNode.from_node(interior) except hou.OperationFailed: interior = None if interior and interior.directive_type == "pbrt_medium": medium_paramset |= interior.paramset try: preset_value = prim.stringAttribValue("preset") if preset_value: medium_paramset.replace(PBRTParam("string", "preset", preset_value)) except hou.OperationFailed: pass try: g_value = prim.floatAttribValue("g") medium_paramset.replace(PBRTParam("float", "g", g_value)) except hou.OperationFailed: pass try: scale_value = prim.floatAttribValue("scale") medium_paramset.replace(PBRTParam("float", "scale", scale_value)) except hou.OperationFailed: pass try: sigma_a_value = prim.floatListAttribValue("sigma_a") if len(sigma_a_value) == 3: medium_paramset.replace(PBRTParam("rgb", "sigma_a", sigma_a_value)) except hou.OperationFailed: pass try: sigma_s_value = prim.floatListAttribValue("sigma_s") if len(sigma_s_value) == 3: medium_paramset.replace(PBRTParam("rgb", "sigma_s", sigma_s_value)) except hou.OperationFailed: pass return medium_paramset
def process_full_pt_instance_medium(instance_info, medium_type): gdp = instance_info.gdp if medium_type not in ("interior", "exterior"): return None, None medium_attrib_h = gdp.attribute("geo:point", "pbrt_" + medium_type) if medium_attrib_h < 0: return None, None medium = gdp.value(medium_attrib_h, instance_info.number)[0] # an empty string is valid here as it means no medium if medium == "": return medium, ParamSet() suffix = ":%s[%i]" % (instance_info.source, instance_info.number) medium_node = BaseNode.from_node(medium) medium_node.path_suffix = suffix if not (medium_node and medium_node.directive_type == "pbrt_medium"): return None, None medium_paramset = ParamSet(medium_node.paramset) # TODO: Currently both this and the geometry overrides # for mediums only support "rgb" and not spectrums. parms = { "sigma_a": "rgb", "sigma_s": "rgb", "preset": "string", "g": "float", "scale": "float", } for parm, ptype in parms.iteritems(): attrib_name = "%s_%s" % (medium_type, parm) attrib_h = gdp.attribute("geo:point", attrib_name) if attrib_h < 0: continue # TODO: Checks? # attrib_size = gdp.attribProperty(attrib_h, "geo:vectorsize")[0] # attrib_storage = gdp.attribProperty(attrib_h, "geo:storage")[0] val = gdp.value(attrib_h, instance_info.number) medium_paramset.replace(PBRTParam(ptype, parm, val)) # We might be outputing a named medium even if its not going to be needed # as in the case of instancing volume prims api.MakeNamedMedium(medium_node.full_name, "homogeneous", medium_paramset) return medium_node.full_name, medium_paramset
def tube_wrangler(gdp, paramset=None, properties=None, override_node=None): """Outputs "cone" or "cylinder" Shapes for the input geometry Args: gdp (hou.Geometry): Input geo paramset (ParamSet): Any base params to add to the shape. (Optional) properties (dict): Dictionary of SohoParms (Optional) Returns: None """ for prim in gdp.prims(): shape_paramset = ParamSet(paramset) shape_paramset |= prim_override(prim, override_node) with api.TransformBlock(): side_paramset = ParamSet(shape_paramset) xform = prim_transform(prim) taper = prim.intrinsicValue("tubetaper") # workaround, see TODO below in the else: pass if not (taper == 0 or taper == 1): api.Comment( "Skipping tube, prim # %i, with non-conforming taper of %f" % (prim.number(), taper)) continue closed = prim.intrinsicValue("closed") api.ConcatTransform(xform) api.Rotate(-90, 1, 0, 0) if taper == 0: shape = "cone" api.Translate(0, 0, -0.5) elif taper == 1: shape = "cylinder" side_paramset.add(PBRTParam("float", "zmin", -0.5)) side_paramset.add(PBRTParam("float", "zmax", 0.5)) else: # TODO support hyperboloid, however pbrt currently # has no ends of trouble with this shape type # crashes or hangs api.Comment("Hyperboloid skipped due to PBRT instability") with api.AttributeBlock(): api.ReverseOrientation() # Flip in Y so parameteric UV's match Houdini's api.Scale(1, -1, 1) api.Shape(shape, side_paramset) if closed: disk_paramset = ParamSet(shape_paramset) if shape == "cylinder": disk_paramset.add(PBRTParam("float", "height", 0.5)) api.Shape("disk", disk_paramset) disk_paramset.replace(PBRTParam("float", "height", -0.5)) with api.AttributeBlock(): api.ReverseOrientation() api.Shape("disk", disk_paramset) else: with api.AttributeBlock(): api.ReverseOrientation() api.Shape("disk", disk_paramset) return