Ejemplo n.º 1
0
def test_setSimpleScale():
    node = SceneNode()
    op = ScaleOperation(node, Vector(1, 2, 3), set_scale = True)

    op.redo()
    assert node.getScale() == Vector(1, 2, 3)

    op.undo()
    assert node.getScale() == Vector(1, 1, 1)
Ejemplo n.º 2
0
 def _scaleSelectedNodes(self, scale_vector: Vector) -> None:
     selected_nodes = self._getSelectedObjectsWithoutSelectedAncestors()
     if len(selected_nodes) > 1:
         op = GroupedOperation()
         for node in selected_nodes:
             op.addOperation(ScaleOperation(node, scale_vector, scale_around_point=node.getWorldPosition()))
         op.push()
     else:
         for node in selected_nodes:
             ScaleOperation(node, scale_vector, scale_around_point=node.getWorldPosition()).push()
Ejemplo n.º 3
0
def test_relativeScale():
    node = SceneNode()
    op = ScaleOperation(node, Vector(2, 2, 2), set_scale=True)
    op.redo()

    op2 = ScaleOperation(node, Vector(1, 2, 3), relative_scale=True)
    op2.redo()
    assert node.getScale() == Vector(3, 4, 5)
Ejemplo n.º 4
0
def test_addScale():
    node = SceneNode()
    op = ScaleOperation(node, Vector(1, 2, 3), set_scale=True)
    op.redo()

    op2 = ScaleOperation(node, Vector(1, 2, 3), add_scale=True)
    op2.redo()
    assert node.getScale() == Vector(2, 4, 6)
Ejemplo n.º 5
0
    def event(self, event):
        super().event(event)

        if event.type == Event.MousePressEvent:
            if MouseEvent.LeftButton not in event.buttons:
                return False

            id = self._renderer.getIdAtCoordinate(event.x, event.y)
            if not id:
                return False

            if ToolHandle.isAxis(id):
                self.setLockedAxis(id)
                return True

        if event.type == Event.MouseReleaseEvent:
            if self.getLockedAxis():
                op = None
                if Selection.getCount() == 1:
                    node = Selection.getSelectedObject(0)
                    scale = node.getScale()
                    if self.getLockedAxis() == ToolHandle.XAxis:
                        scale.setX(-scale.x)
                    elif self.getLockedAxis() == ToolHandle.YAxis:
                        scale.setY(-scale.y)
                    elif self.getLockedAxis() == ToolHandle.ZAxis:
                        scale.setZ(-scale.z)

                    op = ScaleOperation(node, scale, set_scale=True)
                else:
                    op = GroupedOperation()

                    for node in Selection.getAllSelectedObjects():
                        scale = node.getScale()
                        if self.getLockedAxis() == ToolHandle.XAxis:
                            scale.setX(-scale.x)
                        elif self.getLockedAxis() == ToolHandle.YAxis:
                            scale.setY(-scale.y)
                        elif self.getLockedAxis() == ToolHandle.ZAxis:
                            scale.setZ(-scale.z)

                        op.addOperation(
                            ScaleOperation(node, scale, set_scale=True))

                op.push()

                self.setLockedAxis(None)
                return True

        return False
Ejemplo n.º 6
0
def test_relativeScale():
    node = SceneNode()
    op = ScaleOperation(node, Vector(2, 2, 2), set_scale=True)
    op.redo()

    op2 = ScaleOperation(node, Vector(1, 2, 3), relative_scale=True)
    op2.redo()
    assert node.getScale() == Vector(3, 4, 5)
Ejemplo n.º 7
0
def test_addScale():
    node = SceneNode()
    op = ScaleOperation(node, Vector(1, 2, 3), set_scale = True)
    op.redo()

    op2 = ScaleOperation(node, Vector(1, 2, 3), add_scale = True)
    op2.redo()
    assert node.getScale() == Vector(2, 4, 6)
Ejemplo n.º 8
0
def test_setSimpleScale():
    node = SceneNode()
    op = ScaleOperation(node, Vector(1, 2, 3), set_scale=True)

    op.redo()
    assert node.getScale() == Vector(1, 2, 3)

    op.undo()
    assert node.getScale() == Vector(1, 1, 1)
