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
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
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
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
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)
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)