Example #1
0
    def transform(self, o):
        """
        Transform the Blender object <o> as a node, e.g. rotate and shear it appropriately
        
        Returns:
            The resulting matrix for the transformation
        """
        matrix = None
        # calculate rotation angle
        # remember, the base edge has the index zero in the tuple
        baseEdge = self.edges[0][0]
        _baseEdge = self._edges[0][0]
        dot = baseEdge.dot(_baseEdge)
        # check if <baseEdge> and <_baseEdge> are already aligned
        if abs(1 - dot) > zero2:
            angle = acos(dot)
            if self.n.dot(_baseEdge.cross(baseEdge)) < 0.:
                angle = -angle
            bpy.ops.transform.rotate(value=angle, axis=self.n)
            matrix = mathutils.Matrix.Rotation(angle, 4, self.n)

        angle = self.rotate(o)

        self.shear(o, angle)

        # remember the transformation matrix
        self.matrix = matrix

        return matrix
Example #2
0
 def rotate(self, o):
     """
     Realization of <Node.rotate(..)>
     """
     # check if we need to perform rotation
     cos = self.edges[1][2]
     convex = self.edges[1][3]
     if convex and abs(cos) < zero2:
         return
     
     angle = acos(cos)
     
     bm = getBmesh(o)
     bmesh.ops.rotate(
         bm,
         cent = zeroVector,
         matrix = mathutils.Matrix.Rotation(
             angle-math.pi/2. if convex else 1.5*math.pi-angle,
             3,
             self.n
         ),
         verts = getVertsForVertexGroup(o, bm, o.vertex_groups[ self._edges[1][1] ].name)
     )
     setBmesh(o, bm)
     
     return angle
Example #3
0
 def transform(self, o):
     """
     Transform the Blender object <o> as a node, e.g. rotate and shear it appropriately
     
     Returns:
         The resulting matrix for the transformation
     """
     matrix = None
     # calculate rotation angle
     # remember, the base edge has the index zero in the tuple
     baseEdge = self.edges[0][0]
     _baseEdge = self._edges[0][0]
     dot = baseEdge.dot(_baseEdge)
     # check if <baseEdge> and <_baseEdge> are already aligned
     if abs(1-dot) > zero2:
         angle = acos(dot)
         if self.n.dot( _baseEdge.cross(baseEdge) ) < 0.:
             angle = -angle
         bpy.ops.transform.rotate(value = angle, axis=self.n)
         matrix = mathutils.Matrix.Rotation(angle, 4, self.n)
     
     angle = self.rotate(o)
     
     self.shear(o, angle)
     
     # remember the transformation matrix
     self.matrix = matrix
     
     return matrix
Example #4
0
    def rotate(self, o):
        """
        Realization of <Node.rotate(..)>
        """
        # check if we need to perform rotation
        cos = self.edges[1][2]
        convex = self.edges[1][3]
        if convex and abs(cos) < zero2:
            return

        angle = acos(cos)

        bm = getBmesh(o)
        bmesh.ops.rotate(
            bm,
            cent=zeroVector,
            matrix=mathutils.Matrix.Rotation(
                angle - math.pi / 2. if convex else 1.5 * math.pi - angle, 3,
                self.n),
            verts=getVertsForVertexGroup(
                o, bm, o.vertex_groups[self._edges[1][1]].name))
        setBmesh(o, bm)

        return angle
