Просмотр исходного кода

Merge branch 'master' of https://github.com/Ultimaker/Cura

fieldOfView 8 лет назад
Родитель
Сommit
5f26372b96

+ 8 - 14
cura/BuildVolume.py

@@ -13,6 +13,7 @@ from UM.Math.Color import Color
 from UM.Math.AxisAlignedBox import AxisAlignedBox
 from UM.Math.Polygon import Polygon
 from UM.Message import Message
+from UM.Signal import Signal
 
 from UM.View.RenderBatch import RenderBatch
 from UM.View.GL.OpenGL import OpenGL
@@ -49,6 +50,8 @@ def approximatedCircleVertices(r):
 class BuildVolume(SceneNode):
     VolumeOutlineColor = Color(12, 169, 227, 255)
 
+    raftThicknessChanged = Signal()
+
     def __init__(self, parent = None):
         super().__init__(parent)
 
@@ -69,7 +72,6 @@ class BuildVolume(SceneNode):
 
         self._raft_thickness = 0.0
         self._adhesion_type = None
-        self._raft_mesh = None
         self._platform = Platform(self)
 
         self._active_container_stack = None
@@ -103,8 +105,6 @@ class BuildVolume(SceneNode):
         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._raft_mesh and self._adhesion_type == "raft":
-            renderer.queueNode(self, mesh=self._raft_mesh, transparent=True, backface_cull=True, sort=-9)
 
         return True
 
@@ -153,17 +153,6 @@ class BuildVolume(SceneNode):
             mb.setVertexUVCoordinates(n, v[0], v[2])
         self._grid_mesh = mb.build()
 
-        # Build raft mesh: a plane on the height of the raft.
-        mb = MeshBuilder()
-        mb.addQuad(
-            Vector(min_w, self._raft_thickness, min_d),
-            Vector(max_w, self._raft_thickness, min_d),
-            Vector(max_w, self._raft_thickness, max_d),
-            Vector(min_w, self._raft_thickness, max_d),
-            color=Color(128, 128, 128, 64)
-        )
-        self._raft_mesh = mb.build()
-
         disallowed_area_height = 0.1
         disallowed_area_size = 0
         if self._disallowed_areas:
@@ -221,6 +210,9 @@ class BuildVolume(SceneNode):
             " \"Print Sequence\" setting to prevent the gantry from colliding"
             " with printed objects."), lifetime=10).show()
 
+    def getRaftThickness(self):
+        return self._raft_thickness
+
     def _updateRaftThickness(self):
         old_raft_thickness = self._raft_thickness
         self._adhesion_type = self._active_container_stack.getProperty("adhesion_type", "value")
@@ -232,9 +224,11 @@ class BuildVolume(SceneNode):
                 self._active_container_stack.getProperty("raft_surface_layers", "value") *
                     self._active_container_stack.getProperty("raft_surface_thickness", "value") +
                 self._active_container_stack.getProperty("raft_airgap", "value"))
+
         # Rounding errors do not matter, we check if raft_thickness has changed at all
         if old_raft_thickness != self._raft_thickness:
             self.setPosition(Vector(0, -self._raft_thickness, 0), SceneNode.TransformSpace.World)
+            self.raftThicknessChanged.emit()
 
     def _onGlobalContainerStackChanged(self):
         if self._active_container_stack:

+ 19 - 4
cura/ConvexHullDecorator.py

@@ -16,6 +16,12 @@ class ConvexHullDecorator(SceneNodeDecorator):
         self._init2DConvexHullCache()
 
         self._global_stack = None
+
+        self._raft_thickness = 0.0
+        # For raft thickness, DRY
+        self._build_volume = Application.getInstance().getBuildVolume()
+        self._build_volume.raftThicknessChanged.connect(self._onChanged)
+
         Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
         Application.getInstance().getController().toolOperationStarted.connect(self._onChanged)
         Application.getInstance().getController().toolOperationStopped.connect(self._onChanged)
@@ -93,14 +99,17 @@ class ConvexHullDecorator(SceneNodeDecorator):
 
         convex_hull = self.getConvexHull()
         if self._convex_hull_node:
-            if self._convex_hull_node.getHull() == convex_hull:
+            # Check if convex hull has changed
+            if (self._convex_hull_node.getHull() == convex_hull and
+                self._convex_hull_node.getThickness() == self._raft_thickness):
+
                 return
             self._convex_hull_node.setParent(None)
-        hull_node = ConvexHullNode.ConvexHullNode(self._node, convex_hull, root)
+        hull_node = ConvexHullNode.ConvexHullNode(self._node, convex_hull, self._raft_thickness, root)
         self._convex_hull_node = hull_node
 
     def _onSettingValueChanged(self, key, property_name):
-        if key == "print_sequence" and property_name == "value":
+        if key in self._affected_settings and property_name == "value":
             self._onChanged()
 
     def _init2DConvexHullCache(self):
