Ejemplo n.º 1
0
    def _onSelectedFaceChanged(self):
        self._handle.setEnabled(not Selection.getFaceSelectMode())

        selected_face = Selection.getSelectedFace()
        if not Selection.getSelectedFace() or not (Selection.hasSelection() and Selection.getFaceSelectMode()):
            return

        original_node, face_id = selected_face
        meshdata = original_node.getMeshDataTransformed()
        if not meshdata or face_id < 0:
            return

        rotation_point, face_normal = meshdata.getFacePlane(face_id)
        rotation_point_vector = Vector(rotation_point[0], rotation_point[1], rotation_point[2])
        face_normal_vector = Vector(face_normal[0], face_normal[1], face_normal[2])
        rotation_quaternion = Quaternion.rotationTo(face_normal_vector.normalized(), Vector(0.0, -1.0, 0.0))

        operation = GroupedOperation()
        current_node = None  # type: Optional[SceneNode]
        for node in Selection.getAllSelectedObjects():
            current_node = node
            parent_node = current_node.getParent()
            while parent_node and parent_node.callDecoration("isGroup"):
                current_node = parent_node
                parent_node = current_node.getParent()
        if current_node is None:
            return

        rotate_operation = RotateOperation(current_node, rotation_quaternion, rotation_point_vector)
        operation.addOperation(rotate_operation)
        operation.push()
Ejemplo n.º 2
0
    def test_faceSelectMode(self):
        Selection.selectedFaceChanged = MagicMock()

        Selection.setFaceSelectMode(True)
        assert Selection.getFaceSelectMode()

        Selection.setFaceSelectMode(True)
        Selection.setFaceSelectMode(False)
        assert not Selection.getFaceSelectMode()
        assert Selection.selectedFaceChanged.emit.call_count == 2
Ejemplo n.º 3
0
 def _changeRenderMode(self, faces=True):
     if Selection.hasSelection() and Selection.getFaceSelectMode() != faces:
         self._select = False
         Selection.setFaceSelectMode(faces)
         if self._selection_pass:
             self._selection_pass.render()
         self._select = True
Ejemplo n.º 4
0
 def setSelectFaceToLayFlatMode(self, select: bool) -> None:
     if select != self._select_face_mode or select != Selection.getFaceSelectMode(
     ):
         self._select_face_mode = select
         if not select:
             Selection.clearFace()
         Selection.setFaceSelectMode(self._select_face_mode)
         self.propertyChanged.emit()
Ejemplo n.º 5
0
    def setSelectFaceToLayFlatMode(self, select: bool) -> None:
        """Set the rotate tool to/from 'Lay flat by face'-Mode."""

        if select != self._select_face_mode or select != Selection.getFaceSelectMode():
            self._select_face_mode = select
            if not select:
                Selection.clearFace()
            Selection.setFaceSelectMode(self._select_face_mode)
            self.propertyChanged.emit()
Ejemplo n.º 6
0
 def _pixelHover(self, event):
     if Selection.getFaceSelectMode():
         face_id = self._selection_pass.getFaceIdAtPosition(event.x, event.y)
         if face_id >= 0:
             Selection.hoverFace(Selection.getSelectedObject(0), face_id)
         else:
             Selection.clearFace()
         return True
     return False
Ejemplo n.º 7
0
    def _onSelectedFaceChanged(self):
        if not self._select_face_mode:
            return

        self._handle.setEnabled(not Selection.getFaceSelectMode())

        selected_face = Selection.getSelectedFace()
        if not Selection.getSelectedFace() or not (
                Selection.hasSelection() and Selection.getFaceSelectMode()):
            return

        original_node, face_id = selected_face
        meshdata = original_node.getMeshDataTransformed()
        if not meshdata or face_id < 0:
            return
        if face_id > (meshdata.getVertexCount() / 3 if
                      not meshdata.hasIndices() else meshdata.getFaceCount()):
            return

        face_mid, face_normal = meshdata.getFacePlane(face_id)
        object_mid = original_node.getBoundingBox().center
        rotation_point_vector = Vector(object_mid.x, object_mid.y, face_mid[2])
        face_normal_vector = Vector(face_normal[0], face_normal[1],
                                    face_normal[2])
        rotation_quaternion = Quaternion.rotationTo(
            face_normal_vector.normalized(), Vector(0.0, -1.0, 0.0))

        operation = GroupedOperation()
        current_node = None  # type: Optional[SceneNode]
        for node in Selection.getAllSelectedObjects():
            current_node = node
            parent_node = current_node.getParent()
            while parent_node and parent_node.callDecoration("isGroup"):
                current_node = parent_node
                parent_node = current_node.getParent()
        if current_node is None:
            return

        rotate_operation = RotateOperation(current_node, rotation_quaternion,
                                           rotation_point_vector)
        gravity_operation = GravityOperation(current_node)
        operation.addOperation(rotate_operation)
        operation.addOperation(gravity_operation)
        operation.push()
    def add(self):
        Selection.clearFace()
        if not Selection.getFaceSelectMode():
            Selection.setFaceSelectMode(True)

        if len(self._bcs) == 0:
            N = 1
        else:
            N = int(self._bcs[-1].getName().split(" ")[1]) + 1

        if self._bc_type == BoundaryConditionListModel.Anchor:
            bc = SmartSliceScene.AnchorFace('Anchor ' + str(N))
            bc.surface_type = SmartSliceScene.HighlightFace.SurfaceType.Flat
        else:
            bc = SmartSliceScene.LoadFace('Load ' + str(N))
            bc.force.magnitude = 10.0
            bc.force.direction_type = SmartSliceScene.Force.DirectionType.Normal
            bc.surface_type = SmartSliceScene.HighlightFace.SurfaceType.Flat

        self._smart_slice_scene_node.addFace(bc)