Ejemplo n.º 9
0
    def setScaleZ(self, scale):
        obj = Selection.getSelectedObject(0)
        if obj:
            obj_scale = obj.getScale()
            if round(float(obj_scale.z), 4) != scale:
                scale_factor = abs(scale / obj_scale.z)
                if self._non_uniform_scale:
                    scale_vector = Vector(1, 1, scale_factor)
                else:
                    scale_vector = Vector(scale_factor, scale_factor,
                                          scale_factor)

                op = GroupedOperation()
                for node in self._getSelectedObjectsWithoutSelectedAncestors():
                    op.addOperation(
                        ScaleOperation(
                            node,
                            scale_vector,
                            scale_around_point=node.getWorldPosition()))
                op.push()
Ejemplo n.º 10
0
    def setScaleZ(self, scale):
        obj = Selection.getSelectedObject(0)
        if obj:
            obj_scale = self._getScaleInWorldCoordinates(obj)
            if round(float(obj_scale.z), 4) != scale:
                scale_factor = abs(scale / obj_scale.z)
                if self._non_uniform_scale:
                    scale_vector = Vector(1, 1, scale_factor)
                else:
                    scale_vector = Vector(scale_factor, scale_factor,
                                          scale_factor)

                op = GroupedOperation()
                for node in Selection.getAllSelectedObjects():
                    op.addOperation(
                        ScaleOperation(
                            node,
                            scale_vector,
                            scale_around_point=node.getWorldPosition()))
                op.push()
Ejemplo n.º 11
0
    def event(self, event):
        super().event(event)

        if event.type == Event.MousePressEvent:
            if MouseEvent.LeftButton not in event.buttons:
                return False

            id = self._renderer.getIdAtCoordinate(event.x, event.y)
            if not id:
                return False

            if ToolHandle.isAxis(id):
                self.setLockedAxis(id)
                return True

        if event.type == Event.MouseReleaseEvent:
            if self.getLockedAxis():
                op = None
                if Selection.getCount() == 1:
                    node = Selection.getSelectedObject(0)
                    scale = node.getScale()
                    if self.getLockedAxis() == ToolHandle.XAxis:
                        scale.setX(-scale.x)
                    elif self.getLockedAxis() == ToolHandle.YAxis:
                        scale.setY(-scale.y)
                    elif self.getLockedAxis() == ToolHandle.ZAxis:
                        scale.setZ(-scale.z)

                    op = ScaleOperation(node, scale, set_scale=True)
                else:
                    op = GroupedOperation()

                    for node in Selection.getAllSelectedObjects():
                        scale = node.getScale()
                        if self.getLockedAxis() == ToolHandle.XAxis:
                            scale.setX(-scale.x)
                        elif self.getLockedAxis() == ToolHandle.YAxis:
                            scale.setY(-scale.y)
                        elif self.getLockedAxis() == ToolHandle.ZAxis:
                            scale.setZ(-scale.z)

                        op.addOperation(ScaleOperation(node, scale, set_scale = True))

                op.push()

                self.setLockedAxis(None)
                return True

        return False
Ejemplo n.º 12
0
    def setObjectDepth(self, depth):
        obj = Selection.getSelectedObject(0)
        if obj:
            depth = float(depth)
            obj_depth = obj.getBoundingBox().depth
            if not Float.fuzzyCompare(obj_depth, depth, DIMENSION_TOLERANCE):
                scale_factor = depth / obj_depth
                if self._non_uniform_scale:
                    scale_vector = Vector(1, 1, scale_factor)
                else:
                    scale_vector = Vector(scale_factor, scale_factor,
                                          scale_factor)

                op = GroupedOperation()
                for node in self._getSelectedObjectsWithoutSelectedAncestors():
                    op.addOperation(
                        ScaleOperation(
                            node,
                            scale_vector,
                            scale_around_point=node.getWorldPosition()))
                op.push()