@@ -157,7 +166,8 @@ class ConvexHullDecorator(SceneNodeDecorator):
                 vertex_data = mesh.getConvexHullTransformedVertices(world_transform)
                 # Don't use data below 0.
                 # TODO; We need a better check for this as this gives poor results for meshes with long edges.
-                vertex_data = vertex_data[vertex_data[:,1] >= -0.01]
+                # Do not throw away vertices: the convex hull may be too small and objects can collide.
+                # vertex_data = vertex_data[vertex_data[:,1] >= -0.01]
 
                 if len(vertex_data) >= 4:
                     # Round the vertex data to 1/10th of a mm, then remove all duplicate vertices
@@ -213,6 +223,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
         return convex_hull.getMinkowskiHull(Polygon(numpy.array([[-0.5, -0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]], numpy.float32)))
 
     def _onChanged(self, *args):
+        self._raft_thickness = self._build_volume.getRaftThickness()
         self.recomputeConvexHull()
 
     def _onGlobalStackChanged(self):
@@ -235,3 +246,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
         if root is node:
             return True
         return self.__isDescendant(root, node.getParent())
+
+    _affected_settings = [
+        "adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers",
+        "raft_surface_thickness", "raft_airgap", "print_sequence"]

+ 24 - 29
cura/ConvexHullNode.py

@@ -4,16 +4,16 @@
 from UM.Scene.SceneNode import SceneNode
 from UM.Resources import Resources
 from UM.Math.Color import Color
-from UM.Math.Vector import Vector
 from UM.Mesh.MeshBuilder import MeshBuilder  # To create a mesh to display the convex hull with.
 
 from UM.View.GL.OpenGL import OpenGL
 
 class ConvexHullNode(SceneNode):
-    ##  Convex hull node is a special type of scene node that is used to display a 2D area, to indicate the
+    ##  Convex hull node is a special type of scene node that is used to display an area, to indicate the
     #   location an object uses on the buildplate. This area (or area's in case of one at a time printing) is
-    #   then displayed as a transparent shadow.
-    def __init__(self, node, hull, parent = None):
+    #   then displayed as a transparent shadow. If the adhesion type is set to raft, the area is extruded
+    #   to represent the raft as well.
+    def __init__(self, node, hull, thickness, parent = None):
         super().__init__(parent)
 
         self.setCalculateBoundingBox(False)
@@ -23,7 +23,7 @@ class ConvexHullNode(SceneNode):
         self._original_parent = parent
 
         # Color of the drawn convex hull
-        self._color = Color(35, 35, 35, 128)
+        self._color = Color(35, 35, 35, 192)
 
         # The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
         self._mesh_height = 0.1
@@ -34,44 +34,38 @@ class ConvexHullNode(SceneNode):
         self._onNodeDecoratorsChanged(self._node)
 
         self._convex_hull_head_mesh = None
-        self._hull = hull
 
+        self._hull = hull
+        self._thickness = thickness
         if self._hull:
-            hull_mesh = self.createHullMesh(self._hull.getPoints())
-            if hull_mesh:
+            hull_mesh_builder = MeshBuilder()
+
+            if hull_mesh_builder.addConvexPolygonExtrusion(
+                self._hull.getPoints()[::-1],  # bottom layer is reversed
+                self._mesh_height-thickness, self._mesh_height, color=self._color):
+
+                hull_mesh = hull_mesh_builder.build()
                 self.setMeshData(hull_mesh)
         convex_hull_head = self._node.callDecoration("getConvexHullHead")
         if convex_hull_head:
-            self._convex_hull_head_mesh = self.createHullMesh(convex_hull_head.getPoints())
+            convex_hull_head_builder = MeshBuilder()
+            convex_hull_head_builder.addConvexPolygon(convex_hull_head.getPoints(), self._mesh_height-thickness)
+            self._convex_hull_head_mesh = convex_hull_head_builder.build()
 
     def getHull(self):
         return self._hull
 
-    ##  Actually create the mesh from the hullpoints
-    #   /param hull_points list of xy values
-    #   /return meshData
-    def createHullMesh(self, hull_points):
-        # Input checking.
-        if len(hull_points) < 3:
-            return None
-
-        mesh_builder = MeshBuilder()
-        point_first = Vector(hull_points[0][0], self._mesh_height, hull_points[0][1])
-        point_previous = Vector(hull_points[1][0], self._mesh_height, hull_points[1][1])
-        for point in hull_points[2:]:  # Add the faces in the order of a triangle fan.
-            point_new = Vector(point[0], self._mesh_height, point[1])
-            mesh_builder.addFace(point_first, point_previous, point_new, color = self._color)
-            point_previous = point_new  # Prepare point_previous for the next triangle.
-
-        return mesh_builder.build()
+    def getThickness(self):
+        return self._thickness
 
     def getWatchedNode(self):
         return self._node
 
     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)