Ejemplo n.º 9
0
 def faceSelectMode(self):
     return Selection.getFaceSelectMode()
Ejemplo n.º 10
0
 def _onSelectedFaceChanged(self):
     self._mode = SelectionPass.SelectionMode.FACES if Selection.getFaceSelectMode(
     ) else SelectionPass.SelectionMode.OBJECTS
Ejemplo n.º 11
0
 def getSelectFaceToLayFlatMode(self) -> bool:
     if not Selection.getFaceSelectMode():
         self._select_face_mode = False  # .. but not the other way around!
     return self._select_face_mode
Ejemplo n.º 12
0
    def event(self, event: Event) -> bool:

        if not self._selection_pass:
            self._selection_pass = cast(
                SelectionPass,
                Application.getInstance().getRenderer().getRenderPass(
                    "selection"))
            if not self._selection_pass:
                return False

        # Tool activated - make sure we render the faces
        if event.type == Event.ToolActivateEvent:
            self._changeRenderMode(faces=True)
            self._enabled = True
            if self._bc_list and self._bc_list.getActiveNode():
                self._controller.getScene().sceneChanged.emit(
                    self._bc_list.getActiveNode())
            return False

        # Tool deactivated - make sure we render the faces
        if event.type == Event.ToolDeactivateEvent:
            self._changeRenderMode(faces=False)
            self._enabled = False
            if self._bc_list and self._bc_list.getActiveNode():
                self._controller.getScene().sceneChanged.emit(
                    self._bc_list.getActiveNode())
                self._bc_list = None
            return False

        if not self.getEnabled():
            return False

        # Not a load face - make sure we render faces
        if not self._bc_list or not self._bc_list.getActiveNode(
        ) or isinstance(self._bc_list.getActiveNode(),
                        SmartSliceScene.AnchorFace):
            self._changeRenderMode(faces=True)
            return False

        active_node = self._bc_list.getActiveNode()  # Load face
        rotator = active_node.getRotator()  # Rotator on the load face
        arrow = active_node.activeArrow  # Active arrow on the load face

        if event.type == Event.MousePressEvent:

            # Must be a left mouse event to select or rotate
            if MouseEvent.LeftButton not in event.buttons:
                return False

            pixel_color = self._selection_pass.getIdAtPosition(
                event.x, event.y)

            # We did not click the tool - we need to select the surface under it if it exists
            # TODO - This is a little hacky.... we should implement a SelectionPass just for this Tool
            if not pixel_color or not arrow.isAxis(pixel_color):
                if Selection.hasSelection(
                ) and not Selection.getFaceSelectMode():
                    self._changeRenderMode(faces=True)
                    select_tool = PluginRegistry.getInstance().getPluginObject(
                        "SelectionTool")
                    return select_tool.event(event)

            # Rotator isn't enabled - we don't need to do anything
            if not rotator.isEnabled():
                return False

            # If we made it here, we have clicked the tool. Set the locked color to our tool color, and set the plane
            # the user will be constrained to drag in
            self.setLockedAxis(pixel_color)
            self.setDragPlane(Plane(rotator.rotation_axis))

            self.setDragStart(event.x, event.y)
            self._rotating = True
            self._angle = 0
            return True

        if event.type == Event.MouseMoveEvent:

            # Rotator isn't enabled - we don't need to do anything
            if not rotator.isEnabled():
                return False

            event = cast(MouseEvent, event)

            # Turn the shader on for the rotator and arrow if the mouse is hovered on them
            # in the above, pixel_color is the color of the solid mesh of the pixekl the mouse is on
            # For some reason, "ActiveAxis" means the color of the tool we are interested in
            if not self._rotating:
                self._changeRenderMode(faces=False)
                pixel_color = self._selection_pass.getIdAtPosition(
                    event.x, event.y)

                if rotator.isAxis(pixel_color):
                    rotator.setActiveAxis(pixel_color)
                    arrow.setActiveAxis(pixel_color)
                else:
                    rotator.setActiveAxis(None)
                    arrow.setActiveAxis(None)

                return False

            # We are rotating. Check to ensure we have a starting position for the mouse
            if not self.getDragStart():
                self.setDragStart(event.x, event.y)
                if not self.getDragStart():  #May have set it to None.
                    return False

            self.operationStarted.emit(self)

            drag_start = self.getDragStart() - rotator.center
            drag_position = self.getDragPosition(event.x, event.y)
            if not drag_position:
                return False
            drag_end = drag_position - rotator.center

            # Project the vectors back to the plane of the rotator
            drag_start = drag_start - drag_start.dot(
                rotator.rotation_axis) * rotator.rotation_axis
            drag_end = drag_end - drag_end.dot(
                rotator.rotation_axis) * rotator.rotation_axis

            angle = angleBetweenVectors(drag_start, drag_end)

            axes_length = (rotator.rotation_axis.normalized() -
                           drag_end.cross(drag_start).normalized()).length()
            angle = -angle if axes_length < 1.e-2 else angle

            rotation = Quaternion.fromAngleAxis(angle, rotator.rotation_axis)

            self._angle += angle
            active_node.rotateArrow(angle)
            self.setDragStart(event.x, event.y)

            return True

        # Finished the rotation - reset everything and update the arrow direction
        if event.type == Event.MouseReleaseEvent:
            if self._rotating:
                self.setDragPlane(None)
                self.setLockedAxis(ToolHandle.NoAxis)
                self._angle = None
                self._rotating = False
                self.propertyChanged.emit()
                active_node.facePropertyChanged.emit(active_node)
                # self._changeRenderMode(faces=True)
                self.operationStopped.emit(self)

                return True

        return False