Ejemplo n.º 13
0
    def setScaleY(self, scale):
        obj = Selection.getSelectedObject(0)
        if obj:
            obj_scale = self.getObjectHeight() / obj.getMeshData().getExtents(
            ).height
            if round(float(obj_scale), 4) != scale:
                scale_factor = abs(scale / obj_scale)
                if self._non_uniform_scale:
                    scale_vector = Vector(1, scale_factor, 1)
                else:
                    scale_vector = Vector(scale_factor, scale_factor,
                                          scale_factor)

                op = GroupedOperation()
                for node in self._getSelectedObjectsWithoutSelectedAncestors():
                    op.addOperation(
                        ScaleOperation(
                            node,
                            scale_vector,
                            scale_around_point=node.getWorldPosition()))
                op.push()
Ejemplo n.º 14
0
    def setObjectHeight(self, height):
        obj = Selection.getSelectedObject(0)
        if obj:
            height = float(height)
            obj_height = obj.getBoundingBox().height
            if not Float.fuzzyCompare(obj_height, height, DIMENSION_TOLERANCE):
                scale_factor = height / obj_height
                if self._non_uniform_scale:
                    scale_vector = Vector(1, scale_factor, 1)
                else:
                    scale_vector = Vector(scale_factor, scale_factor,
                                          scale_factor)

                op = GroupedOperation()
                for node in self._getSelectedObjectsWithoutSelectedAncestors():
                    op.addOperation(
                        ScaleOperation(
                            node,
                            scale_vector,
                            scale_around_point=node.getWorldPosition()))
                op.push()
Ejemplo n.º 15
0
    def setObjectWidth(self, width):
        obj = Selection.getSelectedObject(0)
        if obj:
            width = float(width)
            obj_width = obj.getBoundingBox().width
            if not Float.fuzzyCompare(obj_width, width, DIMENSION_TOLERANCE):
                scale_factor = width / obj_width
                if self._non_uniform_scale:
                    scale_vector = Vector(scale_factor, 1, 1)
                else:
                    scale_vector = Vector(scale_factor, scale_factor,
                                          scale_factor)

                op = GroupedOperation()
                for node in Selection.getAllSelectedObjects():
                    op.addOperation(
                        ScaleOperation(
                            node,
                            scale_vector,
                            scale_around_point=node.getWorldPosition()))
                op.push()