+            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():
@@ -85,4 +79,5 @@ class ConvexHullNode(SceneNode):
         self._color = Color(35, 35, 35, 0.5)
 
         if not node:
-            return
+            return
+

+ 2 - 7
cura/Settings/MachineManager.py

@@ -543,15 +543,10 @@ class MachineManager(QObject):
         if containers:
             new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile"))
 
-            new_container = UM.Settings.InstanceContainer("")
-
-            ## Copy all values
-            new_container.deserialize(containers[0].serialize())
+            new_container = containers[0].duplicate(new_name, new_name)
 
-            new_container.setReadOnly(False)
-            new_container.setName(new_name)
-            new_container._id = new_name
             UM.Settings.ContainerRegistry.getInstance().addContainer(new_container)
+
             return new_name
 
         return ""

+ 9 - 1
plugins/GCodeWriter/GCodeWriter.py

@@ -78,15 +78,19 @@ class GCodeWriter(MeshWriter):
 
         # Duplicate the current quality profile and update it with any user settings.
         flat_quality_id = machine_manager.duplicateContainer(container_with_profile.getId())
+
         flat_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = flat_quality_id)[0]
         user_settings = stack.getTop()
+
+        # We don't want to send out any signals, so disconnect them.
+        flat_quality.propertyChanged.disconnectAll()
+
         for key in user_settings.getAllKeys():
             flat_quality.setProperty(key, "value", user_settings.getProperty(key, "value"))
 
         serialized = flat_quality.serialize()
 
         data = {"global_quality": serialized}
-
         manager = ExtruderManager.getInstance()
         for extruder in manager.getMachineExtruders(stack.getId()):
             extruder_quality = extruder.findContainer({"type": "quality"})
@@ -94,6 +98,10 @@ class GCodeWriter(MeshWriter):
             flat_extruder_quality_id = machine_manager.duplicateContainer(extruder_quality.getId())
             flat_extruder_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=flat_extruder_quality_id)[0]
             extruder_user_settings = extruder.getTop()
+
+            # We don't want to send out any signals, so disconnect them.
+            flat_extruder_quality.propertyChanged.disconnectAll()
+            
             for key in extruder_user_settings.getAllKeys():
                 flat_extruder_quality.setProperty(key, "value", extruder_user_settings.getProperty(key, "value"))
 

+ 74 - 0
resources/shaders/transparent_object.shader

@@ -0,0 +1,74 @@
+[shaders]
+vertex =
+    uniform highp mat4 u_viewProjectionMatrix;
+    uniform highp mat4 u_modelMatrix;
+    uniform highp mat4 u_normalMatrix;
+
+    attribute highp vec4 a_vertex;
+    attribute highp vec4 a_normal;
+    attribute highp vec2 a_uvs;
+
+    varying highp vec3 v_vertex;
+    varying highp vec3 v_normal;
+    varying highp vec2 v_uvs;
+
+    void main()
+    {
+        vec4 world_space_vert = u_modelMatrix * a_vertex;
+        gl_Position = u_viewProjectionMatrix * world_space_vert;
+
+        v_vertex = world_space_vert.xyz;
+        v_normal = (u_normalMatrix * normalize(a_normal)).xyz;
+
+        v_uvs = a_uvs;
+    }
+
+fragment =
+    uniform mediump vec4 u_ambientColor;
+    uniform mediump vec4 u_diffuseColor;
+    uniform highp vec3 u_lightPosition;
+    uniform highp vec3 u_viewPosition;
+    uniform mediump float u_opacity;
+    uniform sampler2D u_texture;
+
+    varying highp vec3 v_vertex;
+    varying highp vec3 v_normal;
+    varying highp vec2 v_uvs;
+
+    void main()
+    {
+        // Copied from platform.shader, removed texture
+        mediump vec4 final_color = vec4(0.0);
+
+        /* Ambient Component */
+        final_color += u_ambientColor;
+
+        highp vec3 normal = normalize(v_normal);
+        highp vec3 light_dir = normalize(u_lightPosition - v_vertex);
+
+        /* Diffuse Component */
+        highp float n_dot_l = clamp(dot(normal, light_dir), 0.0, 1.0);
+        final_color += (n_dot_l * u_diffuseColor);
+
+        final_color.a = u_opacity;
+
+        gl_FragColor = final_color;
+    }
+
+[defaults]
+u_ambientColor = [0.3, 0.3, 0.3, 1.0]
+u_diffuseColor = [1.0, 1.0, 1.0, 1.0]
+u_opacity = 0.5
+u_texture = 0
+
+[bindings]
+u_viewProjectionMatrix = view_projection_matrix
+u_modelMatrix = model_matrix
+u_normalMatrix = normal_matrix
+u_lightPosition = light_0_position
+u_viewPosition = camera_position
+
+[attributes]
+a_vertex = vertex
+a_normal = normal
+a_uvs = uv0