Ejemplo n.º 13
0
    def getSelectFaceToLayFlatMode(self) -> bool:
        """Whether the rotate tool is in 'Lay flat by face'-Mode."""

        if not Selection.getFaceSelectMode():
            self._select_face_mode = False  # .. but not the other way around!
        return self._select_face_mode
Ejemplo n.º 14
0
    def _pixelSelection(self, event):
        # Find a node id by looking at a pixel value at the requested location
        if self._selection_pass:
            if Selection.getFaceSelectMode():
                item_id = id(Selection.getSelectedObject(0))
            else:
                item_id = self._selection_pass.getIdAtPosition(
                    event.x, event.y)
        else:
            Logger.log(
                "w",
                "Selection pass is None. getRenderPass('selection') returned None"
            )
            return False

        if not item_id and not self._shift_is_active:
            if Selection.hasSelection():
                Selection.clearFace()
                Selection.clear()
                return True
            return False  # Nothing was selected before and the user didn't click on an object.

        # Find the scene-node which matches the node-id
        for node in BreadthFirstIterator(self._scene.getRoot()):
            if id(node) != item_id:
                continue

            if self._isNodeInGroup(node):
                is_selected = Selection.isSelected(
                    self._findTopGroupNode(node))
            else:
                is_selected = Selection.isSelected(node)

            if self._shift_is_active:
                if is_selected:
                    # Deselect the SceneNode and its siblings in a group
                    if node.getParent():
                        if self._ctrl_is_active or not self._isNodeInGroup(
                                node):
                            Selection.remove(node)
                        else:
                            Selection.remove(self._findTopGroupNode(node))
                        return True
                else:
                    # Select the SceneNode and its siblings in a group
                    if node.getParent():
                        if self._ctrl_is_active or not self._isNodeInGroup(
                                node):
                            Selection.add(node)
                        else:
                            Selection.add(self._findTopGroupNode(node))
                        return True
            else:
                if Selection.getFaceSelectMode():
                    face_id = self._selection_pass.getFaceIdAtPosition(
                        event.x, event.y)
                    if face_id >= 0:
                        Selection.toggleFace(node, face_id)
                    else:
                        Selection.clear()
                        Selection.clearFace()
                if not is_selected or Selection.getCount() > 1:
                    # Select only the SceneNode and its siblings in a group
                    Selection.clear()
                    if node.getParent():
                        if self._ctrl_is_active or not self._isNodeInGroup(
                                node):
                            Selection.add(node)
                        else:
                            Selection.add(self._findTopGroupNode(node))
                        return True
                elif self._isNodeInGroup(node) and self._ctrl_is_active:
                    Selection.clear()
                    Selection.add(node)
                    return True

        return False