Ejemplo n.º 16
0
    def event(self, event):
        """Handle mouse and keyboard events

        :param event: type(Event)
        """

        super().event(event)

        if event.type == Event.ToolActivateEvent:
            for node in self._getSelectedObjectsWithoutSelectedAncestors():
                node.boundingBoxChanged.connect(self.propertyChanged)

        if event.type == Event.ToolDeactivateEvent:
            for node in self._getSelectedObjectsWithoutSelectedAncestors():
                node.boundingBoxChanged.disconnect(self.propertyChanged)

        # Handle modifier keys: Shift toggles snap, Control toggles uniform scaling
        if event.type == Event.KeyPressEvent:
            if event.key == KeyEvent.ShiftKey:
                self.setScaleSnap(not self._snap_scale)

            elif event.key == KeyEvent.ControlKey:
                self.setNonUniformScale(not self._non_uniform_scale)

        if event.type == Event.KeyReleaseEvent:
            if event.key == KeyEvent.ShiftKey:
                self.setScaleSnap(not self._snap_scale)

            elif event.key == KeyEvent.ControlKey:
                self.setNonUniformScale(not self._non_uniform_scale)

        if event.type == Event.MousePressEvent and self._controller.getToolsEnabled(
        ):
            # Initialise a scale operation
            if MouseEvent.LeftButton not in event.buttons:
                return False

            id = self._selection_pass.getIdAtPosition(event.x, event.y)
            if not id:
                return False

            if self._handle.isAxis(id):
                self.setLockedAxis(id)
            self._saved_handle_position = self._handle.getWorldPosition()

            # Save the current positions of the node, as we want to scale arround their current centres
            self._saved_node_positions = []
            for node in self._getSelectedObjectsWithoutSelectedAncestors():
                self._saved_node_positions.append((node, node.getPosition()))

            self._scale_sum = 0.0
            self._last_event = event

            if id == ToolHandle.XAxis:
                self.setDragPlane(
                    Plane(Vector(0, 0, 1), self._saved_handle_position.z))
            elif id == ToolHandle.YAxis:
                self.setDragPlane(
                    Plane(Vector(0, 0, 1), self._saved_handle_position.z))
            elif id == ToolHandle.ZAxis:
                self.setDragPlane(
                    Plane(Vector(0, 1, 0), self._saved_handle_position.y))
            else:
                self.setDragPlane(
                    Plane(Vector(0, 1, 0), self._saved_handle_position.y))

            self.setDragStart(event.x, event.y)
            return True

        if event.type == Event.MouseMoveEvent:
            # Perform a scale operation
            if not self.getDragPlane():
                return False

            drag_position = self.getDragPosition(event.x, event.y)
            if drag_position:
                if self.getLockedAxis() == ToolHandle.XAxis:
                    drag_position = drag_position.set(y=0, z=0)
                elif self.getLockedAxis() == ToolHandle.YAxis:
                    drag_position = drag_position.set(x=0, z=0)
                elif self.getLockedAxis() == ToolHandle.ZAxis:
                    drag_position = drag_position.set(x=0, y=0)

                drag_length = (drag_position -
                               self._saved_handle_position).length()
                if self._drag_length > 0:
                    drag_change = (drag_length -
                                   self._drag_length) / 100 * self._scale_speed
                    if self.getLockedAxis() in [
                            ToolHandle.XAxis, ToolHandle.YAxis,
                            ToolHandle.ZAxis
                    ]:
                        # drag the handle, axis is already determined
                        if self._snap_scale:
                            scale_factor = round(drag_change, 1)
                        else:
                            scale_factor = drag_change
                    else:
                        # uniform scaling; because we use central cube, we use the screen x, y for scaling.
                        # upper right is scale up, lower left is scale down
                        scale_factor_delta = (
                            (self._last_event.y - event.y) -
                            (self._last_event.x - event.x)) * self._scale_speed
                        self._scale_sum += scale_factor_delta
                        if self._snap_scale:
                            scale_factor = round(self._scale_sum, 1)
                            # remember the decimals when snap scaling
                            self._scale_sum -= scale_factor
                        else:
                            scale_factor = self._scale_sum
                            self._scale_sum = 0.0
                    if scale_factor:
                        scale_change = Vector(0.0, 0.0, 0.0)
                        if self._non_uniform_scale:
                            if self.getLockedAxis() == ToolHandle.XAxis:
                                scale_change = scale_change.set(x=scale_factor)
                            elif self.getLockedAxis() == ToolHandle.YAxis:
                                scale_change = scale_change.set(y=scale_factor)
                            elif self.getLockedAxis() == ToolHandle.ZAxis:
                                scale_change = scale_change.set(z=scale_factor)
                            else:
                                # Middle handle
                                scale_change = scale_change.set(x=scale_factor,
                                                                y=scale_factor,
                                                                z=scale_factor)
                        else:
                            scale_change = scale_change.set(x=scale_factor,
                                                            y=scale_factor,
                                                            z=scale_factor)

                        # Scale around the saved centers of all selected nodes
                        if len(self._saved_node_positions) > 1:
                            op = GroupedOperation()
                            for node, position in self._saved_node_positions:
                                op.addOperation(
                                    ScaleOperation(
                                        node,
                                        scale_change,
                                        relative_scale=True,
                                        scale_around_point=position))
                            op.push()
                        else:
                            for node, position in self._saved_node_positions:
                                ScaleOperation(
                                    node,
                                    scale_change,
                                    relative_scale=True,
                                    scale_around_point=position).push()
                        self._drag_length = (self._saved_handle_position -
                                             drag_position).length()
                else:
                    self.operationStarted.emit(self)
                    self._drag_length = (
                        self._saved_handle_position - drag_position
                    ).length()  #First move, do nothing but set right length.
                self._last_event = event  # remember for uniform drag
                return True

        if event.type == Event.MouseReleaseEvent:
            # Finish a scale operation
            if self.getDragPlane():
                self.setDragPlane(None)
                self.setLockedAxis(ToolHandle.NoAxis)
                self._drag_length = 0
                self.operationStopped.emit(self)
                return True
