Example #1
0
    def __init__(self, width, height):
        super().__init__("selection", width, height, -999)

        self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "selection.shader"))
        self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
        self._gl = OpenGL.getInstance().getBindingsObject()
        self._scene = Application.getInstance().getController().getScene()

        self._renderer = Application.getInstance().getRenderer()

        self._selection_map = {}
        self._toolhandle_selection_map = {
            self._dropAlpha(ToolHandle.DisabledSelectionColor): ToolHandle.NoAxis,
            self._dropAlpha(ToolHandle.XAxisSelectionColor): ToolHandle.XAxis,
            self._dropAlpha(ToolHandle.YAxisSelectionColor): ToolHandle.YAxis,
            self._dropAlpha(ToolHandle.ZAxisSelectionColor): ToolHandle.ZAxis,
            self._dropAlpha(ToolHandle.AllAxisSelectionColor): ToolHandle.AllAxis,
            ToolHandle.DisabledSelectionColor: ToolHandle.NoAxis,
            ToolHandle.XAxisSelectionColor: ToolHandle.XAxis,
            ToolHandle.YAxisSelectionColor: ToolHandle.YAxis,
            ToolHandle.ZAxisSelectionColor: ToolHandle.ZAxis,
            ToolHandle.AllAxisSelectionColor: ToolHandle.AllAxis
        }

        self._output = None
Example #2
0
    def _initialize(self):
        OpenGL.setInstance(QtOpenGL())
        self._gl = OpenGL.getInstance().getBindingsObject()

        self._default_material = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))

        self._render_passes.add(DefaultPass(self._viewport_width, self._viewport_height))
        self._render_passes.add(SelectionPass(self._viewport_width, self._viewport_height))
        self._render_passes.add(CompositePass(self._viewport_width, self._viewport_height))

        buffer = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer)
        buffer.create()
        buffer.bind()
        buffer.allocate(120)
        data = numpy.array([
            -1.0, -1.0, 0.0,
             1.0,  1.0, 0.0,
            -1.0,  1.0, 0.0,
            -1.0, -1.0, 0.0,
             1.0, -1.0, 0.0,
             1.0,  1.0, 0.0,
             0.0,  0.0,
             1.0,  1.0,
             0.0,  1.0,
             0.0,  0.0,
             1.0,  0.0,
             1.0,  1.0
        ], dtype = numpy.float32).tostring()
        buffer.write(0, data, len(data))
        buffer.release()
        self._quad_buffer = buffer

        self._initialized = True
Example #3
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._enabled_shader:
            self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader"))
            self._disabled_shader.setUniformValue("u_diffuseColor1", [0.48, 0.48, 0.48, 1.0])
            self._disabled_shader.setUniformValue("u_diffuseColor2", [0.68, 0.68, 0.68, 1.0])
            self._disabled_shader.setUniformValue("u_width", 50.0)

        if Application.getInstance().getGlobalContainerStack():
            if Preferences.getInstance().getValue("view/show_overhang"):
                angle = Application.getInstance().getGlobalContainerStack().getProperty("support_angle", "value")
                if angle is not None:
                    self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle)))
                else:
                    self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang.
            else:
                self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    # TODO: Find a better way to handle this
                    #if node.getBoundingBoxMesh():
                    #    renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines)

                    uniforms = {}
                    if self._extruders_model.rowCount() > 0:
                        # Get color to render this mesh in from ExtrudersModel
                        extruder_index = 0
                        extruder_id = node.callDecoration("getActiveExtruder")
                        if extruder_id:
                            extruder_index = max(0, self._extruders_model.find("id", extruder_id))

                        extruder_color = self._extruders_model.getItem(extruder_index)["colour"]
                        try:
                            # Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
                            # an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
                            uniforms["diffuse_color"] = [
                                int(extruder_color[1:3], 16) / 255,
                                int(extruder_color[3:5], 16) / 255,
                                int(extruder_color[5:7], 16) / 255,
                                1.0
                            ]
                        except ValueError:
                            pass

                    if hasattr(node, "_outside_buildarea"):
                        if node._outside_buildarea:
                            renderer.queueNode(node, shader = self._disabled_shader)
                        else:
                            renderer.queueNode(node, shader = self._enabled_shader, uniforms = uniforms)
                    else:
                        renderer.queueNode(node, material = self._enabled_shader, uniforms = uniforms)
                if node.callDecoration("isGroup"):
                    renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(), mode = Renderer.RenderLines)
    def __init__(self, width, height):
        super().__init__("composite", width, height, RenderPass.MaximumPriority)

        self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "composite.shader"))
        self._gl = OpenGL.getInstance().getBindingsObject()
        self._renderer = Application.getInstance().getRenderer()

        self._layer_bindings = [ "default", "selection" ]
    def __init__(self, width, height):
        super().__init__("selection", width, height, -999)

        self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "selection.shader"))
        self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
        self._gl = OpenGL.getInstance().getBindingsObject()
        self._scene = Application.getInstance().getController().getScene()

        self._renderer = Application.getInstance().getRenderer()

        self._selection_map = {}
        self._output = None
Example #6
0
    def render(self):
        if not self._layer_shader:
            self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layers.shader"))
        # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
        self._layer_shader.setUniformValue("u_active_extruder", float(max(0, self._extruder_manager.activeExtruderIndex)))
        if not self._tool_handle_shader:
            self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        self.bind()

        tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay)

        for node in DepthFirstIterator(self._scene.getRoot()):
            if isinstance(node, ToolHandle):
                tool_handle_batch.addItem(node.getWorldTransformation(), mesh = node.getSolidMesh())

            elif isinstance(node, SceneNode) and node.getMeshData() and node.isVisible():
                layer_data = node.callDecoration("getLayerData")
                if not layer_data:
                    continue

                # Render all layers below a certain number as line mesh instead of vertices.
                if self._layerview._current_layer_num - self._layerview._solid_layers > -1 and not self._layerview._only_show_top_layers:
                    start = 0
                    end = 0
                    element_counts = layer_data.getElementCounts()
                    for layer, counts in element_counts.items():
                        if layer + self._layerview._solid_layers > self._layerview._current_layer_num:
                            break
                        end += counts

                    # This uses glDrawRangeElements internally to only draw a certain range of lines.
                    batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid, mode = RenderBatch.RenderMode.Lines, range = (start, end))
                    batch.addItem(node.getWorldTransformation(), layer_data)
                    batch.render(self._scene.getActiveCamera())

                # Create a new batch that is not range-limited
                batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid)

                if self._layerview._current_layer_mesh:
                    batch.addItem(node.getWorldTransformation(), self._layerview._current_layer_mesh)

                if self._layerview._current_layer_jumps:
                    batch.addItem(node.getWorldTransformation(), self._layerview._current_layer_jumps)

                if len(batch.items) > 0:
                    batch.render(self._scene.getActiveCamera())

        # Render toolhandles on top of the layerview
        if len(tool_handle_batch.items) > 0:
            tool_handle_batch.render(self._scene.getActiveCamera())

        self.release()
Example #7
0
    def __init__(self, width, height):
        super().__init__("composite", width, height, RenderPass.MaximumPriority)

        self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "composite.shader"))
        theme = Application.getInstance().getTheme()
        self._shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
        self._shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))

        self._gl = OpenGL.getInstance().getBindingsObject()
        self._renderer = Application.getInstance().getRenderer()

        self._layer_bindings = [ "default", "selection" ]
Example #8
0
    def render(self, renderer):
        if not self.getMeshData():
            return True

        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
            self._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader"))

        renderer.queueNode(self, mode = RenderBatch.RenderMode.Lines)
        renderer.queueNode(self, mesh = self._grid_mesh, shader = self._grid_shader, backface_cull = True)
        if self._disallowed_area_mesh:
            renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9)
        return True
Example #9
0
    def _updateTexture(self):
        if not self._global_container_stack or not OpenGL.getInstance():
            return

        self._texture = OpenGL.getInstance().createTexture()

        container = self._global_container_stack.findContainer({"platform_texture":"*"})
        if container:
            texture_file = container.getMetaDataEntry("platform_texture")
            self._texture.load(Resources.getPath(Resources.Images, texture_file))
        # Note: if no texture file is specified, a 1 x 1 pixel transparent image is created
        # by UM.GL.QtTexture to prevent rendering issues

        if self._shader:
            self._shader.setTexture(0, self._texture)
Example #10
0
    def _updateTexture(self):
        if not self._machine_instance or not OpenGL.getInstance():
            return

        texture_file = self._machine_instance.getMachineDefinition().getPlatformTexture()
        if texture_file:
            self._texture = OpenGL.getInstance().createTexture()
            self._texture.load(Resources.getPath(Resources.Images, texture_file))

            if self._shader:
                self._shader.setTexture(0, self._texture)
        else:
            self._texture = None
            if self._shader:
                self._shader.setTexture(0, None)
Example #11
0
    def event(self, event):
        if event.type == Event.ViewActivateEvent:
            if not self._xray_pass:
                # Currently the RenderPass constructor requires a size > 0
                # This should be fixed in RenderPass's constructor.
                self._xray_pass = XRayPass.XRayPass(1, 1)
                self.getRenderer().addRenderPass(self._xray_pass)

            if not self._xray_composite_shader:
                self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
                self._xray_composite_shader.setUniformValue("u_error_color", Color(*theme.getColor("xray_error").getRgb()))
                self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))

            if not self._composite_pass:
                self._composite_pass = self.getRenderer().getRenderPass("composite")

            self._old_layer_bindings = self._composite_pass.getLayerBindings()
            self._composite_pass.setLayerBindings(["default", "selection", "xray"])
            self._old_composite_shader = self._composite_pass.getCompositeShader()
            self._composite_pass.setCompositeShader(self._xray_composite_shader)

        if event.type == Event.ViewDeactivateEvent:
            self._composite_pass.setLayerBindings(self._old_layer_bindings)
            self._composite_pass.setCompositeShader(self._old_composite_shader)
Example #12
0
    def createMaterial(self):
        self._material = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))

        self._material.setUniformValue("u_ambientColor", Color(0.3, 0.3, 0.3, 1.0))
        self._material.setUniformValue("u_diffuseColor", self._color)
        self._material.setUniformValue("u_specularColor", Color(1.0, 1.0, 1.0, 1.0))
        self._material.setUniformValue("u_shininess", 50.0)
Example #13
0
    def _updateTexture(self):
        if not self._global_container_stack or not OpenGL.getInstance():
            return

        container = self._global_container_stack.findContainer({"platform_texture":"*"})
        if container:
            texture_file = container.getMetaDataEntry("platform_texture")
            if texture_file:
                self._texture = OpenGL.getInstance().createTexture()
                self._texture.load(Resources.getPath(Resources.Images, texture_file))

                if self._shader:
                    self._shader.setTexture(0, self._texture)
        else:
            self._texture = None
            if self._shader:
                self._shader.setTexture(0, None)
Example #14
0
    def __init__(self, name: str, width: int, height: int, priority: int = 0) -> None:
        self._name = name #type: str
        self._width = width #type: int
        self._height = height #type: int
        self._priority = priority #type: int

        self._gl = OpenGL.getInstance().getBindingsObject()

        self._fbo = None #type: Optional[FrameBufferObject]
Example #15
0
    def __init__(self, width, height):
        super().__init__("layerview", width, height)

        self._layer_shader = None
        self._tool_handle_shader = None
        self._gl = OpenGL.getInstance().getBindingsObject()
        self._scene = Application.getInstance().getController().getScene()
        self._extruder_manager = ExtruderManager.getInstance()

        self._layer_view = None
Example #16
0
    def __init__(self, name, width, height, priority = 0):
        self._name = name
        self._width = width
        self._height = height
        self._priority = priority

        self._gl = OpenGL.getInstance().getBindingsObject()

        self._fbo = None

        self._updateRenderStorage()
Example #17
0
    def render(self, renderer):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
            self._shader.setUniformValue("u_color", self._color)

        if self.getParent():
            renderer.queueNode(self, transparent = True, shader = self._shader, backface_cull = True, sort = -8)
            if self._convex_hull_head_mesh:
                renderer.queueNode(self, shader = self._shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)

        return True
Example #18
0
    def _updateRenderStorage(self) -> None:
        # On Mac OS X, this function may get called by a main window resize signal during closing.
        # This will cause a crash, so don't do anything when it is shutting down.
        import UM.Qt.QtApplication
        if UM.Qt.QtApplication.QtApplication.getInstance().isShuttingDown():
            return
        if self._width <= 0 or self._height <= 0:
            Logger.log("w", "Tried to create render pass with size <= 0")
            return

        self._fbo = OpenGL.getInstance().createFrameBufferObject(self._width, self._height)