Example #5
0
    def shear(self, o, angle):
        """
        Realization of <Node.shear(..)>
        """
        if angle is None or not "c" in o.vertex_groups:
            return

        _edges = self._edges

        convex = self.edges[1][3]
        bm = getBmesh(o)
        shearFactor = 1. / math.tan(angle / 2.)
        if convex:
            shearFactor = shearFactor - 1.
        else:
            shearFactor = -shearFactor - 1.

        # For the share transformation of the central part defined by the vertex group <c>
        # we may have to provide a space matrix, since the parameters of the share transformation are
        # defined under assumtions that the central part defined by the vertex group <c> is oriented
        # along the <baseBisector>. So the <space> matrix defines the rotation that orients
        # the actual bisector along the <baseBisector>
        bisector = (_edges[0][0] + _edges[1][0]).normalized()
        dot = bisector.dot(baseBisector)
        # check if <bisector> and <baseBisector> are already aligned
        if abs(1 - dot) > zero2:
            _angle = acos(dot)
            if self.n.dot(bisector.cross(baseBisector)) < 0.:
                _angle = -_angle
            spaceMatrix = mathutils.Matrix.Rotation(_angle, 4, self.n)
        else:
            spaceMatrix = mathutils.Matrix.Identity(4)

        bmesh.ops.transform(bm,
                            matrix=mathutils.Matrix.Shear(
                                'XY', 4, (shearFactor, 0.)),
                            verts=getVertsForVertexGroup(o, bm, "c"),
                            space=spaceMatrix)
        # Set BMesh here to get the correct result in the next section
        # of the code related to the shape key update
        setBmesh(o, bm)

        # update shape key data (if available) for the vertices of the vertex group <c>
        shape_keys = o.data.shape_keys
        if shape_keys:
            if shape_keys.key_blocks.get("frame_width", None):
                bm = getBmesh(o)

                shapeKey = bm.verts.layers.shape.get("frame_width")
                # the bisector of the edges after the shear transformation
                bisector = mathutils.Matrix.Rotation(
                    angle / 2. - math.pi / 4. if convex else 0.75 * math.pi -
                    angle / 2., 3, self.n) * bisector
                # offset vector for the shape key
                offset = shapeKeyOffset / math.sin(angle / 2.) * bisector
                for v in getVertsForVertexGroup(o, bm, "c"):
                    # check if the vertex changes its location for the shape key
                    if ((v[shapeKey] - v.co).length > zero2):
                        v[shapeKey] = v.co + offset

                setBmesh(o, bm)
Example #6
0
 def shear(self, o, angle):
     """
     Realization of <Node.shear(..)>
     """
     if angle is None or not "c" in o.vertex_groups:
         return
     
     _edges = self._edges
     
     convex = self.edges[1][3]
     bm = getBmesh(o)
     shearFactor = 1./math.tan(angle/2.)
     if convex:
         shearFactor = shearFactor - 1.
     else:
         shearFactor = -shearFactor - 1.
     
     # For the share transformation of the central part defined by the vertex group <c>
     # we may have to provide a space matrix, since the parameters of the share transformation are
     # defined under assumtions that the central part defined by the vertex group <c> is oriented
     # along the <baseBisector>. So the <space> matrix defines the rotation that orients
     # the actual bisector along the <baseBisector>
     bisector = (_edges[0][0] + _edges[1][0]).normalized()
     dot = bisector.dot(baseBisector)
     # check if <bisector> and <baseBisector> are already aligned
     if abs(1-dot) > zero2:
         _angle = acos(dot)
         if self.n.dot( bisector.cross(baseBisector) ) < 0.:
             _angle = -_angle
         spaceMatrix = mathutils.Matrix.Rotation(_angle, 4, self.n)
     else:
         spaceMatrix = mathutils.Matrix.Identity(4)
     
     bmesh.ops.transform(
         bm,
         matrix = mathutils.Matrix.Shear('XY', 4, (shearFactor, 0.)),
         verts = getVertsForVertexGroup(o, bm, "c"),
         space = spaceMatrix
     )
     # Set BMesh here to get the correct result in the next section
     # of the code related to the shape key update
     setBmesh(o, bm)
     
     # update shape key data (if available) for the vertices of the vertex group <c>
     shape_keys = o.data.shape_keys
     if shape_keys:
         if shape_keys.key_blocks.get("frame_width", None):
             bm = getBmesh(o)
             
             shapeKey = bm.verts.layers.shape.get("frame_width")
             # the bisector of the edges after the shear transformation
             bisector = mathutils.Matrix.Rotation(
                 angle/2. - math.pi/4. if convex else 0.75*math.pi - angle/2.,
                 3,
                 self.n
             ) * bisector
             # offset vector for the shape key
             offset = shapeKeyOffset / math.sin(angle/2.) * bisector
             for v in getVertsForVertexGroup(o, bm, "c"):
                 # check if the vertex changes its location for the shape key
                 if ( (v[shapeKey] - v.co).length > zero2):
                     v[shapeKey] = v.co + offset
             
             setBmesh(o, bm)