Ejemplo n.º 17
0
    def event(self, event):
        super().event(event)

        if event.type == Event.ToolActivateEvent:
            self._old_scale = Selection.getSelectedObject(0).getScale()
            for node in Selection.getAllSelectedObjects():
                node.boundingBoxChanged.connect(self.propertyChanged)

        if event.type == Event.ToolDeactivateEvent:
            for node in Selection.getAllSelectedObjects():
                node.boundingBoxChanged.disconnect(self.propertyChanged)

        # Handle modifier keys: Shift toggles snap, Control toggles uniform scaling
        if event.type == Event.KeyPressEvent:
            if event.key == KeyEvent.ShiftKey:
                self._snap_scale = False
                self.propertyChanged.emit()
            elif event.key == KeyEvent.ControlKey:
                self._non_uniform_scale = True
                self.propertyChanged.emit()

        if event.type == Event.KeyReleaseEvent:
            if event.key == KeyEvent.ShiftKey:
                self._snap_scale = True
                self.propertyChanged.emit()
            elif event.key == KeyEvent.ControlKey:
                self._non_uniform_scale = False
                self.propertyChanged.emit()

        if event.type == Event.MousePressEvent and self._controller.getToolsEnabled():
            # Initialise a scale operation
            if MouseEvent.LeftButton not in event.buttons:
                return False

            id = self._selection_pass.getIdAtPosition(event.x, event.y)
            if not id:
                return False

            if ToolHandle.isAxis(id):
                self.setLockedAxis(id)

            # Save the current positions of the node, as we want to scale arround their current centres
            self._saved_node_positions = []
            for node in Selection.getAllSelectedObjects():
                self._saved_node_positions.append((node, node.getWorldPosition()))

            self._saved_handle_position = self._handle.getWorldPosition()

            if id == ToolHandle.XAxis:
                self.setDragPlane(Plane(Vector(0, 0, 1), self._saved_handle_position.z))
            elif id == ToolHandle.YAxis:
                self.setDragPlane(Plane(Vector(0, 0, 1), self._saved_handle_position.z))
            elif id == ToolHandle.ZAxis:
                self.setDragPlane(Plane(Vector(0, 1, 0), self._saved_handle_position.y))
            else:
                self.setDragPlane(Plane(Vector(0, 1, 0), self._saved_handle_position.y))

            self.setDragStart(event.x, event.y)
            self.operationStarted.emit(self)

        if event.type == Event.MouseMoveEvent:
            # Perform a scale operation
            if not self.getDragPlane():
                return False

            drag_position = self.getDragPosition(event.x, event.y)
            if drag_position:
                drag_length = (drag_position - self._saved_handle_position).length()
                if self._drag_length > 0:
                    drag_change = (drag_length - self._drag_length) / 100 * self._scale_speed
                    if self._snap_scale:
                        scale_factor = round(drag_change, 1)
                    else:
                        scale_factor = drag_change
                    if scale_factor:
                        scale_change = Vector(0.0, 0.0, 0.0)
                        if self._non_uniform_scale:
                            if self.getLockedAxis() == ToolHandle.XAxis:
                                scale_change.setX(scale_factor)
                            elif self.getLockedAxis() == ToolHandle.YAxis:
                                scale_change.setY(scale_factor)
                            elif self.getLockedAxis() == ToolHandle.ZAxis:
                                scale_change.setZ(scale_factor)
                        else:
                            scale_change.setX(scale_factor)
                            scale_change.setY(scale_factor)
                            scale_change.setZ(scale_factor)

                        # Scale around the saved centeres of all selected nodes
                        op = GroupedOperation()
                        for node, position in self._saved_node_positions:
                            op.addOperation(ScaleOperation(node, scale_change, relative_scale = True, scale_around_point = position))
                        op.push()
                        self._drag_length = (self._saved_handle_position - drag_position).length()
                else:
                    self._drag_length = (self._saved_handle_position - drag_position).length() #First move, do nothing but set right length.
                return True

        if event.type == Event.MouseReleaseEvent:
            # Finish a scale operation
            if self.getDragPlane():
                self.setDragPlane(None)
                self.setLockedAxis(None)
                self._drag_length = 0
                self.operationStopped.emit(self)
                return True