Example #19
0
    def render(self, renderer):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "platform.shader"))
            if self._texture:
                self._shader.setTexture(0, self._texture)
            else:
                self._updateTexture()

        if self.getMeshData():
            renderer.queueNode(self, shader = self._shader, transparent = True, backface_cull = True, sort = -10)
            return True
Example #20
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "object.shader"))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    renderer.queueNode(node, shader = self._shader)
Example #21
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._enabled_shader:
            self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
            self._disabled_shader.setUniformValue("u_diffuseColor", [0.68, 0.68, 0.68, 1.0])
            self._disabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))

        if Application.getInstance().getMachineManager().getWorkingProfile():
            profile = Application.getInstance().getMachineManager().getWorkingProfile()

            if Preferences.getInstance().getValue("view/show_overhang"):
                angle = profile.getSettingValue("support_angle")
                if angle != None:
                    self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle)))
                else:
                    self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang.
            else:
                self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    # TODO: Find a better way to handle this
                    #if node.getBoundingBoxMesh():
                    #    renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines)
                    if hasattr(node, "_outside_buildarea"):
                        if node._outside_buildarea:
                            renderer.queueNode(node, shader = self._disabled_shader)
                        else:
                            renderer.queueNode(node, shader = self._enabled_shader)
                    else:
                        renderer.queueNode(node, material = self._enabled_shader)
                if node.callDecoration("isGroup"):
                    renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines)
Example #22
0
    def render(self, renderer):
        if not ConvexHullNode.shader:
            ConvexHullNode.shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
            ConvexHullNode.shader.setUniformValue("u_diffuseColor", self._color)
            ConvexHullNode.shader.setUniformValue("u_opacity", 0.6)

        if self.getParent():
            if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate:
                renderer.queueNode(self, transparent = True, shader = ConvexHullNode.shader, backface_cull = True, sort = -8)
                if self._convex_hull_head_mesh:
                    renderer.queueNode(self, shader = ConvexHullNode.shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)

        return True
Example #23
0
    def render(self, renderer):
        if not self.getMeshData():
            return True

        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
            self._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader"))
            theme = Application.getInstance().getTheme()
            self._grid_shader.setUniformValue("u_gridColor0", Color(*theme.getColor("buildplate").getRgb()))
            self._grid_shader.setUniformValue("u_gridColor1", Color(*theme.getColor("buildplate_alt").getRgb()))

        renderer.queueNode(self, mode = RenderBatch.RenderMode.Lines)
        renderer.queueNode(self, mesh = self._origin_mesh)
        renderer.queueNode(self, mesh = self._grid_mesh, shader = self._grid_shader, backface_cull = True)
        if self._disallowed_area_mesh:
            renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9)

        if self._error_mesh:
            renderer.queueNode(self, mesh=self._error_mesh, shader=self._shader, transparent=True,
                               backface_cull=True, sort=-8)

        return True
Example #24
0
    def render(self, renderer):
        if not ConvexHullNode.shader:
            ConvexHullNode.shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
            ConvexHullNode.shader.setUniformValue("u_diffuseColor", self._color)
            ConvexHullNode.shader.setUniformValue("u_opacity", 0.6)

        if self.getParent():
            if self.getMeshData():
                renderer.queueNode(self, transparent = True, shader = ConvexHullNode.shader, backface_cull = True, sort = -8)
                if self._convex_hull_head_mesh:
                    renderer.queueNode(self, shader = ConvexHullNode.shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)

        return True
Example #25
0
    def event(self, event):
        modifiers = QApplication.keyboardModifiers()
        ctrl_is_active = modifiers & Qt.ControlModifier
        shift_is_active = modifiers & Qt.ShiftModifier
        if event.type == Event.KeyPressEvent and ctrl_is_active:
            amount = 10 if shift_is_active else 1
            if event.key == KeyEvent.UpKey:
                self.setLayer(self._current_layer_num + amount)
                return True
            if event.key == KeyEvent.DownKey:
                self.setLayer(self._current_layer_num - amount)
                return True

        if event.type == Event.ViewActivateEvent:
            # Make sure the SimulationPass is created
            layer_pass = self.getSimulationPass()
            self.getRenderer().addRenderPass(layer_pass)

            # Make sure the NozzleNode is add to the root
            nozzle = self.getNozzleNode()
            nozzle.setParent(self.getController().getScene().getRoot())
            nozzle.setVisible(False)

            Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
            self._onGlobalStackChanged()

            if not self._simulationview_composite_shader:
                self._simulationview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), "simulationview_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._simulationview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
                self._simulationview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))

            if not self._composite_pass:
                self._composite_pass = self.getRenderer().getRenderPass("composite")

            self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later
            self._composite_pass.getLayerBindings().append("simulationview")
            self._old_composite_shader = self._composite_pass.getCompositeShader()
            self._composite_pass.setCompositeShader(self._simulationview_composite_shader)

        elif event.type == Event.ViewDeactivateEvent:
            self._wireprint_warning_message.hide()
            Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged)
            if self._global_container_stack:
                self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)

            self._nozzle_node.setParent(None)
            self.getRenderer().removeRenderPass(self._layer_pass)
            self._composite_pass.setLayerBindings(self._old_layer_bindings)
            self._composite_pass.setCompositeShader(self._old_composite_shader)
Example #26
0
    def _initialize(self):
        supports_vao = OpenGLContext.supportsVertexArrayObjects()  # fill the OpenGLContext.properties
        Logger.log("d", "Support for Vertex Array Objects: %s", supports_vao)

        OpenGL.setInstance(OpenGL())
        self._gl = OpenGL.getInstance().getBindingsObject()

        self._default_material = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))

        self._render_passes.add(DefaultPass(self._viewport_width, self._viewport_height))
        self._render_passes.add(SelectionPass(self._viewport_width, self._viewport_height))
        self._render_passes.add(CompositePass(self._viewport_width, self._viewport_height))

        buffer = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer)
        buffer.create()
        buffer.bind()
        buffer.allocate(120)
        data = numpy.array([
            -1.0, -1.0, 0.0,
             1.0,  1.0, 0.0,
            -1.0,  1.0, 0.0,
            -1.0, -1.0, 0.0,
             1.0, -1.0, 0.0,
             1.0,  1.0, 0.0,
             0.0,  0.0,
             1.0,  1.0,
             0.0,  1.0,
             0.0,  0.0,
             1.0,  0.0,
             1.0,  1.0
        ], dtype = numpy.float32).tostring()
        buffer.write(0, data, len(data))
        buffer.release()
        self._quad_buffer = buffer

        self._initialized = True
        self.initialized.emit()
Example #27
0
    def _getOpenGLInfo(self):
        opengl_instance = OpenGL.getInstance()
        if not opengl_instance:
            self.data["opengl"] = {"version": "n/a", "vendor": "n/a", "type": "n/a"}
            return catalog.i18nc("@label", "Not yet initialized<br/>")

        info = "<ul>"
        info += catalog.i18nc("@label OpenGL version", "<li>OpenGL Version: {version}</li>").format(version = opengl_instance.getOpenGLVersion())
        info += catalog.i18nc("@label OpenGL vendor", "<li>OpenGL Vendor: {vendor}</li>").format(vendor = opengl_instance.getGPUVendorName())
        info += catalog.i18nc("@label OpenGL renderer", "<li>OpenGL Renderer: {renderer}</li>").format(renderer = opengl_instance.getGPUType())
        info += "</ul>"

        self.data["opengl"] = {"version": opengl_instance.getOpenGLVersion(), "vendor": opengl_instance.getGPUVendorName(), "type": opengl_instance.getGPUType()}

        return info
Example #28
0
    def render(self, renderer):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        if self._auto_scale:
            camera_position = self._scene.getActiveCamera().getWorldPosition()
            dist = (camera_position - self.getWorldPosition()).length()
            scale = dist / 400
            self.setScale(Vector(scale, scale, scale))

        if self._line_mesh:
            renderer.queueNode(self, mesh = self._line_mesh, mode = RenderBatch.RenderMode.Lines, overlay = True, shader = self._shader)
        if self._solid_mesh:
            renderer.queueNode(self, mesh = self._solid_mesh, overlay = True, shader = self._shader)

        return True
Example #29
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "mesh.shader"))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    if node.getDecorator(PathResultDecorator.PathResultDecorator):
                        renderer.queueNode(node, mode=RenderBatch.RenderMode.Lines, overlay=True)
                    else:
                        renderer.queueNode(node, shader=self._shader)
                if node.callDecoration("isGroup"):
                    renderer.queueNode(scene.getRoot(), mesh=node.getBoundingBoxMesh(), mode=RenderBatch.RenderMode.LineLoop)
Example #30
0
    def render(self):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader"))

        batch = RenderBatch(self._shader, type = RenderBatch.RenderType.NoType, backface_cull = False, blend_mode = RenderBatch.BlendMode.Additive)
        for node in DepthFirstIterator(self._scene.getRoot()):
            if type(node) is SceneNode and node.getMeshData() and node.isVisible():
                batch.addItem(node.getWorldTransformation(), node.getMeshData())

        self.bind()

        self._gl.glDisable(self._gl.GL_DEPTH_TEST)
        batch.render(self._scene.getActiveCamera())
        self._gl.glEnable(self._gl.GL_DEPTH_TEST)

        self.release()
Example #31
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._xray_shader:
            self._xray_shader = OpenGL.getInstance().createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath("XRayView"),
                    "xray.shader"))
            self._xray_shader.setUniformValue("u_color", [0.1, 0.1, 0.2, 1.0])

        for node in BreadthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    renderer.queueNode(
                        node,
                        shader=self._xray_shader,
                        type=RenderBatch.RenderType.Solid,
                        blend_mode=RenderBatch.BlendMode.Additive,
                        sort=-10,
                        state_setup_callback=lambda gl: gl.glDepthFunc(
                            gl.GL_ALWAYS),
                        state_teardown_callback=lambda gl: gl.glDepthFunc(
                            gl.GL_LESS))
Example #32
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._ghost_shader:
            self._ghost_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "color.shader"))
            self._ghost_shader.setUniformValue(
                "u_color",
                Color(*Application.getInstance().getTheme().getColor(
                    "layerview_ghost").getRgb()))

        for node in DepthFirstIterator(scene.getRoot()):
            # We do not want to render ConvexHullNode as it conflicts with the bottom layers.
            # However, it is somewhat relevant when the node is selected, so do render it then.
            if type(node) is ConvexHullNode and not Selection.isSelected(
                    node.getWatchedNode()):
                continue

            if not node.render(renderer):
                if (node.getMeshData()) and node.isVisible():
                    renderer.queueNode(node,
                                       transparent=True,
                                       shader=self._ghost_shader)
Example #33
0
    def render(self, renderer):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders,
                                  "transparent_object.shader"))
            self._shader.setUniformValue("u_diffuseColor", self._color)
            self._shader.setUniformValue("u_opacity", 0.6)

        if self.getParent():
            if self.getMeshData():
                renderer.queueNode(self,
                                   transparent=True,
                                   shader=self._shader,
                                   backface_cull=True,
                                   sort=-8)
                if self._convex_hull_head_mesh:
                    renderer.queueNode(self,
                                       shader=self._shader,
                                       transparent=True,
                                       mesh=self._convex_hull_head_mesh,
                                       backface_cull=True,
                                       sort=-8)

        return True
Example #34
0
    def render(self) -> None:
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "overhang.shader"))
            self._shader.setUniformValue("u_overhangAngle", 1.0)
            self._shader.setUniformValue("u_ambientColor",
                                         [0.1, 0.1, 0.1, 1.0])
            self._shader.setUniformValue("u_specularColor",
                                         [0.6, 0.6, 0.6, 1.0])
            self._shader.setUniformValue("u_shininess", 20.0)

        self._gl.glClearColor(0.0, 0.0, 0.0, 0.0)
        self._gl.glClear(self._gl.GL_COLOR_BUFFER_BIT
                         | self._gl.GL_DEPTH_BUFFER_BIT)

        # Create a new batch to be rendered
        batch = RenderBatch(self._shader)

        # Fill up the batch with objects that can be sliced. `
        for node in DepthFirstIterator(self._scene.getRoot()):
            if node.callDecoration(
                    "isSliceable") and node.getMeshData() and node.isVisible():
                uniforms = {}
                uniforms["diffuse_color"] = prettier_color(
                    node.getDiffuseColor())
                batch.addItem(node.getWorldTransformation(),
                              node.getMeshData(),
                              uniforms=uniforms)

        self.bind()
        if self._camera is None:
            batch.render(Application.getInstance().getController().getScene().
                         getActiveCamera())
        else:
            batch.render(self._camera)
        self.release()
