def is_multimat(obj): """Check if a material is a multimaterial.""" try: is_app_feature = obj.isDerivedFrom("App::FeaturePython") except AttributeError: return False is_type_multimat = getproxyattr(obj, "Type", None) == "MultiMaterial" return obj is not None and is_app_feature and is_type_multimat
def get_rendering_string(self, view): """Provide a rendering string for the view of an object. This method selects the specialized rendering method adapted for 'view', according to its source object type, and calls it. Parameters: view -- the view of the object to render Returns: a rendering string in the format of the external renderer for the supplied 'view' """ try: source = view.Source objtype = getproxyattr(source, "type", "Object") name = str(source.Name) switcher = { "Object": RendererHandler._render_object, "PointLight": RendererHandler._render_pointlight, "Camera": RendererHandler._render_camera, "AreaLight": RendererHandler._render_arealight, "SunskyLight": RendererHandler._render_sunskylight, "ImageLight": RendererHandler._render_imagelight, } res = switcher[objtype](self, name, view) except (AttributeError, TypeError, AssertionError) as err: msg = translate( "Render", "[Render] Cannot render view '{0}': {1} (file {2}, " "line {3} in {4}). Skipping...\n") _, _, exc_traceback = sys.exc_info() framestack = traceback.extract_tb(exc_traceback)[-1] App.Console.PrintWarning(msg.format( getattr(view, "Label", "<No label>"), err, framestack.filename, framestack.lineno, framestack.name)) return "" else: return res
def is_renderable(obj): """Determine if an object is renderable. This is a weak test: we just check if the object belongs to a class we would know how to handle - no further verification is made on the consistency of the object data against get_rendering_string requirements. """ try: res = (obj.isDerivedFrom("Part::Feature") or obj.isDerivedFrom("App::Link") or obj.isDerivedFrom("Mesh::Feature") or (obj.isDerivedFrom("App::FeaturePython") and getproxyattr(obj, "type", "") in [ "PointLight", "Camera", "AreaLight", "SunskyLight", "ImageLight" ])) except AttributeError: res = False return res
def get_renderables(obj, name, upper_material, mesher, **kwargs): """Get the renderables from a FreeCAD object. A renderable is a tuple (name, mesh, material). There can be several renderables for one object, for instance if the object is a compound of subobjects, so the result of this function is a **list** of renderables. If this function does not know how to extract renderables from the given object, a TypeError is raised Parameters: obj -- the FreeCAD object from which to extract the renderables name -- the name of the object upper_material -- the FreeCAD material inherited from the upper level mesher -- a callable which can convert a shape into a mesh Keywords arguments: ignore_unknown -- a flag to prevent exception raising if 'obj' is of no renderable type transparency_boost -- a factor (positive integer) to boost transparency in shape color Returns: A list of renderables """ obj_is_applink = obj.isDerivedFrom("App::Link") obj_is_partfeature = obj.isDerivedFrom("Part::Feature") obj_is_meshfeature = obj.isDerivedFrom("Mesh::Feature") obj_is_app_part = obj.isDerivedFrom("App::Part") obj_type = getproxyattr(obj, "Type", "") mat = (getattr(obj, "Material", None) if upper_material is None else upper_material) mat = mat if is_valid_material(mat) or is_multimat(mat) else None del upper_material # Should not be used after this point... label = getattr(obj, "Label", name) ignore_unknown = bool(kwargs.get("ignore_unknown", False)) transparency_boost = int(kwargs.get("transparency_boost", 0)) # Link (plain) if obj_is_applink and not obj.ElementCount: debug("Object", label, "'Link (plain)' detected") renderables = \ _get_rends_from_plainapplink(obj, name, mat, mesher, **kwargs) # Link (array) elif obj_is_applink and obj.ElementCount: debug("Object", label, "'Link (array)' detected") renderables = \ _get_rends_from_elementlist(obj, name, mat, mesher, **kwargs) # Array, PathArray elif obj_is_partfeature and obj_type in ("Array", "PathArray"): debug("Object", label, "'%s' detected" % obj_type) expand_array = getattr(obj, "ExpandArray", False) renderables = (_get_rends_from_array(obj, name, mat, mesher, **kwargs) if not expand_array else _get_rends_from_elementlist( obj, name, mat, mesher, **kwargs)) # Window elif obj_is_partfeature and obj_type == "Window": debug("Object", label, "'Window' detected") renderables = _get_rends_from_window(obj, name, mat, mesher, **kwargs) # Wall elif obj_is_partfeature and obj_type == "Wall": debug("Object", label, "'Wall' detected") renderables = _get_rends_from_wall(obj, name, mat, mesher, **kwargs) # App part elif obj_is_app_part: debug("Object", label, "'App::Part' detected") renderables = _get_rends_from_part(obj, name, mat, mesher, **kwargs) # Plain part feature elif obj_is_partfeature: debug("Object", label, "'Part::Feature' detected") renderables = _get_rends_from_feature(obj, name, mat, mesher, **kwargs) # Mesh elif obj_is_meshfeature: debug("Object", label, "'Mesh::Feature' detected") color = _get_shapecolor(obj, transparency_boost) renderables = [Renderable(name, obj.Mesh, mat, color)] # Unhandled else: renderables = [] if not ignore_unknown: ascendants = ", ".join(obj.getAllDerivedFrom()) msg = translate("Render", "Unhandled object type (%s)" % ascendants) raise TypeError(msg) debug("Object", label, "Not renderable") return renderables