Beispiel #1
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
Beispiel #2
0
 def getInitialLoop(self, bm):
     # find the first occurrence of a number in the names of vertex groups
     for g in self.obj.vertex_groups:
         g = g.name
         if g.isdigit():
             break
     # getting bottom <vb> and top <vt> vertices
     vb, vt = getVertsForVertexGroup(self.obj, bm, g)
     if vb.co.z > vt.co.z:
         vb, vt = vt, vb
     if len(vb.link_loops) == 1:
         # <vb> and <vt> are located at an open end of the finish
         loop1 = vb.link_loops[0]
     else:  # len(vb.link_loops) == 2
         loop1, loop2 = vb.link_loops
         # ensure that loop1 goes horizontally
         if loop1.link_loop_next.vert == vt:
             loop1 = loop2
     return loop1
Beispiel #3
0
 def getInitialLoop(self, bm):
     # find the first occurrence of a number in the names of vertex groups
     for g in self.obj.vertex_groups:
         g = g.name
         if g.isdigit():
             break
     # getting bottom <vb> and top <vt> vertices
     vb, vt = getVertsForVertexGroup(self.obj, bm, g)
     if vb.co.z > vt.co.z:
         vb, vt = vt, vb
     if len(vb.link_loops) == 1:
         # <vb> and <vt> are located at an open end of the finish
         loop1 = vb.link_loops[0]
     else: # len(vb.link_loops) == 2
         loop1, loop2 = vb.link_loops
         # ensure that loop1 goes horizontally
         if loop1.link_loop_next.vert == vt:
             loop1 = loop2
     return loop1
Beispiel #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
Beispiel #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)
Beispiel #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)