Example #35
0
    def render(self):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath("XRayView"),
                    "xray.shader"))

        batch = RenderBatch(self._shader,
                            type=RenderBatch.RenderType.NoType,
                            backface_cull=False,
                            blend_mode=RenderBatch.BlendMode.Additive)
        for node in DepthFirstIterator(self._scene.getRoot()):
            if isinstance(node, SteSlicerSceneNode) and node.getMeshData(
            ) and node.isVisible():
                batch.addItem(node.getWorldTransformation(),
                              node.getMeshData())

        self.bind()

        self._gl.glDisable(self._gl.GL_DEPTH_TEST)
        batch.render(self._scene.getActiveCamera())
        self._gl.glEnable(self._gl.GL_DEPTH_TEST)

        self.release()
Example #36
0
    def render(self, renderer):
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        if self._auto_scale:
            camera_position = self._scene.getActiveCamera().getWorldPosition()
            dist = (camera_position - self.getWorldPosition()).length()
            scale = dist / 400
            self.setScale(Vector(scale, scale, scale))

        if self._line_mesh:
            renderer.queueNode(self,
                               mesh=self._line_mesh,
                               mode=RenderBatch.RenderMode.Lines,
                               overlay=True,
                               shader=self._shader)
        if self._solid_mesh:
            renderer.queueNode(self,
                               mesh=self._solid_mesh,
                               overlay=True,
                               shader=self._shader)

        return True
Example #37
0
    def _getOpenGLInfo(self):
        info = "<ul>"
        info += catalog.i18nc(
            "@label OpenGL version",
            "<li>OpenGL Version: {version}</li>").format(
                version=OpenGL.getInstance().getOpenGLVersion())
        info += catalog.i18nc(
            "@label OpenGL vendor", "<li>OpenGL Vendor: {vendor}</li>").format(
                vendor=OpenGL.getInstance().getGPUVendorName())
        info += catalog.i18nc("@label OpenGL renderer",
                              "<li>OpenGL Renderer: {renderer}</li>").format(
                                  renderer=OpenGL.getInstance().getGPUType())
        info += "</ul>"

        self.data["opengl"] = {
            "version": OpenGL.getInstance().getOpenGLVersion(),
            "vendor": OpenGL.getInstance().getGPUVendorName(),
            "type": OpenGL.getInstance().getGPUType()
        }

        return info
Example #38
0
 def getSelectFaceSupported(self):
     return OpenGL.getInstance().getOpenGLShadingLanguageVersion() >= Version("1.50")
Example #39
0
    def _updateRenderStorage(self):
        if self._width <= 0 or self._height <= 0:
            Logger.log("w", "Tried to create render pass with size <= 0")
            return

        self._fbo = OpenGL.getInstance().createFrameBufferObject(self._width, self._height)
Example #40
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._enabled_shader:
            self._enabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "overhang.shader"))
            theme = Application.getInstance().getTheme()
            self._enabled_shader.setUniformValue(
                "u_overhangColor",
                Color(*theme.getColor("model_overhang").getRgb()))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            theme = Application.getInstance().getTheme()
            self._disabled_shader.setUniformValue(
                "u_diffuseColor1",
                Color(*theme.getColor("model_unslicable").getRgb()))
            self._disabled_shader.setUniformValue(
                "u_diffuseColor2",
                Color(*theme.getColor("model_unslicable_alt").getRgb()))
            self._disabled_shader.setUniformValue("u_width", 50.0)

        multi_extrusion = False

        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if global_container_stack:
            multi_extrusion = global_container_stack.getProperty(
                "machine_extruder_count", "value") > 1

            if multi_extrusion:
                support_extruder_nr = global_container_stack.getProperty(
                    "support_extruder_nr", "value")
                support_angle_stack = ExtruderManager.getInstance(
                ).getExtruderStack(support_extruder_nr)
                if not support_angle_stack:
                    support_angle_stack = global_container_stack
            else:
                support_angle_stack = global_container_stack

            if Preferences.getInstance().getValue("view/show_overhang"):
                angle = support_angle_stack.getProperty(
                    "support_angle", "value")
                # Make sure the overhang angle is valid before passing it to the shader
                # Note: if the overhang angle is set to its default value, it does not need to get validated (validationState = None)
                if angle is not None and global_container_stack.getProperty(
                        "support_angle",
                        "validationState") in [None, ValidatorState.Valid]:
                    self._enabled_shader.setUniformValue(
                        "u_overhangAngle", math.cos(math.radians(90 - angle)))
                else:
                    self._enabled_shader.setUniformValue(
                        "u_overhangAngle", math.cos(math.radians(0))
                    )  #Overhang angle of 0 causes no area at all to be marked as overhang.
            else:
                self._enabled_shader.setUniformValue("u_overhangAngle",
                                                     math.cos(math.radians(0)))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    uniforms = {}
                    shade_factor = 1.0

                    if not multi_extrusion:
                        if global_container_stack:
                            material = global_container_stack.findContainer(
                                {"type": "material"})
                            material_color = material.getMetaDataEntry(
                                "color_code",
                                default=self._extruders_model.defaultColors[0]
                            ) if material else self._extruders_model.defaultColors[
                                0]
                        else:
                            material_color = self._extruders_model.defaultColors[
                                0]
                    else:
                        # Get color to render this mesh in from ExtrudersModel
                        extruder_index = 0
                        extruder_id = node.callDecoration("getActiveExtruder")
                        if extruder_id:
                            extruder_index = max(
                                0,
                                self._extruders_model.find("id", extruder_id))
                        try:
                            material_color = self._extruders_model.getItem(
                                extruder_index)["color"]
                        except KeyError:
                            material_color = self._extruders_model.defaultColors[
                                0]

                        if extruder_index != ExtruderManager.getInstance(
                        ).activeExtruderIndex:
                            # Shade objects that are printed with the non-active extruder 25% darker
                            shade_factor = 0.6
                    try:
                        # Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
                        # an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
                        uniforms["diffuse_color"] = [
                            shade_factor * int(material_color[1:3], 16) / 255,
                            shade_factor * int(material_color[3:5], 16) / 255,
                            shade_factor * int(material_color[5:7], 16) / 255,
                            1.0
                        ]
                    except ValueError:
                        pass

                    if hasattr(node, "_outside_buildarea"):
                        if node._outside_buildarea:
                            renderer.queueNode(node,
                                               shader=self._disabled_shader)
                        else:
                            renderer.queueNode(node,
                                               shader=self._enabled_shader,
                                               uniforms=uniforms)
                    else:
                        renderer.queueNode(node,
                                           material=self._enabled_shader,
                                           uniforms=uniforms)
                if node.callDecoration("isGroup") and Selection.isSelected(
                        node):
                    renderer.queueNode(scene.getRoot(),
                                       mesh=node.getBoundingBoxMesh(),
                                       mode=Renderer.RenderLines)
Example #41
0
    def render(self) -> None:
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "overhang.shader"))
            if self._shader:
                self._shader.setUniformValue("u_overhangAngle", 1.0)
                self._shader.setUniformValue("u_ambientColor",
                                             [0.1, 0.1, 0.1, 1.0])
                self._shader.setUniformValue("u_specularColor",
                                             [0.6, 0.6, 0.6, 1.0])
                self._shader.setUniformValue("u_shininess", 20.0)

        if not self._non_printing_shader:
            if self._non_printing_shader:
                self._non_printing_shader = OpenGL.getInstance(
                ).createShaderProgram(
                    Resources.getPath(Resources.Shaders,
                                      "transparent_object.shader"))
                self._non_printing_shader.setUniformValue(
                    "u_diffuseColor", [0.5, 0.5, 0.5, 0.5])
                self._non_printing_shader.setUniformValue("u_opacity", 0.6)

        if not self._support_mesh_shader:
            self._support_mesh_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            if self._support_mesh_shader:
                self._support_mesh_shader.setUniformValue(
                    "u_vertical_stripes", True)
                self._support_mesh_shader.setUniformValue("u_width", 5.0)

        self._gl.glClearColor(0.0, 0.0, 0.0, 0.0)
        self._gl.glClear(self._gl.GL_COLOR_BUFFER_BIT
                         | self._gl.GL_DEPTH_BUFFER_BIT)

        # Create batches to be rendered
        batch = RenderBatch(self._shader)
        batch_support_mesh = RenderBatch(self._support_mesh_shader)

        # Fill up the batch with objects that can be sliced.
        for node in DepthFirstIterator(
                self._scene.getRoot()
        ):  #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
            if node.callDecoration(
                    "isSliceable") and node.getMeshData() and node.isVisible():
                per_mesh_stack = node.callDecoration("getStack")
                if node.callDecoration("isNonThumbnailVisibleMesh"):
                    # Non printing mesh
                    continue
                elif per_mesh_stack is not None and per_mesh_stack.getProperty(
                        "support_mesh", "value"):
                    # Support mesh
                    uniforms = {}
                    shade_factor = 0.6
                    diffuse_color = node.getDiffuseColor()
                    diffuse_color2 = [
                        diffuse_color[0] * shade_factor,
                        diffuse_color[1] * shade_factor,
                        diffuse_color[2] * shade_factor, 1.0
                    ]
                    uniforms["diffuse_color"] = prettier_color(diffuse_color)
                    uniforms["diffuse_color_2"] = diffuse_color2
                    batch_support_mesh.addItem(node.getWorldTransformation(),
                                               node.getMeshData(),
                                               uniforms=uniforms)
                else:
                    # Normal scene node
                    uniforms = {}
                    uniforms["diffuse_color"] = prettier_color(
                        node.getDiffuseColor())
                    batch.addItem(node.getWorldTransformation(),
                                  node.getMeshData(),
                                  uniforms=uniforms)

        self.bind()

        if self._camera is None:
            render_camera = Application.getInstance().getController().getScene(
            ).getActiveCamera()
        else:
            render_camera = self._camera

        batch.render(render_camera)
        batch_support_mesh.render(render_camera)

        self.release()
Example #42
0
    def render(self):
        if not self._layer_shader:
            if self._compatibility_mode:
                shader_filename = "layers.shader"
            else:
                shader_filename = "layers3d.shader"
            self._layer_shader = OpenGL.getInstance().createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath("LayerView"),
                    shader_filename))
        # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
        self._layer_shader.setUniformValue(
            "u_active_extruder",
            float(max(0, self._extruder_manager.activeExtruderIndex)))
        if self._layer_view:
            self._layer_shader.setUniformValue(
                "u_layer_view_type", self._layer_view.getLayerViewType())
            self._layer_shader.setUniformValue(
                "u_extruder_opacity", self._layer_view.getExtruderOpacities())
            self._layer_shader.setUniformValue(
                "u_show_travel_moves", self._layer_view.getShowTravelMoves())
            self._layer_shader.setUniformValue(
                "u_show_helpers", self._layer_view.getShowHelpers())
            self._layer_shader.setUniformValue("u_show_skin",
                                               self._layer_view.getShowSkin())
            self._layer_shader.setUniformValue(
                "u_show_infill", self._layer_view.getShowInfill())
        else:
            #defaults
            self._layer_shader.setUniformValue("u_layer_view_type", 1)
            self._layer_shader.setUniformValue("u_extruder_opacity",
                                               [1, 1, 1, 1])
            self._layer_shader.setUniformValue("u_show_travel_moves", 0)
            self._layer_shader.setUniformValue("u_show_helpers", 1)
            self._layer_shader.setUniformValue("u_show_skin", 1)
            self._layer_shader.setUniformValue("u_show_infill", 1)

        if not self._tool_handle_shader:
            self._tool_handle_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        self.bind()

        tool_handle_batch = RenderBatch(self._tool_handle_shader,
                                        type=RenderBatch.RenderType.Overlay)

        for node in DepthFirstIterator(self._scene.getRoot()):

            if isinstance(node, ToolHandle):
                tool_handle_batch.addItem(node.getWorldTransformation(),
                                          mesh=node.getSolidMesh())

            elif isinstance(node, SceneNode) and (node.getMeshData(
            ) or node.callDecoration("isBlockSlicing")) and node.isVisible():
                layer_data = node.callDecoration("getLayerData")
                if not layer_data:
                    continue

                # Render all layers below a certain number as line mesh instead of vertices.
                if self._layer_view._current_layer_num > -1 and (
                    (not self._layer_view._only_show_top_layers) or
                    (not self._layer_view.getCompatibilityMode())):
                    start = 0
                    end = 0
                    element_counts = layer_data.getElementCounts()
                    for layer in sorted(element_counts.keys()):
                        if layer > self._layer_view._current_layer_num:
                            break
                        if self._layer_view._minimum_layer_num > layer:
                            start += element_counts[layer]
                        end += element_counts[layer]

                    # This uses glDrawRangeElements internally to only draw a certain range of lines.
                    batch = RenderBatch(self._layer_shader,
                                        type=RenderBatch.RenderType.Solid,
                                        mode=RenderBatch.RenderMode.Lines,
                                        range=(start, end))
                    batch.addItem(node.getWorldTransformation(), layer_data)
                    batch.render(self._scene.getActiveCamera())

                # Create a new batch that is not range-limited
                batch = RenderBatch(self._layer_shader,
                                    type=RenderBatch.RenderType.Solid)

                if self._layer_view.getCurrentLayerMesh():
                    batch.addItem(node.getWorldTransformation(),
                                  self._layer_view.getCurrentLayerMesh())

                if self._layer_view.getCurrentLayerJumps():
                    batch.addItem(node.getWorldTransformation(),
                                  self._layer_view.getCurrentLayerJumps())

                if len(batch.items) > 0:
                    batch.render(self._scene.getActiveCamera())

        # Render toolhandles on top of the layerview
        if len(tool_handle_batch.items) > 0:
            tool_handle_batch.render(self._scene.getActiveCamera())

        self.release()
