def _render_sunskylight(self, name, view):
        """Get a rendering string for a sunsky light object.

        This method follows EAFP idiom and will raise exceptions if something
        goes wrong (missing attribute, inconsistent data...).

        Parameters:
        name -- the name of the sunsky light
        view -- the view of the sunsky light (contains the light data)

        Returns: a rendering string, obtained from the renderer module
        """
        debug("SunskyLight", name, "Processing")
        src = view.Source
        direction = App.Vector(src.SunDirection)
        turbidity = float(src.Turbidity)
        # Distance from the sun:
        distance = App.Units.parseQuantity("151000000 km").Value

        assert turbidity >= 0,\
            translate("Render", "Negative turbidity")

        assert direction.Length,\
            translate("Render", "Sun direction is null")

        return self._call_renderer("write_sunskylight", name, direction,
                                   distance, turbidity)
Пример #2
0
    def _point_at_cb(self, event_cb):
        """`point_at` method callback.

        Args:
            event_cb -- coin event callback object
        """
        event = event_cb.getEvent()
        if (event.getState() == coin.SoMouseButtonEvent.DOWN
                and event.getButton() == coin.SoMouseButtonEvent.BUTTON1):
            # Get point
            picked_point = event_cb.getPickedPoint()
            try:
                point = App.Vector(picked_point.getPoint())
            except AttributeError:
                # No picked point (outside geometry)
                msg = translate(
                    "Render", "[Point at] Target outside geometry "
                    "-- Aborting") + "\n"
                App.Console.PrintMessage(msg)
            else:
                # Make underlying object point at target point
                self.fpo.Proxy.point_at(point)
                msg = translate(
                    "Render", "[Point at] Now pointing at "
                    "({0.x}, {0.y}, {0.z})") + "\n"
                App.Console.PrintMessage(msg.format(point))
            finally:
                # Remove coin event catcher
                Gui.ActiveDocument.ActiveView.removeEventCallbackPivy(
                    coin.SoMouseButtonEvent.getClassTypeId(), self.callback)
Пример #3
0
def check_renderables(renderables):
    """Assert compliance of a list of renderables."""
    assert renderables,\
        translate("Render", "Nothing to render")
    for renderable in renderables:
        mesh = renderable.mesh
        assert mesh,\
            translate("Render", "Cannot find mesh data")
        assert mesh.Topology[0] and mesh.Topology[1],\
            translate("Render", "Mesh topology is empty")
        assert mesh.getPointNormals(),\
            translate("Render", "Mesh topology has no normals")
Пример #4
0
    def __init__(self, rdrname, **kwargs):
        """Initialize RendererHandler class.

        Args:
            rdrname -- renderer name (str). Must match a renderer plugin name.

        Keyword args:
            linear_deflection -- linear deflection (float) to be passed to
                mesher
            angular_deflection -- angular deflection (float) to be passed to
                mesher.
            transparency_boost -- an integer to augment transparency in
                implicit material computation
        """
        self.renderer_name = str(rdrname)
        self.linear_deflection = float(kwargs.get("linear_deflection", .1))
        self.angular_deflection = float(kwargs.get("angular_deflection", .524))
        self.transparency_boost = float(kwargs.get("transparency_boost", 0))

        try:
            self.renderer_module = import_module("renderers." + rdrname)
        except ModuleNotFoundError:
            msg = translate(
                "Render",
                "[Render] Import Error: Renderer '%s' not found\n") % rdrname
            App.Console.PrintError(msg)
            raise
Пример #5
0
    def point_at(self):
        """Make this camera point at another object.

        User will be requested to select an object to point at.
        """
        msg = translate("Render",
                        "[Point at] Please select target (on geometry)") + "\n"
        App.Console.PrintMessage(msg)
        self.callback = Gui.ActiveDocument.ActiveView.addEventCallbackPivy(
            coin.SoMouseButtonEvent.getClassTypeId(), self._point_at_cb)