Example #43
0
    def event(self, event):
        if event.type == Event.ViewActivateEvent:
            # FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching.
            # This can happen when you do the following steps:
            #   1. Start Cura
            #   2. Load a model
            #   3. Switch to Custom mode
            #   4. Select the model and click on the per-object tool icon
            #   5. Switch view to Layer view or X-Ray
            #   6. Cura will very likely crash
            # It seems to be a timing issue that the currentContext can somehow be empty, but I have no clue why.
            # This fix tries to reschedule the view changing event call on the Qt thread again if the current OpenGL
            # context is None.
            if Platform.isOSX():
                if QOpenGLContext.currentContext() is None:
                    Logger.log(
                        "d",
                        "current context of OpenGL is empty on Mac OS X, will try to create shaders later"
                    )
                    CuraApplication.getInstance().callLater(
                        lambda e=event: self.event(e))
                    return

            if not self._xray_pass:
                # Currently the RenderPass constructor requires a size > 0
                # This should be fixed in RenderPass's constructor.
                self._xray_pass = XRayPass.XRayPass(1, 1)

            self.getRenderer().addRenderPass(self._xray_pass)

            if not self._xray_composite_shader:
                self._xray_composite_shader = OpenGL.getInstance(
                ).createShaderProgram(
                    os.path.join(
                        PluginRegistry.getInstance().getPluginPath("XRayView"),
                        "xray_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._xray_composite_shader.setUniformValue(
                    "u_background_color",
                    Color(*theme.getColor("viewport_background").getRgb()))
                self._xray_composite_shader.setUniformValue(
                    "u_error_color",
                    Color(*theme.getColor("xray_error").getRgb()))
                self._xray_composite_shader.setUniformValue(
                    "u_outline_color",
                    Color(*theme.getColor("model_selection_outline").getRgb()))

            if not self._composite_pass:
                self._composite_pass = self.getRenderer().getRenderPass(
                    "composite")

            self._old_layer_bindings = self._composite_pass.getLayerBindings()
            self._composite_pass.setLayerBindings(
                ["default", "selection", "xray"])
            self._old_composite_shader = self._composite_pass.getCompositeShader(
            )
            self._composite_pass.setCompositeShader(
                self._xray_composite_shader)

        if event.type == Event.ViewDeactivateEvent:
            self.getRenderer().removeRenderPass(self._xray_pass)
            self._composite_pass.setLayerBindings(self._old_layer_bindings)
            self._composite_pass.setCompositeShader(self._old_composite_shader)
Example #44
0
    def render(self):
        if not self._layer_shader:
            if self._compatibility_mode:
                shader_filename = "layers.shader"
                shadow_shader_filename = "layers_shadow.shader"
            else:
                shader_filename = "layers3d.shader"
                shadow_shader_filename = "layers3d_shadow.shader"
            self._layer_shader = OpenGL.getInstance().createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath(
                        "SimulationView"), shader_filename))
            self._layer_shadow_shader = OpenGL.getInstance(
            ).createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath(
                        "SimulationView"), shadow_shader_filename))
            self._current_shader = self._layer_shader

        self._updateLayerShaderValues()

        if not self._tool_handle_shader:
            self._tool_handle_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        if not self._nozzle_shader:
            self._nozzle_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "color.shader"))
            self._nozzle_shader.setUniformValue(
                "u_color",
                Color(*Application.getInstance().getTheme().getColor(
                    "layerview_nozzle").getRgb()))

        self.bind()

        tool_handle_batch = RenderBatch(self._tool_handle_shader,
                                        type=RenderBatch.RenderType.Overlay,
                                        backface_cull=True)
        head_position = None  # Indicates the current position of the print head
        nozzle_node = None

        for node in DepthFirstIterator(self._scene.getRoot()):
            if isinstance(node, ToolHandle):
                tool_handle_batch.addItem(node.getWorldTransformation(),
                                          mesh=node.getSolidMesh())

            elif isinstance(node, NozzleNode):
                nozzle_node = node
                nozzle_node.setVisible(False)

            elif isinstance(node, SceneNode) and (node.getMeshData(
            ) or node.callDecoration("isBlockSlicing")) and node.isVisible():
                layer_data = node.callDecoration("getLayerData")
                if not layer_data:
                    continue

                # Render all layers below a certain number as line mesh instead of vertices.
                if self._layer_view._current_layer_num > -1 and (
                    (not self._layer_view._only_show_top_layers) or
                    (not self._layer_view.getCompatibilityMode())):
                    start = self._layer_view.start_elements_index
                    end = self._layer_view.end_elements_index
                    index = self._layer_view._current_path_num
                    offset = 0
                    for polygon in layer_data.getLayer(
                            self._layer_view._current_layer_num).polygons:
                        # The size indicates all values in the two-dimension array, and the second dimension is
                        # always size 3 because we have 3D points.
                        if index >= polygon.data.size // 3 - offset:
                            index -= polygon.data.size // 3 - offset
                            offset = 1  # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon
                            continue
                        # The head position is calculated and translated
                        head_position = Vector(
                            polygon.data[index + offset][0],
                            polygon.data[index + offset][1],
                            polygon.data[index +
                                         offset][2]) + node.getWorldPosition()
                        break

                    # Calculate the range of paths in the last layer
                    current_layer_start = end
                    current_layer_end = end + self._layer_view._current_path_num * 2  # Because each point is used twice

                    # This uses glDrawRangeElements internally to only draw a certain range of lines.
                    # All the layers but the current selected layer are rendered first
                    if self._old_current_path != self._layer_view._current_path_num:
                        self._current_shader = self._layer_shadow_shader
                        self._switching_layers = False
                    if not self._layer_view.isSimulationRunning(
                    ) and self._old_current_layer != self._layer_view._current_layer_num:
                        self._current_shader = self._layer_shader
                        self._switching_layers = True

                    layers_batch = RenderBatch(
                        self._current_shader,
                        type=RenderBatch.RenderType.Solid,
                        mode=RenderBatch.RenderMode.Lines,
                        range=(start, end),
                        backface_cull=True)
                    layers_batch.addItem(node.getWorldTransformation(),
                                         layer_data)
                    layers_batch.render(self._scene.getActiveCamera())

                    # Current selected layer is rendered
                    current_layer_batch = RenderBatch(
                        self._layer_shader,
                        type=RenderBatch.RenderType.Solid,
                        mode=RenderBatch.RenderMode.Lines,
                        range=(current_layer_start, current_layer_end))
                    current_layer_batch.addItem(node.getWorldTransformation(),
                                                layer_data)
                    current_layer_batch.render(self._scene.getActiveCamera())

                    self._old_current_layer = self._layer_view._current_layer_num
                    self._old_current_path = self._layer_view._current_path_num

                # Create a new batch that is not range-limited
                batch = RenderBatch(self._layer_shader,
                                    type=RenderBatch.RenderType.Solid)

                if self._layer_view.getCurrentLayerMesh():
                    batch.addItem(node.getWorldTransformation(),
                                  self._layer_view.getCurrentLayerMesh())

                if self._layer_view.getCurrentLayerJumps():
                    batch.addItem(node.getWorldTransformation(),
                                  self._layer_view.getCurrentLayerJumps())

                if len(batch.items) > 0:
                    batch.render(self._scene.getActiveCamera())

        # The nozzle is drawn when once we know the correct position of the head,
        # but the user is not using the layer slider, and the compatibility mode is not enabled
        if not self._switching_layers and not self._compatibility_mode and self._layer_view.getActivity(
        ) and nozzle_node is not None:
            if head_position is not None:
                nozzle_node.setVisible(True)
                nozzle_node.setPosition(head_position)
                nozzle_batch = RenderBatch(
                    self._nozzle_shader,
                    type=RenderBatch.RenderType.Transparent)
                nozzle_batch.addItem(nozzle_node.getWorldTransformation(),
                                     mesh=nozzle_node.getMeshData())
                nozzle_batch.render(self._scene.getActiveCamera())

        # Render toolhandles on top of the layerview
        if len(tool_handle_batch.items) > 0:
            tool_handle_batch.render(self._scene.getActiveCamera())

        self.release()
Example #45
0
    def render(self) -> None:
        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "overhang.shader"))
            if self._shader:
                self._shader.setUniformValue("u_overhangAngle", 1.0)
                self._shader.setUniformValue("u_ambientColor",
                                             [0.1, 0.1, 0.1, 1.0])
                self._shader.setUniformValue("u_specularColor",
                                             [0.6, 0.6, 0.6, 1.0])
                self._shader.setUniformValue("u_shininess", 20.0)
                self._shader.setUniformValue(
                    "u_renderError", 0.0)  # We don't want any error markers!.
                self._shader.setUniformValue(
                    "u_faceId",
                    -1)  # Don't render any selected faces in the preview.
            else:
                Logger.error(
                    "Unable to compile shader program: overhang.shader")

        if not self._non_printing_shader:
            if self._non_printing_shader:
                self._non_printing_shader = OpenGL.getInstance(
                ).createShaderProgram(
                    Resources.getPath(Resources.Shaders,
                                      "transparent_object.shader"))
                self._non_printing_shader.setUniformValue(
                    "u_diffuseColor", [0.5, 0.5, 0.5, 0.5])
                self._non_printing_shader.setUniformValue("u_opacity", 0.6)

        if not self._support_mesh_shader:
            self._support_mesh_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            if self._support_mesh_shader:
                self._support_mesh_shader.setUniformValue(
                    "u_vertical_stripes", True)
                self._support_mesh_shader.setUniformValue("u_width", 5.0)

        self._gl.glClearColor(0.0, 0.0, 0.0, 0.0)
        self._gl.glClear(self._gl.GL_COLOR_BUFFER_BIT
                         | self._gl.GL_DEPTH_BUFFER_BIT)

        # Create batches to be rendered
        batch = RenderBatch(self._shader)
        batch_support_mesh = RenderBatch(self._support_mesh_shader)

        # Fill up the batch with objects that can be sliced.
        for node in DepthFirstIterator(self._scene.getRoot()):
            if hasattr(node, "_outside_buildarea") and not getattr(
                    node, "_outside_buildarea"):
                if node.callDecoration("isSliceable") and node.getMeshData(
                ) and node.isVisible():
                    per_mesh_stack = node.callDecoration("getStack")
                    if node.callDecoration("isNonThumbnailVisibleMesh"):
                        # Non printing mesh
                        continue
                    elif per_mesh_stack is not None and per_mesh_stack.getProperty(
                            "support_mesh", "value"):
                        # Support mesh
                        uniforms = {}
                        shade_factor = 0.6
                        diffuse_color = cast(CuraSceneNode,
                                             node).getDiffuseColor()
                        diffuse_color2 = [
                            diffuse_color[0] * shade_factor,
                            diffuse_color[1] * shade_factor,
                            diffuse_color[2] * shade_factor, 1.0
                        ]
                        uniforms["diffuse_color"] = prettier_color(
                            diffuse_color)
                        uniforms["diffuse_color_2"] = diffuse_color2
                        batch_support_mesh.addItem(
                            node.getWorldTransformation(copy=False),
                            node.getMeshData(),
                            uniforms=uniforms)
                    else:
                        # Normal scene node
                        uniforms = {}
                        uniforms["diffuse_color"] = prettier_color(
                            cast(CuraSceneNode, node).getDiffuseColor())
                        batch.addItem(node.getWorldTransformation(copy=False),
                                      node.getMeshData(),
                                      uniforms=uniforms)

        self.bind()

        if self._camera is None:
            render_camera = Application.getInstance().getController().getScene(
            ).getActiveCamera()
        else:
            render_camera = self._camera

        batch.render(render_camera)
        batch_support_mesh.render(render_camera)

        self.release()
Example #46
0
    def event(self, event):
        modifiers = QApplication.keyboardModifiers()
        ctrl_is_active = modifiers == Qt.ControlModifier
        if event.type == Event.KeyPressEvent and ctrl_is_active:
            if event.key == KeyEvent.UpKey:
                self.setLayer(self._current_layer_num + 1)
                return True
            if event.key == KeyEvent.DownKey:
                self.setLayer(self._current_layer_num - 1)
                return True

        if event.type == Event.ViewActivateEvent:
            # Make sure the LayerPass is created
            self.getLayerPass()

            Application.getInstance().globalContainerStackChanged.connect(
                self._onGlobalStackChanged)
            self._onGlobalStackChanged()

            if not self._layerview_composite_shader:
                self._layerview_composite_shader = OpenGL.getInstance(
                ).createShaderProgram(
                    os.path.join(
                        PluginRegistry.getInstance().getPluginPath(
                            "LayerView"), "layerview_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._layerview_composite_shader.setUniformValue(
                    "u_background_color",
                    Color(*theme.getColor("viewport_background").getRgb()))
                self._layerview_composite_shader.setUniformValue(
                    "u_outline_color",
                    Color(*theme.getColor("model_selection_outline").getRgb()))

            if not self._composite_pass:
                self._composite_pass = self.getRenderer().getRenderPass(
                    "composite")

            self._old_layer_bindings = self._composite_pass.getLayerBindings(
            )[:]  # make a copy so we can restore to it later
            self._composite_pass.getLayerBindings().append("layerview")
            self._old_composite_shader = self._composite_pass.getCompositeShader(
            )
            self._composite_pass.setCompositeShader(
                self._layerview_composite_shader)

            if self.getLayerViewType(
            ) == self.LAYER_VIEW_TYPE_LINE_TYPE or self._compatibility_mode:
                self.enableLegend()

        elif event.type == Event.ViewDeactivateEvent:
            self._wireprint_warning_message.hide()
            Application.getInstance().globalContainerStackChanged.disconnect(
                self._onGlobalStackChanged)
            if self._global_container_stack:
                self._global_container_stack.propertyChanged.disconnect(
                    self._onPropertyChanged)

            self._composite_pass.setLayerBindings(self._old_layer_bindings)
            self._composite_pass.setCompositeShader(self._old_composite_shader)

            self.disableLegend()
Example #47
0
    def event(self, event):
        modifiers = QApplication.keyboardModifiers()
        ctrl_is_active = modifiers & Qt.ControlModifier
        shift_is_active = modifiers & Qt.ShiftModifier
        if event.type == Event.KeyPressEvent and ctrl_is_active:
            amount = 10 if shift_is_active else 1
            if event.key == KeyEvent.UpKey:
                self.setLayer(self._current_layer_num + amount)
                return True
            if event.key == KeyEvent.DownKey:
                self.setLayer(self._current_layer_num - amount)
                return True

        if event.type == Event.ViewActivateEvent:
            # FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching.
            # This can happen when you do the following steps:
            #   1. Start Cura
            #   2. Load a model
            #   3. Switch to Custom mode
            #   4. Select the model and click on the per-object tool icon
            #   5. Switch view to Layer view or X-Ray
            #   6. Cura will very likely crash
            # It seems to be a timing issue that the currentContext can somehow be empty, but I have no clue why.
            # This fix tries to reschedule the view changing event call on the Qt thread again if the current OpenGL
            # context is None.
            if Platform.isOSX():
                if QOpenGLContext.currentContext() is None:
                    Logger.log("d", "current context of OpenGL is empty on Mac OS X, will try to create shaders later")
                    CuraApplication.getInstance().callLater(lambda e=event: self.event(e))
                    return

            # Make sure the SimulationPass is created
            layer_pass = self.getSimulationPass()
            self.getRenderer().addRenderPass(layer_pass)

            # Make sure the NozzleNode is add to the root
            nozzle = self.getNozzleNode()
            nozzle.setParent(self.getController().getScene().getRoot())
            nozzle.setVisible(False)

            Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
            self._onGlobalStackChanged()

            if not self._simulationview_composite_shader:
                self._simulationview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), "simulationview_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._simulationview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
                self._simulationview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))

            if not self._composite_pass:
                self._composite_pass = self.getRenderer().getRenderPass("composite")

            self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later
            self._composite_pass.getLayerBindings().append("simulationview")
            self._old_composite_shader = self._composite_pass.getCompositeShader()
            self._composite_pass.setCompositeShader(self._simulationview_composite_shader)

        elif event.type == Event.ViewDeactivateEvent:
            self._wireprint_warning_message.hide()
            Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged)
            if self._global_container_stack:
                self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)

            self._nozzle_node.setParent(None)
            self.getRenderer().removeRenderPass(self._layer_pass)
            self._composite_pass.setLayerBindings(self._old_layer_bindings)
            self._composite_pass.setCompositeShader(self._old_composite_shader)
Example #48
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._enabled_shader:
            self._enabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "overhang.shader"))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            self._disabled_shader.setUniformValue("u_diffuseColor1",
                                                  [0.48, 0.48, 0.48, 1.0])
            self._disabled_shader.setUniformValue("u_diffuseColor2",
                                                  [0.68, 0.68, 0.68, 1.0])
            self._disabled_shader.setUniformValue("u_width", 50.0)

        if Application.getInstance().getGlobalContainerStack():
            if Preferences.getInstance().getValue("view/show_overhang"):
                angle = Application.getInstance().getGlobalContainerStack(
                ).getProperty("support_angle", "value")
                if angle is not None:
                    self._enabled_shader.setUniformValue(
                        "u_overhangAngle", math.cos(math.radians(90 - angle)))
                else:
                    self._enabled_shader.setUniformValue(
                        "u_overhangAngle", math.cos(math.radians(0))
                    )  #Overhang angle of 0 causes no area at all to be marked as overhang.
            else:
                self._enabled_shader.setUniformValue("u_overhangAngle",
                                                     math.cos(math.radians(0)))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible():
                    # TODO: Find a better way to handle this
                    #if node.getBoundingBoxMesh():
                    #    renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines)

                    uniforms = {}
                    if self._extruders_model.rowCount() == 0:
                        material = Application.getInstance(
                        ).getGlobalContainerStack().findContainer(
                            {"type": "material"})
                        material_color = material.getMetaDataEntry(
                            "color_code",
                            default=self._extruders_model.defaultColours[0]
                        ) if material else self._extruders_model.defaultColours[
                            0]
                    else:
                        # Get color to render this mesh in from ExtrudersModel
                        extruder_index = 0
                        extruder_id = node.callDecoration("getActiveExtruder")
                        if extruder_id:
                            extruder_index = max(
                                0,
                                self._extruders_model.find("id", extruder_id))

                        material_color = self._extruders_model.getItem(
                            extruder_index)["colour"]
                    try:
                        # Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
                        # an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
                        uniforms["diffuse_color"] = [
                            int(material_color[1:3], 16) / 255,
                            int(material_color[3:5], 16) / 255,
                            int(material_color[5:7], 16) / 255, 1.0
                        ]
                    except ValueError:
                        pass

                    if hasattr(node, "_outside_buildarea"):
                        if node._outside_buildarea:
                            renderer.queueNode(node,
                                               shader=self._disabled_shader)
                        else:
                            renderer.queueNode(node,
                                               shader=self._enabled_shader,
                                               uniforms=uniforms)
                    else:
                        renderer.queueNode(node,
                                           material=self._enabled_shader,
                                           uniforms=uniforms)
                if node.callDecoration("isGroup") and Selection.isSelected(
                        node):
                    renderer.queueNode(scene.getRoot(),
                                       mesh=node.getBoundingBoxMesh(),
                                       mode=Renderer.RenderLines)
Example #49
0
    def render(self):
        if not self._layer_shader:
            if self._compatibility_mode:
                shader_filename = "layers.shader"
                shadow_shader_filename = "layers_shadow.shader"
            else:
                shader_filename = "layers3d.shader"
                shadow_shader_filename = "layers3d_shadow.shader"
            self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), shader_filename))
            self._layer_shadow_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), shadow_shader_filename))
            self._current_shader = self._layer_shader
        # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
        self._layer_shader.setUniformValue("u_active_extruder", float(max(0, self._extruder_manager.activeExtruderIndex)))
        if self._layer_view:
            self._layer_shader.setUniformValue("u_max_feedrate", self._layer_view.getMaxFeedrate())
            self._layer_shader.setUniformValue("u_min_feedrate", self._layer_view.getMinFeedrate())
            self._layer_shader.setUniformValue("u_max_thickness", self._layer_view.getMaxThickness())
            self._layer_shader.setUniformValue("u_min_thickness", self._layer_view.getMinThickness())
            self._layer_shader.setUniformValue("u_layer_view_type", self._layer_view.getSimulationViewType())
            self._layer_shader.setUniformValue("u_extruder_opacity", self._layer_view.getExtruderOpacities())
            self._layer_shader.setUniformValue("u_show_travel_moves", self._layer_view.getShowTravelMoves())
            self._layer_shader.setUniformValue("u_show_helpers", self._layer_view.getShowHelpers())
            self._layer_shader.setUniformValue("u_show_skin", self._layer_view.getShowSkin())
            self._layer_shader.setUniformValue("u_show_infill", self._layer_view.getShowInfill())
        else:
            #defaults
            self._layer_shader.setUniformValue("u_max_feedrate", 1)
            self._layer_shader.setUniformValue("u_min_feedrate", 0)
            self._layer_shader.setUniformValue("u_max_thickness", 1)
            self._layer_shader.setUniformValue("u_min_thickness", 0)
            self._layer_shader.setUniformValue("u_layer_view_type", 1)
            self._layer_shader.setUniformValue("u_extruder_opacity", [1, 1, 1, 1])
            self._layer_shader.setUniformValue("u_show_travel_moves", 0)
            self._layer_shader.setUniformValue("u_show_helpers", 1)
            self._layer_shader.setUniformValue("u_show_skin", 1)
            self._layer_shader.setUniformValue("u_show_infill", 1)

        if not self._tool_handle_shader:
            self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        if not self._nozzle_shader:
            self._nozzle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
            self._nozzle_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_nozzle").getRgb()))

        self.bind()

        tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay, backface_cull = True)
        active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
        head_position = None  # Indicates the current position of the print head
        head_rotation = None#Quaternion(z=1.0)
        nozzle_node = None

        for node in DepthFirstIterator(self._scene.getRoot()):

            if isinstance(node, ToolHandle):
                tool_handle_batch.addItem(node.getWorldTransformation(), mesh = node.getSolidMesh())

            elif isinstance(node, NozzleNode):
                nozzle_node = node
                nozzle_node.setVisible(False)

            elif isinstance(node, SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible():
                layer_data = node.callDecoration("getLayerData")
                if not layer_data:
                    continue

                # Render all layers below a certain number as line mesh instead of vertices.
                if self._layer_view._current_layer_num > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())):
                    start = 0
                    end = 0
                    element_counts = layer_data.getElementCounts()
                    for layer in sorted(element_counts.keys()):
                        # In the current layer, we show just the indicated paths
                        if layer == self._layer_view._current_layer_num:
                            # We look for the position of the head, searching the point of the current path
                            index = self._layer_view._current_path_num
                            offset = 0
                            for polygon in layer_data.getLayer(layer).polygons:
                                # The size indicates all values in the two-dimension array, and the second dimension is
                                # always size 3 because we have 3D points.
                                if index >= polygon.data.size // 6 - offset:
                                    index -= polygon.data.size // 6 - offset
                                    offset = 1  # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon
                                    continue
                                # The head position is calculated and translated
                                head_position = Vector(polygon.data[index+offset][0], polygon.data[index+offset][1], polygon.data[index+offset][2]) + node.getWorldPosition()
                                if len(polygon.data[index+offset]) > 3:
                                    head_rotation = Quaternion.rotationTo(Vector(0,1,0), Vector(polygon.data[index+offset][3], polygon.data[index+offset][4], polygon.data[index+offset][5]))
                                else:
                                    head_rotation = Quaternion(y=-1)
                                break
                            break
                        if self._layer_view._minimum_layer_num > layer:
                            start += element_counts[layer]
                        end += element_counts[layer]

                    # Calculate the range of paths in the last layer
                    current_layer_start = end
                    current_layer_end = end + self._layer_view._current_path_num * 2 # Because each point is used twice

                    # This uses glDrawRangeElements internally to only draw a certain range of lines.
                    # All the layers but the current selected layer are rendered first
                    if self._old_current_path != self._layer_view._current_path_num:
                        self._current_shader = self._layer_shadow_shader
                        self._switching_layers = False
                    if not self._layer_view.isSimulationRunning() and self._old_current_layer != self._layer_view._current_layer_num:
                        self._current_shader = self._layer_shader
                        self._switching_layers = True

                    layers_batch = RenderBatch(self._current_shader, type = RenderBatch.RenderType.Solid, mode = RenderBatch.RenderMode.Lines, range = (start, end), backface_cull = True)
                    layers_batch.addItem(node.getWorldTransformation(), layer_data)
                    layers_batch.render(self._scene.getActiveCamera())

                    # Current selected layer is rendered
                    current_layer_batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid, mode = RenderBatch.RenderMode.Lines, range = (current_layer_start, current_layer_end))
                    current_layer_batch.addItem(node.getWorldTransformation(), layer_data)
                    current_layer_batch.render(self._scene.getActiveCamera())

                    self._old_current_layer = self._layer_view._current_layer_num
                    self._old_current_path = self._layer_view._current_path_num

                # Create a new batch that is not range-limited
                batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid)

                if self._layer_view.getCurrentLayerMesh():
                    batch.addItem(node.getWorldTransformation(), self._layer_view.getCurrentLayerMesh())

                if self._layer_view.getCurrentLayerJumps():
                    batch.addItem(node.getWorldTransformation(), self._layer_view.getCurrentLayerJumps())

                if len(batch.items) > 0:
                    batch.render(self._scene.getActiveCamera())

        # The nozzle is drawn when once we know the correct position of the head,
        # but the user is not using the layer slider, and the compatibility mode is not enabled
        if not self._switching_layers and not self._compatibility_mode and self._layer_view.getActivity() and nozzle_node is not None:
            if head_position is not None:
                nozzle_node.setVisible(True)

                if head_rotation is not None:
                    nozzle_node.setOrientation(head_rotation, SceneNode.TransformSpace.Local)


                nozzle_node.setPosition(head_position)

                
                nozzle_batch = RenderBatch(self._nozzle_shader, type = RenderBatch.RenderType.Transparent)
                nozzle_batch.addItem(nozzle_node.getWorldTransformation(), mesh = nozzle_node.getMeshData())
                nozzle_batch.render(self._scene.getActiveCamera())

        # Render toolhandles on top of the layerview
        if len(tool_handle_batch.items) > 0:
            tool_handle_batch.render(self._scene.getActiveCamera())

        self.release()