Пример #6
0
def _get_rends_from_window(obj, name, material, mesher, **kwargs):
    """Get renderables from an Window object (from Arch workbench).

    Parameters:
        obj -- the Window object
        name -- the name assigned to the Window object for rendering
        material -- the material for the Window object (should be a
                    multimaterial)
        mesher -- a callable object which converts a shape into a mesh

    Returns:
        A list of renderables for the Window object
    """
    # Subobjects names
    window_parts = obj.WindowParts
    if not window_parts and hasattr(obj, "CloneOf") and obj.CloneOf:
        # Workaround: if obj is a window Clone, WindowsParts is unfortunately
        # not replicated (must be a bug...). Therefore we look at base's
        # WindowsParts
        window_parts = obj.CloneOf.WindowParts
    subnames = window_parts[0::5]  # Names every 5th item...
    names = ["%s_%s" % (name, s.replace(' ', '_')) for s in subnames]

    # Subobjects meshes
    meshes = [mesher(s) for s in obj.Shape.childShapes()]

    # Subobjects colors
    transparency_boost = kwargs.get("transparency_boost", 0)
    faces_len = [len(s.Faces) for s in obj.Shape.Solids]
    if obj.ViewObject is not None:  # Gui is up
        colors = [
            _boost_tp(obj.ViewObject.DiffuseColor[i], transparency_boost)
            for i in itertools.accumulate([0] + faces_len[:-1])
        ]
    else:
        colors = [RGBA(0.8, 0.8, 0.8, 1)] * len(subnames)

    # Subobjects materials
    if material is not None:
        assert is_multimat(material), "Multimaterial expected"
        mats_dict = dict(zip(material.Names, material.Materials))
        mats = [mats_dict.get(s) for s in subnames]
        if [m for m in mats if not m]:
            msg = translate("Render", "Incomplete multimaterial (missing {})")
            missing_mats = ', '.join(set(subnames) - mats_dict.keys())
            warn("Window", obj.Label, msg.format(missing_mats))
    else:
        mats = [None] * len(subnames)

    # Build renderables
    return [Renderable(*r) for r in zip(names, meshes, mats, colors)]
Пример #7
0
    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 __init__(self, rdrname, angular_deflection, linear_deflection):
        """Initialize RendererHandler class.

        Args:
            rdrname -- renderer name (str). Must match a renderer plugin name.
            linear_deflection -- linear deflection (float) to be passed to
                mesher
            angular_deflection -- angular deflection (float) to be passed to
                mesher.
        """
        self.renderer_name = str(rdrname)
        self.linear_deflection = float(linear_deflection)
        self.angular_deflection = float(angular_deflection)

        try:
            self.renderer_module = import_module("renderers." + rdrname)
        except ModuleNotFoundError:
            msg = translate(
                "Render",
                "[Render] Import Error: Renderer '%s' not found\n") % rdrname
            App.Console.PrintError(msg)
            raise
Пример #9
0
 def message(self):
     """Give error message."""
     msg = translate(
         "Render",
         "[Render] Error: Renderer '%s' not found") % self.renderer
     return msg
Пример #10
0
                         translate)

# ===========================================================================
#                                   Export
# ===========================================================================

Param = collections.namedtuple("Param", "name type default desc")

# IMPORTANT: Please note that, by convention, the first parameter of each
# material will be used as default color in fallback mechanisms.
# Please be careful to preserve a color-typed field as first parameter of each
# material, if you modify an existing material or you add a new one...
STD_MATERIALS_PARAMETERS = {
    "Glass": [
        Param("Color", "RGB", (1, 1, 1),
              translate("Render", "Transmitted color")),
        Param("IOR", "float", 1.5, translate("Render", "Index of refraction")),
    ],
    "Disney": [
        Param("BaseColor", "RGB", (0.8, 0.8, 0.8),
              translate("Render", "Base color")),
        Param("Subsurface", "float", 0.0,
              translate("Render", "Subsurface coefficient")),
        Param("Metallic", "float", 0.0,
              translate("Render", "Metallic coefficient")),
        Param("Specular", "float", 0.0,
              translate("Render", "Specular coefficient")),
        Param("SpecularTint", "float", 0.0,
              translate("Render", "Specular tint coefficient")),
        Param("Roughness", "float", 0.0,
              translate("Render", "Roughness coefficient")),
Пример #11
0
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