Example #50
0
    def render(self):
        if not self._layer_shader:
            if self._compatibility_mode:
                shader_filename = "layers.shader"
                shadow_shader_filename = "layers_shadow.shader"
            else:
                shader_filename = "layers3d.shader"
                shadow_shader_filename = "layers3d_shadow.shader"
            self._layer_shader = OpenGL.getInstance().createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath(
                        "SimulationView"), shader_filename))
            self._layer_shadow_shader = OpenGL.getInstance(
            ).createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath(
                        "SimulationView"), shadow_shader_filename))
            self._current_shader = self._layer_shader
        # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
        self._layer_shader.setUniformValue(
            "u_active_extruder",
            float(max(0, self._extruder_manager.activeExtruderIndex)))
        if not self._compatibility_mode:
            self._layer_shader.setUniformValue(
                "u_starts_color",
                Color(*Application.getInstance().getTheme().getColor(
                    "layerview_starts").getRgb()))

        if self._layer_view:
            self._layer_shader.setUniformValue(
                "u_max_feedrate", self._layer_view.getMaxFeedrate())
            self._layer_shader.setUniformValue(
                "u_min_feedrate", self._layer_view.getMinFeedrate())
            self._layer_shader.setUniformValue(
                "u_max_thickness", self._layer_view.getMaxThickness())
            self._layer_shader.setUniformValue(
                "u_min_thickness", self._layer_view.getMinThickness())
            self._layer_shader.setUniformValue(
                "u_max_line_width", self._layer_view.getMaxLineWidth())
            self._layer_shader.setUniformValue(
                "u_min_line_width", self._layer_view.getMinLineWidth())
            self._layer_shader.setUniformValue(
                "u_max_flow_rate", self._layer_view.getMaxFlowRate())
            self._layer_shader.setUniformValue(
                "u_min_flow_rate", self._layer_view.getMinFlowRate())
            self._layer_shader.setUniformValue(
                "u_layer_view_type", self._layer_view.getSimulationViewType())
            self._layer_shader.setUniformValue(
                "u_extruder_opacity", self._layer_view.getExtruderOpacities())
            self._layer_shader.setUniformValue(
                "u_show_travel_moves", self._layer_view.getShowTravelMoves())
            self._layer_shader.setUniformValue(
                "u_show_helpers", self._layer_view.getShowHelpers())
            self._layer_shader.setUniformValue("u_show_skin",
                                               self._layer_view.getShowSkin())
            self._layer_shader.setUniformValue(
                "u_show_infill", self._layer_view.getShowInfill())
            self._layer_shader.setUniformValue(
                "u_show_starts", self._layer_view.getShowStarts())
        else:
            #defaults
            self._layer_shader.setUniformValue("u_max_feedrate", 1)
            self._layer_shader.setUniformValue("u_min_feedrate", 0)
            self._layer_shader.setUniformValue("u_max_thickness", 1)
            self._layer_shader.setUniformValue("u_min_thickness", 0)
            self._layer_shader.setUniformValue("u_max_flow_rate", 1)
            self._layer_shader.setUniformValue("u_min_flow_rate", 0)
            self._layer_shader.setUniformValue("u_max_line_width", 1)
            self._layer_shader.setUniformValue("u_min_line_width", 0)
            self._layer_shader.setUniformValue("u_layer_view_type", 1)
            self._layer_shader.setUniformValue(
                "u_extruder_opacity",
                [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
            self._layer_shader.setUniformValue("u_show_travel_moves", 0)
            self._layer_shader.setUniformValue("u_show_helpers", 1)
            self._layer_shader.setUniformValue("u_show_skin", 1)
            self._layer_shader.setUniformValue("u_show_infill", 1)
            self._layer_shader.setUniformValue("u_show_starts", 1)

        if not self._tool_handle_shader:
            self._tool_handle_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        if not self._nozzle_shader:
            self._nozzle_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "color.shader"))
            self._nozzle_shader.setUniformValue(
                "u_color",
                Color(*Application.getInstance().getTheme().getColor(
                    "layerview_nozzle").getRgb()))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            self._disabled_shader.setUniformValue(
                "u_diffuseColor1",
                Color(*Application.getInstance().getTheme().getColor(
                    "model_unslicable").getRgb()))
            self._disabled_shader.setUniformValue(
                "u_diffuseColor2",
                Color(*Application.getInstance().getTheme().getColor(
                    "model_unslicable_alt").getRgb()))
            self._disabled_shader.setUniformValue("u_width", 50.0)
            self._disabled_shader.setUniformValue("u_opacity", 0.6)

        self.bind()

        tool_handle_batch = RenderBatch(self._tool_handle_shader,
                                        type=RenderBatch.RenderType.Overlay,
                                        backface_cull=True)
        disabled_batch = RenderBatch(self._disabled_shader)
        head_position = None  # Indicates the current position of the print head
        nozzle_node = None

        for node in DepthFirstIterator(self._scene.getRoot()):

            if isinstance(node, ToolHandle):
                tool_handle_batch.addItem(node.getWorldTransformation(),
                                          mesh=node.getSolidMesh())

            elif isinstance(node, NozzleNode):
                nozzle_node = node
                nozzle_node.setVisible(
                    False)  # Don't set to true, we render it separately!

            elif getattr(node, "_outside_buildarea", False) and isinstance(
                    node, SceneNode) and node.getMeshData() and node.isVisible(
                    ) and not node.callDecoration("isNonPrintingMesh"):
                disabled_batch.addItem(node.getWorldTransformation(copy=False),
                                       node.getMeshData())

            elif isinstance(node, SceneNode) and (node.getMeshData(
            ) or node.callDecoration("isBlockSlicing")) and node.isVisible():
                layer_data = node.callDecoration("getLayerData")
                if not layer_data:
                    continue

                # Render all layers below a certain number as line mesh instead of vertices.
                if self._layer_view._current_layer_num > -1 and (
                    (not self._layer_view._only_show_top_layers) or
                    (not self._layer_view.getCompatibilityMode())):
                    start = 0
                    end = 0
                    element_counts = layer_data.getElementCounts()
                    for layer in sorted(element_counts.keys()):
                        # In the current layer, we show just the indicated paths
                        if layer == self._layer_view._current_layer_num:
                            # We look for the position of the head, searching the point of the current path
                            index = self._layer_view._current_path_num
                            offset = 0
                            for polygon in layer_data.getLayer(layer).polygons:
                                # The size indicates all values in the two-dimension array, and the second dimension is
                                # always size 3 because we have 3D points.
                                if index >= polygon.data.size // 3 - offset:
                                    index -= polygon.data.size // 3 - offset
                                    offset = 1  # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon
                                    continue
                                # The head position is calculated and translated
                                head_position = Vector(
                                    polygon.data[index + offset][0],
                                    polygon.data[index + offset][1],
                                    polygon.data[index + offset]
                                    [2]) + node.getWorldPosition()
                                break
                            break
                        if self._layer_view._minimum_layer_num > layer:
                            start += element_counts[layer]
                        end += element_counts[layer]

                    # Calculate the range of paths in the last layer
                    current_layer_start = end
                    current_layer_end = end + self._layer_view._current_path_num * 2  # Because each point is used twice

                    # This uses glDrawRangeElements internally to only draw a certain range of lines.
                    # All the layers but the current selected layer are rendered first
                    if self._old_current_path != self._layer_view._current_path_num:
                        self._current_shader = self._layer_shadow_shader
                        self._switching_layers = False
                    if not self._layer_view.isSimulationRunning(
                    ) and self._old_current_layer != self._layer_view._current_layer_num:
                        self._current_shader = self._layer_shader
                        self._switching_layers = True

                    # The first line does not have a previous line: add a MoveCombingType in front for start detection
                    # this way the first start of the layer can also be drawn
                    prev_line_types = numpy.concatenate([
                        numpy.asarray([LayerPolygon.MoveCombingType],
                                      dtype=numpy.float32),
                        layer_data._attributes["line_types"]["value"]
                    ])
                    # Remove the last element
                    prev_line_types = prev_line_types[
                        0:layer_data._attributes["line_types"]["value"].size]
                    layer_data._attributes["prev_line_types"] = {
                        'opengl_type': 'float',
                        'value': prev_line_types,
                        'opengl_name': 'a_prev_line_type'
                    }

                    layers_batch = RenderBatch(
                        self._current_shader,
                        type=RenderBatch.RenderType.Solid,
                        mode=RenderBatch.RenderMode.Lines,
                        range=(start, end),
                        backface_cull=True)
                    layers_batch.addItem(node.getWorldTransformation(),
                                         layer_data)
                    layers_batch.render(self._scene.getActiveCamera())

                    # Current selected layer is rendered
                    current_layer_batch = RenderBatch(
                        self._layer_shader,
                        type=RenderBatch.RenderType.Solid,
                        mode=RenderBatch.RenderMode.Lines,
                        range=(current_layer_start, current_layer_end))
                    current_layer_batch.addItem(node.getWorldTransformation(),
                                                layer_data)
                    current_layer_batch.render(self._scene.getActiveCamera())

                    self._old_current_layer = self._layer_view._current_layer_num
                    self._old_current_path = self._layer_view._current_path_num

                # Create a new batch that is not range-limited
                batch = RenderBatch(self._layer_shader,
                                    type=RenderBatch.RenderType.Solid)

                if self._layer_view.getCurrentLayerMesh():
                    batch.addItem(node.getWorldTransformation(),
                                  self._layer_view.getCurrentLayerMesh())

                if self._layer_view.getCurrentLayerJumps():
                    batch.addItem(node.getWorldTransformation(),
                                  self._layer_view.getCurrentLayerJumps())

                if len(batch.items) > 0:
                    batch.render(self._scene.getActiveCamera())

        # The nozzle is drawn when once we know the correct position of the head,
        # but the user is not using the layer slider, and the compatibility mode is not enabled
        if not self._switching_layers and not self._compatibility_mode and self._layer_view.getActivity(
        ) and nozzle_node is not None:
            if head_position is not None:
                nozzle_node.setPosition(head_position)
                nozzle_batch = RenderBatch(
                    self._nozzle_shader,
                    type=RenderBatch.RenderType.Transparent)
                nozzle_batch.addItem(nozzle_node.getWorldTransformation(),
                                     mesh=nozzle_node.getMeshData())
                nozzle_batch.render(self._scene.getActiveCamera())

        if len(disabled_batch.items) > 0:
            disabled_batch.render(self._scene.getActiveCamera())

        # Render toolhandles on top of the layerview
        if len(tool_handle_batch.items) > 0:
            tool_handle_batch.render(self._scene.getActiveCamera())

        self.release()
Example #51
0
    def _renderItem(self, item: Dict[str, Any]):
        transformation = item["transformation"]
        mesh = item["mesh"]

        # Do not render if there's no vertex (empty mesh)
        if mesh.getVertexCount() == 0:
            return

        normal_matrix = item["normal_transformation"]
        if mesh.hasNormals() and normal_matrix is None:
            normal_matrix = Matrix(transformation.getData())
            normal_matrix.setRow(3, [0, 0, 0, 1])
            normal_matrix.setColumn(3, [0, 0, 0, 1])
            normal_matrix.invert()
            normal_matrix.transpose()

        self._shader.updateBindings(model_matrix=transformation,
                                    normal_matrix=normal_matrix)

        if item["uniforms"] is not None:
            self._shader.updateBindings(**item["uniforms"])

        vertex_buffer = OpenGL.getInstance().createVertexBuffer(mesh)
        vertex_buffer.bind()

        if self._render_range is None:
            index_buffer = OpenGL.getInstance().createIndexBuffer(mesh)
        else:
            # glDrawRangeElements does not work as expected and did not get the indices field working..
            # Now we're just uploading a clipped part of the array and the start index always becomes 0.
            index_buffer = OpenGL.getInstance().createIndexBuffer(
                mesh,
                force_recreate=True,
                index_start=self._render_range[0],
                index_stop=self._render_range[1])
        if index_buffer is not None:
            index_buffer.bind()

        self._shader.enableAttribute("a_vertex", "vector3f", 0)
        vertex_count = mesh.getVertexCount()
        offset = vertex_count * 3 * 4

        if mesh.hasNormals():
            self._shader.enableAttribute("a_normal", "vector3f", offset)
            offset += vertex_count * 3 * 4

        if mesh.hasColors():
            self._shader.enableAttribute("a_color", "vector4f", offset)
            offset += vertex_count * 4 * 4

        if mesh.hasUVCoordinates():
            self._shader.enableAttribute("a_uvs", "vector2f", offset)
            offset += vertex_count * 2 * 4

        for attribute_name in mesh.attributeNames():
            attribute = mesh.getAttribute(attribute_name)
            self._shader.enableAttribute(attribute["opengl_name"],
                                         attribute["opengl_type"], offset)
            if attribute["opengl_type"] == "vector2f":
                offset += mesh.getVertexCount() * 2 * 4
            elif attribute["opengl_type"] == "vector4f":
                offset += mesh.getVertexCount() * 4 * 4
            elif attribute["opengl_type"] == "int":
                offset += mesh.getVertexCount() * 4
            elif attribute["opengl_type"] == "float":
                offset += mesh.getVertexCount() * 4
            else:
                Logger.log(
                    "e",
                    "Attribute with name [%s] uses non implemented type [%s]."
                    % (attribute["opengl_name"], attribute["opengl_type"]))
                self._shader.disableAttribute(attribute["opengl_name"])

        if mesh.hasIndices():
            if self._render_range is None:
                if self._render_mode == self.RenderMode.Triangles:
                    self._gl.glDrawElements(self._render_mode,
                                            mesh.getFaceCount() * 3,
                                            self._gl.GL_UNSIGNED_INT, None)
                else:
                    self._gl.glDrawElements(self._render_mode,
                                            mesh.getFaceCount(),
                                            self._gl.GL_UNSIGNED_INT, None)
            else:
                if self._render_mode == self.RenderMode.Triangles:
                    self._gl.glDrawRangeElements(
                        self._render_mode, self._render_range[0],
                        self._render_range[1],
                        self._render_range[1] - self._render_range[0],
                        self._gl.GL_UNSIGNED_INT, None)
                else:
                    self._gl.glDrawElements(
                        self._render_mode,
                        self._render_range[1] - self._render_range[0],
                        self._gl.GL_UNSIGNED_INT, None)
        else:
            self._gl.glDrawArrays(self._render_mode, 0, vertex_count)

        vertex_buffer.release()

        if index_buffer is not None:
            index_buffer.release()
Example #52
0
    def beginRendering(self):
        # Convenience setup
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._shader:
            self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
            self._shader.setUniformValue("u_color", Color(32, 32, 32, 170))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                # For now we only render nodes that indicate that they need rendering.
                if node.getMeshData():
                    # Render origin of this node.
                    renderer.queueNode(scene.getRoot(), mesh = self._getAxisMesh(node), transparent = True)

                    # Render transparent MeshData
                    renderer.queueNode(node, shader = self._shader, transparent = True)

                    billboard_node = self._ensureNodeHasBillboard(node)

                    # Update the displayed data on the billboard.
                    data = self._matrixToHtml(node.getLocalTransformation())
                    billboard_node.setDisplayData({"name": node.getName(), "matrix": data, "depth": node.getDepth(), "parent_name": node.getParent().getName(), "has_mesh": "True"})

                # Handle group nodes
                if node.callDecoration("isGroup"):
                    # Render origin of this node.
                    renderer.queueNode(scene.getRoot(), mesh=self._getAxisMesh(node), transparent = True)
                    # Render bounding box of this node
                    renderer.queueNode(scene.getRoot(), mesh=node.getBoundingBoxMesh(), mode=Renderer.RenderLines)

                    billboard_node = self._ensureNodeHasBillboard(node)

                    # Update the displayed data on the billboard.
                    data = self._matrixToHtml(node.getLocalTransformation())
                    billboard_node.setDisplayData({"name": node.getName(), "matrix": data, "depth": node.getDepth(), "parent_name": node.getParent().getName(), "has_mesh": node.getMeshData() is not None})

                # We sometimes have nodes that are not groups, but have children. Also draw them
                elif not node.getMeshData() and len(node.getChildren()) != 0:
                    # Render origin of this node.
                    renderer.queueNode(scene.getRoot(), mesh=self._getAxisMesh(node), transparent = True)

                    billboard_node = self._ensureNodeHasBillboard(node)

                    # Update the displayed data on the billboard.
                    data = self._matrixToHtml(node.getLocalTransformation())
                    parent_name = node.getParent().getName() if node.getParent() else ""
                    billboard_node.setDisplayData({"name": node.getName(), "matrix": data, "depth": node.getDepth(), "parent_name": parent_name, "has_mesh": "False"})
                    bounding_box = node.getBoundingBox()
                    if bounding_box:
                        mesh_builder = MeshBuilder()
                        mesh_builder.addCube(
                            width=bounding_box.width,
                            height=bounding_box.height,
                            depth=bounding_box.depth,
                            center=bounding_box.center,
                            color=Color(0.0, 0.0, 1.0, 1.0)
                        )
                        mesh = mesh_builder.build()
                        renderer.queueNode(scene.getRoot(), mesh=mesh, mode=Renderer.RenderLines)
Example #53
0
    def beginRendering(self):
        scene = self.getController().getScene()
        renderer = self.getRenderer()

        if not self._theme:
            self._theme = Application.getInstance().getTheme()

        if not self._enabled_shader:
            self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
            self._enabled_shader.setUniformValue("u_overhangColor", Color(*self._theme.getColor("model_overhang").getRgb()))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader"))
            self._disabled_shader.setUniformValue("u_diffuseColor1", Color(*self._theme.getColor("model_unslicable").getRgb()))
            self._disabled_shader.setUniformValue("u_diffuseColor2", Color(*self._theme.getColor("model_unslicable_alt").getRgb()))
            self._disabled_shader.setUniformValue("u_width", 50.0)

        if not self._non_printing_shader:
            self._non_printing_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
            self._non_printing_shader.setUniformValue("u_diffuseColor", Color(*self._theme.getColor("model_non_printing").getRgb()))
            self._non_printing_shader.setUniformValue("u_opacity", 0.6)

        if not self._support_mesh_shader:
            self._support_mesh_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader"))
            self._support_mesh_shader.setUniformValue("u_vertical_stripes", True)
            self._support_mesh_shader.setUniformValue("u_width", 5.0)

        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if global_container_stack:
            support_extruder_nr = global_container_stack.getExtruderPositionValueWithDefault("support_extruder_nr")
            support_angle_stack = Application.getInstance().getExtruderManager().getExtruderStack(support_extruder_nr)

            if support_angle_stack is not None and Preferences.getInstance().getValue("view/show_overhang"):
                angle = support_angle_stack.getProperty("support_angle", "value")
                # Make sure the overhang angle is valid before passing it to the shader
                # Note: if the overhang angle is set to its default value, it does not need to get validated (validationState = None)
                if angle is not None and global_container_stack.getProperty("support_angle", "validationState") in [None, ValidatorState.Valid]:
                    self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle)))
                else:
                    self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang.
            else:
                self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))

        for node in DepthFirstIterator(scene.getRoot()):
            if not node.render(renderer):
                if node.getMeshData() and node.isVisible() and not node.callDecoration("getLayerData"):
                    uniforms = {}
                    shade_factor = 1.0

                    per_mesh_stack = node.callDecoration("getStack")

                    extruder_index = int(node.callDecoration("getActiveExtruderPosition"))

                    # Use the support extruder instead of the active extruder if this is a support_mesh
                    if per_mesh_stack:
                        if per_mesh_stack.getProperty("support_mesh", "value"):
                            extruder_index = int(global_container_stack.getExtruderPositionValueWithDefault("support_extruder_nr"))

                    try:
                        material_color = self._extruders_model.getItem(extruder_index)["color"]
                    except KeyError:
                        material_color = self._extruders_model.defaultColors[0]

                    if extruder_index != ExtruderManager.getInstance().activeExtruderIndex:
                        # Shade objects that are printed with the non-active extruder 25% darker
                        shade_factor = 0.6

                    try:
                        # Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
                        # an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
                        uniforms["diffuse_color"] = [
                            shade_factor * int(material_color[1:3], 16) / 255,
                            shade_factor * int(material_color[3:5], 16) / 255,
                            shade_factor * int(material_color[5:7], 16) / 255,
                            1.0
                        ]
                    except ValueError:
                        pass

                    if node.callDecoration("isNonPrintingMesh"):
                        if per_mesh_stack and (per_mesh_stack.getProperty("infill_mesh", "value") or per_mesh_stack.getProperty("cutting_mesh", "value")):
                            renderer.queueNode(node, shader = self._non_printing_shader, uniforms = uniforms, transparent = True)
                        else:
                            renderer.queueNode(node, shader = self._non_printing_shader, transparent = True)
                    elif getattr(node, "_outside_buildarea", False):
                        renderer.queueNode(node, shader = self._disabled_shader)
                    elif per_mesh_stack and per_mesh_stack.getProperty("support_mesh", "value"):
                        # Render support meshes with a vertical stripe that is darker
                        shade_factor = 0.6
                        uniforms["diffuse_color_2"] = [
                            uniforms["diffuse_color"][0] * shade_factor,
                            uniforms["diffuse_color"][1] * shade_factor,
                            uniforms["diffuse_color"][2] * shade_factor,
                            1.0
                        ]
                        renderer.queueNode(node, shader = self._support_mesh_shader, uniforms = uniforms)
                    else:
                        renderer.queueNode(node, shader = self._enabled_shader, uniforms = uniforms)
                if node.callDecoration("isGroup") and Selection.isSelected(node):
                    renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(), mode = RenderBatch.RenderMode.LineLoop)
Example #54
0
    def render(self):
        if not self._layer_shader:
            self._layer_shader = OpenGL.getInstance().createShaderProgram(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath("LayerView"),
                    "layers.shader"))
        # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
        self._layer_shader.setUniformValue(
            "u_active_extruder",
            float(max(0, self._extruder_manager.activeExtruderIndex)))
        if not self._tool_handle_shader:
            self._tool_handle_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "toolhandle.shader"))

        self.bind()

        tool_handle_batch = RenderBatch(self._tool_handle_shader,
                                        type=RenderBatch.RenderType.Overlay)

        for node in DepthFirstIterator(self._scene.getRoot()):

            if isinstance(node, ToolHandle):
                tool_handle_batch.addItem(node.getWorldTransformation(),
                                          mesh=node.getSolidMesh())

            elif isinstance(node, SceneNode) and (node.getMeshData(
            ) or node.callDecoration("isBlockSlicing")) and node.isVisible():
                layer_data = node.callDecoration("getLayerData")
                if not layer_data:
                    continue

                # Render all layers below a certain number as line mesh instead of vertices.
                if self._layerview._current_layer_num - self._layerview._solid_layers > -1 and not self._layerview._only_show_top_layers:
                    start = 0
                    end = 0
                    element_counts = layer_data.getElementCounts()
                    for layer, counts in element_counts.items():
                        if layer + self._layerview._solid_layers > self._layerview._current_layer_num:
                            break
                        end += counts

                    # This uses glDrawRangeElements internally to only draw a certain range of lines.
                    batch = RenderBatch(self._layer_shader,
                                        type=RenderBatch.RenderType.Solid,
                                        mode=RenderBatch.RenderMode.Lines,
                                        range=(start, end))
                    batch.addItem(node.getWorldTransformation(), layer_data)
                    batch.render(self._scene.getActiveCamera())

                # Create a new batch that is not range-limited
                batch = RenderBatch(self._layer_shader,
                                    type=RenderBatch.RenderType.Solid)

                if self._layerview._current_layer_mesh:
                    batch.addItem(node.getWorldTransformation(),
                                  self._layerview._current_layer_mesh)

                if self._layerview._current_layer_jumps:
                    batch.addItem(node.getWorldTransformation(),
                                  self._layerview._current_layer_jumps)

                if len(batch.items) > 0:
                    batch.render(self._scene.getActiveCamera())

        # Render toolhandles on top of the layerview
        if len(tool_handle_batch.items) > 0:
            tool_handle_batch.render(self._scene.getActiveCamera())

        self.release()
Example #55
0
    def _renderItem(self, item):
        transformation = item["transformation"]
        mesh = item["mesh"]

        normal_matrix = None
        if mesh.hasNormals():
            normal_matrix = copy.deepcopy(transformation)
            normal_matrix.setRow(3, [0, 0, 0, 1])
            normal_matrix.setColumn(3, [0, 0, 0, 1])
            normal_matrix = normal_matrix.getInverse().getTransposed()

        model_view_matrix = copy.deepcopy(transformation).preMultiply(
            self._view_matrix)
        model_view_projection_matrix = copy.deepcopy(
            transformation).preMultiply(self._view_projection_matrix)

        self._shader.updateBindings(
            model_matrix=transformation,
            normal_matrix=normal_matrix,
            model_view_matrix=model_view_matrix,
            model_view_projection_matrix=model_view_projection_matrix)

        if item["uniforms"] is not None:
            self._shader.updateBindings(**item["uniforms"])

        vertex_buffer = OpenGL.getInstance().createVertexBuffer(mesh)
        vertex_buffer.bind()

        index_buffer = OpenGL.getInstance().createIndexBuffer(mesh)
        if index_buffer is not None:
            index_buffer.bind()

        self._shader.enableAttribute("a_vertex", "vector3f", 0)
        offset = mesh.getVertexCount() * 3 * 4

        if mesh.hasNormals():
            self._shader.enableAttribute("a_normal", "vector3f", offset)
            offset += mesh.getVertexCount() * 3 * 4

        if mesh.hasColors():
            self._shader.enableAttribute("a_color", "vector4f", offset)
            offset += mesh.getVertexCount() * 4 * 4

        if mesh.hasUVCoordinates():
            self._shader.enableAttribute("a_uvs", "vector2f", offset)
            offset += mesh.getVertexCount() * 2 * 4

        if mesh.hasIndices():
            if self._render_range is None:
                if self._render_mode == self.RenderMode.Triangles:
                    self._gl.glDrawElements(self._render_mode,
                                            mesh.getFaceCount() * 3,
                                            self._gl.GL_UNSIGNED_INT, None)
                else:
                    self._gl.glDrawElements(self._render_mode,
                                            mesh.getFaceCount(),
                                            self._gl.GL_UNSIGNED_INT, None)
            else:
                if self._render_mode == self.RenderMode.Triangles:
                    self._gl.glDrawRangeElements(
                        self._render_mode, self._render_range[0],
                        self._render_range[1],
                        self._render_range[1] - self._render_range[0],
                        self._gl.GL_UNSIGNED_INT, None)
                else:
                    self._gl.glDrawRangeElements(
                        self._render_mode, self._render_range[0],
                        self._render_range[1],
                        self._render_range[1] - self._render_range[0],
                        self._gl.GL_UNSIGNED_INT, None)
        else:
            self._gl.glDrawArrays(self._render_mode, 0, mesh.getVertexCount())

        self._shader.disableAttribute("a_vertex")
        self._shader.disableAttribute("a_normal")
        self._shader.disableAttribute("a_color")
        self._shader.disableAttribute("a_uvs")
        vertex_buffer.release()

        if index_buffer is not None:
            index_buffer.release()
Example #56
0
    def _checkSetup(self):
        if not self._extruders_model:
            self._extruders_model = Application.getInstance(
            ).getExtrudersModel()

        if not self._theme:
            self._theme = Application.getInstance().getTheme()

        if not self._enabled_shader:
            self._enabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "overhang.shader"))
            self._enabled_shader.setUniformValue(
                "u_overhangColor",
                Color(*self._theme.getColor("model_overhang").getRgb()))

        if not self._disabled_shader:
            self._disabled_shader = OpenGL.getInstance().createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            self._disabled_shader.setUniformValue(
                "u_diffuseColor1",
                Color(*self._theme.getColor("model_unslicable").getRgb()))
            self._disabled_shader.setUniformValue(
                "u_diffuseColor2",
                Color(*self._theme.getColor("model_unslicable_alt").getRgb()))
            self._disabled_shader.setUniformValue("u_width", 50.0)

        if not self._non_printing_shader:
            self._non_printing_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders,
                                  "transparent_object.shader"))
            self._non_printing_shader.setUniformValue(
                "u_diffuseColor",
                Color(*self._theme.getColor("model_non_printing").getRgb()))
            self._non_printing_shader.setUniformValue("u_opacity", 0.6)

        if not self._support_mesh_shader:
            self._support_mesh_shader = OpenGL.getInstance(
            ).createShaderProgram(
                Resources.getPath(Resources.Shaders, "striped.shader"))
            self._support_mesh_shader.setUniformValue("u_vertical_stripes",
                                                      True)
            self._support_mesh_shader.setUniformValue("u_width", 5.0)

        if not Application.getInstance().getPreferences().getValue(
                self._show_xray_warning_preference):
            self._xray_shader = None
            self._xray_composite_shader = None
            if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings(
            ):
                self._composite_pass.setLayerBindings(self._old_layer_bindings)
                self._composite_pass.setCompositeShader(
                    self._old_composite_shader)
                self._old_layer_bindings = None
                self._old_composite_shader = None
                self._xray_warning_message.hide()
        else:
            if not self._xray_shader:
                self._xray_shader = OpenGL.getInstance().createShaderProgram(
                    Resources.getPath(Resources.Shaders, "xray.shader"))

            if not self._xray_composite_shader:
                self._xray_composite_shader = OpenGL.getInstance(
                ).createShaderProgram(
                    Resources.getPath(Resources.Shaders,
                                      "xray_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._xray_composite_shader.setUniformValue(
                    "u_background_color",
                    Color(*theme.getColor("viewport_background").getRgb()))
                self._xray_composite_shader.setUniformValue(
                    "u_outline_color",
                    Color(*theme.getColor("model_selection_outline").getRgb()))

            renderer = self.getRenderer()
            if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(
            ):
                # Currently the RenderPass constructor requires a size > 0
                # This should be fixed in RenderPass's constructor.
                self._xray_pass = XRayPass.XRayPass(1, 1)

                renderer.addRenderPass(self._xray_pass)

                if not self._composite_pass:
                    self._composite_pass = self.getRenderer().getRenderPass(
                        "composite")

                self._old_layer_bindings = self._composite_pass.getLayerBindings(
                )
                self._composite_pass.setLayerBindings(
                    ["default", "selection", "xray"])
                self._old_composite_shader = self._composite_pass.getCompositeShader(
                )
                self._composite_pass.setCompositeShader(
                    self._xray_composite_shader)
Example #57
0
    def __init__(self, width, height):
        super().__init__("xray", width, height)

        self._shader = None
        self._gl = OpenGL.getInstance().getBindingsObject()
        self._scene = Application.getInstance().getController().getScene()
Example #58
0
 def getSelectFaceSupported(self) -> bool:
     # Use a dummy postfix, since an equal version with a postfix is considered smaller normally.
     return Version(OpenGL.getInstance().getOpenGLVersion()) >= Version(
         "4.1 dummy-postfix")
Example #59
0
    def __init__(self):
        super().__init__()

        self._qt_texture = QOpenGLTexture(QOpenGLTexture.Target2D)
        self._gl = OpenGL.getInstance().getBindingsObject()
        self._file_name = None
Example #60
0
    def event(self, event):
        modifiers = QApplication.keyboardModifiers()
        ctrl_is_active = modifiers & Qt.ControlModifier
        shift_is_active = modifiers & Qt.ShiftModifier
        if event.type == Event.KeyPressEvent and ctrl_is_active:
            amount = 10 if shift_is_active else 1
            if event.key == KeyEvent.UpKey:
                self.setLayer(self._current_layer_num + amount)
                return True
            if event.key == KeyEvent.DownKey:
                self.setLayer(self._current_layer_num - amount)
                return True

        if event.type == Event.ViewActivateEvent:
            # Make sure the SimulationPass is created
            layer_pass = self.getSimulationPass()
            self.getRenderer().addRenderPass(layer_pass)

            # Make sure the NozzleNode is add to the root
            nozzle = self.getNozzleNode()
            nozzle.setParent(self.getController().getScene().getRoot())
            nozzle.setVisible(False)

            Application.getInstance().globalContainerStackChanged.connect(
                self._onGlobalStackChanged)
            self._onGlobalStackChanged()

            if not self._simulationview_composite_shader:
                self._simulationview_composite_shader = OpenGL.getInstance(
                ).createShaderProgram(
                    os.path.join(
                        PluginRegistry.getInstance().getPluginPath(
                            "SimulationView"),
                        "simulationview_composite.shader"))
                theme = Application.getInstance().getTheme()
                self._simulationview_composite_shader.setUniformValue(
                    "u_background_color",
                    Color(*theme.getColor("viewport_background").getRgb()))
                self._simulationview_composite_shader.setUniformValue(
                    "u_outline_color",
                    Color(*theme.getColor("model_selection_outline").getRgb()))

            if not self._composite_pass:
                self._composite_pass = self.getRenderer().getRenderPass(
                    "composite")

            self._old_layer_bindings = self._composite_pass.getLayerBindings(
            )[:]  # make a copy so we can restore to it later
            self._composite_pass.getLayerBindings().append("simulationview")
            self._old_composite_shader = self._composite_pass.getCompositeShader(
            )
            self._composite_pass.setCompositeShader(
                self._simulationview_composite_shader)

        elif event.type == Event.ViewDeactivateEvent:
            self._wireprint_warning_message.hide()
            Application.getInstance().globalContainerStackChanged.disconnect(
                self._onGlobalStackChanged)
            if self._global_container_stack:
                self._global_container_stack.propertyChanged.disconnect(
                    self._onPropertyChanged)

            self._nozzle_node.setParent(None)
            self.getRenderer().removeRenderPass(self._layer_pass)
            self._composite_pass.setLayerBindings(self._old_layer_bindings)
            self._composite_pass.setCompositeShader(self._old_composite_shader)