def from_face(face): min_values = Vector.Fill(3, MathUtils.VECTOR_MAX_FLOAT_VALUE) max_values = Vector.Fill(3, MathUtils.VECTOR_MIN_FLOAT_VALUE) for v in face.verts: co = v.co for i, axe_co in enumerate(co): min_values[i] = min(min_values[i], axe_co) max_values[i] = max(max_values[i], axe_co) return BBox(min_values, max_values)
def post_execute(self): out = {} if (self.inputs["Operation"].default_value == 'ADD'): out["Value"] = Vector(self.inputs["X"].default_value) + Vector( self.inputs["Y"].default_value) elif (self.inputs["Operation"].default_value == 'SUB'): out["Value"] = Vector(self.inputs["X"].default_value) - Vector( self.inputs["Y"].default_value) elif (self.inputs["Operation"].default_value == 'MULT'): out["Value"] = Vector(self.inputs["X"].default_value ) * self.inputs["K"].default_value elif (self.inputs["Operation"].default_value == 'VECTORMULT'): x_vec = Vector(self.inputs["X"].default_value) y_vec = Vector(self.inputs["Y"].default_value) out["Value"] = Vector( (x_vec.x * y_vec.x, x_vec.y * y_vec.y, x_vec.z * y_vec.z)) elif (self.inputs["Operation"].default_value == 'CROSS'): out["Value"] = Vector(self.inputs["X"].default_value).cross( Vector(self.inputs["Y"].default_value)) elif (self.inputs["Operation"].default_value == 'DOT'): out["Value"] = Vector.Fill( 3, Vector(self.inputs["X"].default_value).dot( Vector(self.inputs["Y"].default_value))) elif (self.inputs["Operation"].default_value == 'ANGLE'): out["Value"] = Vector.Fill( 3, Vector(self.inputs["X"].default_value).angle( Vector(self.inputs["Y"].default_value))) elif (self.inputs["Operation"].default_value == 'PROJ'): out["Value"] = Vector(self.inputs["X"].default_value).project( Vector(self.inputs["Y"].default_value)) elif (self.inputs["Operation"].default_value == 'REFL'): out["Value"] = Vector(self.inputs["X"].default_value).reflect( Vector(self.inputs["Y"].default_value)) elif (self.inputs["Operation"].default_value == 'ROT'): out["Value"] = Vector( self.inputs["X"].default_value).rotation_difference( Vector(self.inputs["Y"].default_value)).to_euler() elif (self.inputs["Operation"].default_value == 'NORM'): out["Value"] = Vector(self.inputs["X"].default_value).normalized() elif (self.inputs["Operation"].default_value == 'ORTHO'): out["Value"] = Vector(self.inputs["X"].default_value).orthogonal() elif (self.inputs["Operation"].default_value == 'LERP'): out["Value"] = Vector(self.inputs["X"].default_value).lerp( Vector(self.inputs["Y"].default_value), self.inputs["K"].default_value) elif (self.inputs["Operation"].default_value == 'SLERP'): out["Value"] = Vector(self.inputs["X"].default_value).slerp( Vector(self.inputs["Y"].default_value), self.inputs["K"].default_value) return out
def average_locations(locationslist, size=3): avg = Vector.Fill(size) for n in locationslist: avg += n return avg / len(locationslist)
def orthogonal(v): # Vector.orthogonal isn't present in 2.70 size = len(v) v = (Vector((v[0], v[1], 0.0)) if size == 2 else Vector(v)) if v.length_squared < 1e-8: return Vector.Fill(size) ort = Vector((0, 0, 1)).cross(v).normalized() if ort.length_squared < 0.5: ort = Vector((0, 1, 0)).cross(v).normalized() return (ort.to_2d() if size == 2 else ort)
def orthogonal(v, never_zero=False): # Note: Vector.orthogonal() is not guaranteed to lie in XY plane if (not never_zero) and (v.length_squared < 1e-16): return Vector.Fill(len(v)) v = v.normalized() if len(v) == 2: return Vector((-v[1], v[0])) ort = Vector((0, 0, 1)).cross(v).normalized() return (ort if ort.length_squared > 0.5 else Vector((1, 0, 0)))
def __init__(self, old_owner): types.KX_GameObject.__init__(self) #render.showMouse(True) logic.mouse.position = .5, .5 self.phys_id = self.getPhysicsId() self.head = self.foot = None for c in self.children: if "HEAD" in c: self.head = c elif "FOOT" in c: self.foot = c self.walk_direction = Vector.Fill(3, .0) self.jumping = False
def unify_targets(target_objects): context = global_functions.ctx() buckets = [] for anchor in target_objects: if len(buckets) == 0: buckets.append(Bucket(anchor.name, anchor.side, BucketItem(anchor))) continue for b in buckets: if b.name == anchor.name and b.side == anchor.side: b.items.append(BucketItem(anchor)) continue buckets.append(Bucket(anchor.name, anchor.side, BucketItem(anchor))) proxies = [] for b in buckets: total_loc = Vector.Fill(3) total_weight = 0 for val in b.items: total_loc += val.value.matrix.translation total_weight += 1 if not total_weight == 0: total_loc /= total_weight proxies.append( AnchorProxy(fav=False, lock=True, name=b.name, side=b.side, matrix=Matrix.Translation(total_loc))) return proxies
def execute(self, frame, frequency): if self.frameType == "OFFSET": frame += bpy.context.scene.frame_current strengths = Vector.Fill(strengthListLength, 0) for i, channelStrength in enumerate(self.channels): if channelStrength > 0: if frame == int(frame): strengthList = sequencerData.getChannelStrengthList( channel=i + 1, frame=frame) else: # for motion blur / subframes strengthList1 = sequencerData.getChannelStrengthList( channel=i + 1, frame=int(frame)) strengthList2 = sequencerData.getChannelStrengthList( channel=i + 1, frame=int(frame) + 1) influence = frame % 1 strengthList = strengthList1 * ( 1 - influence) + strengthList2 * influence strengths += strengthList * channelStrength strength = self.getFrequencyStrength(strengths, frequency) return strength, list(strengths)
def insertMissingFrames(self, endFrame): if endFrame >= len(self.frames): for i in range(endFrame - len(self.frames) + 1): self.frames.append(Vector.Fill(strengthListLength, 0))
def getStrengthList(self, frame): if frame < len(self.frames): return self.frames[frame] return Vector.Fill(strengthListLength, 0)
def getChannelStrengthList(self, channel, frame): frame = int(frame) if channel in self.channels: return self.channels[channel].getStrengthList(frame) return Vector.Fill(strengthListLength, 0)
class CoordSystemMatrix: def __init__(self, coordsys=None, sv=None, context=None): self.update(coordsys, sv, context) def __coordsys_get(self, coordsys, aspect): aspect = coordsys.get(aspect) if aspect is None: return ('GLOBAL', "", "") elif isinstance(aspect, str): return (aspect, "", "") elif len(aspect) == 1: return (aspect[0], "", "") elif len(aspect) == 2: return (aspect[0], aspect[1], "") else: return (aspect[0], aspect[1], aspect[2]) def _interpret_coordsys_dict(self, coordsys): self.L = self.__coordsys_get(coordsys, "L") self.R = self.__coordsys_get(coordsys, "R") self.S = self.__coordsys_get(coordsys, "S") self.extra_matrix = coordsys.get("extra_matrix") or Matrix() def _interpret_coordsys_pg(self, coordsys): aspect = coordsys.aspect_L self.L = (aspect.mode, aspect.obj_name, aspect.bone_name) aspect = coordsys.aspect_R self.R = (aspect.mode, aspect.obj_name, aspect.bone_name) aspect = coordsys.aspect_S self.S = (aspect.mode, aspect.obj_name, aspect.bone_name) self.extra_matrix = coordsys.extra_matrix def _interpret_coordsys_str(self, L='GLOBAL', R='GLOBAL', S='GLOBAL'): self.L = (L, "", "") self.R = (R, "", "") self.S = (S, "", "") self.extra_matrix = Matrix() def _interpret_coordsys(self, coordsys, context): if isinstance(coordsys, dict): self._interpret_coordsys_dict(coordsys) elif isinstance(coordsys, str): if coordsys == 'NORMAL': self._interpret_coordsys_str('MEAN', 'NORMAL') elif coordsys == 'MANIPULATOR': self._interpret_coordsys_str('PIVOT', 'ORIENTATION') elif coordsys == 'CURRENT': if context is None: context = bpy.context manager = get_coordsystem_manager(context) self._interpret_coordsys(manager.current, context) else: self._interpret_coordsys_str(coordsys, coordsys, coordsys) elif coordsys: # CoordSystemPG self._interpret_coordsys_pg(coordsys) else: self._interpret_coordsys_str() def update(self, coordsys, sv=None, context=None): self._interpret_coordsys(coordsys, context) self.context = context self.calc_active_xyzt(context) if (sv is None) and context: ui_context = self.find_ui_context(context) if ui_context: sv = SmartView3D(use_camera_axes=True, **ui_context) self.sv = sv self.vm, self.vp = self.calc_view_matrix() # Cached values are the same for any object/element self._cached_all = None self._cached_t = None self._cached_xyz = None self._cached_s = None # The "basis" location/rotation/scale can be used with objects and pose-bones # (they have the same the transform-related attributes, even locks!) # Meta-elements have pos/rot/scale too, but nothing more advanced. # However, meta-elements can also be coerced to the same behavior, to some extent def calc_view_matrix(self): if not self.sv: return (Matrix(), Vector((1, 1, 0))) m = matrix_compose(self.sv.right, self.sv.up, self.sv.forward, self.sv.viewpoint) m3 = m.to_3x3() s, d = self.sv.projection_info p = Vector((2.0 / s.x, 2.0 / s.y, s.z)).lerp(Vector((2.0 * d.z / s.x, 2.0 * d.z / s.y, s.z)), s.z) x = m3 * Vector((1, 0, 0)) y = m3 * Vector((0, 1, 0)) z = m3 * Vector( (d.x, d.y, 1.0)).lerp(Vector((d.x / d.z, d.y / d.z, 1.0)), s.z) t = m.translation return (matrix_compose(x, y, -z, t), p) def calc_cam_matrix(self, context, cam_name): scene = context.scene cam_obj = scene.objects.get(cam_name, scene.camera) if (not cam_obj) or (not cam_obj.data): return (Matrix(), Vector((1, 1, 0))) m = Matrix(cam_obj.matrix_world) m.col[0] *= (1.0 / m.col[0].magnitude) m.col[1] *= (1.0 / m.col[1].magnitude) m.col[2] *= -(1.0 / m.col[2].magnitude) m3 = m.to_3x3() s, d = BlUtil.Camera.projection_info(cam_obj.data, context.scene) p = Vector((2.0 / s.x, 2.0 / s.y, s.z)).lerp(Vector((2.0 * d.z / s.x, 2.0 * d.z / s.y, s.z)), s.z) x = m3 * Vector((1, 0, 0)) y = m3 * Vector((0, 1, 0)) z = m3 * Vector( (d.x, d.y, 1.0)).lerp(Vector((d.x / d.z, d.y / d.z, 1.0)), s.z) t = m.translation return (matrix_compose(x, y, -z, t), p) def calc_active_matrix(self, context): if context.mode == 'EDIT_METABALL': elem = context.active_object.data.elements.active return BlUtil.Object.matrix_world(ObjectEmulator_Meta(elem)) elif context.mode == 'POSE': return BlUtil.Object.matrix_world(context.active_pose_bone) else: return BlUtil.Object.matrix_world(context.active_object) def _xyzt_t(self, m, xyzt): if (xyzt is None) or (xyzt[3] is None): t = m.translation else: t = m * Vector(xyzt[3]) return t def _xyzt_xyz(self, m, xyzt): if xyzt is None: xyz = m.col[:3] else: x, y, z = xyzt[0], xyzt[1], xyzt[2] if (x is None) and (y is None) and (z is None): xyz = m.col[:3] else: m3 = m.to_3x3() if x is not None: x = m3 * Vector(x) if y is not None: y = m3 * Vector(y) if z is not None: z = m3 * Vector(z) xyz = orthogonal_XYZ(x, y, z, "z") return xyz def _xyzt_s(self, m, xyzt): if xyzt is None: s = m.to_scale() else: s = Vector((1, 1, 1)) return s def _gimbal_xyz(self, context, am): rotobj = (context.active_pose_bone if context.mode == 'POSE' else None) or context.active_object if (not rotobj) or (rotobj.rotation_mode == 'QUATERNION'): if not am: am = self.calc_active_matrix(context) xyz = am.col[:3] elif rotobj.rotation_mode == 'AXIS_ANGLE': aa = rotobj.rotation_axis_angle z = Vector(aa[1:]).normalized() q = Vector((0, 0, 1)).rotation_difference(z) x = (q * Vector((1, 0, 0))).normalized() y = z.cross(x) else: e = rotobj.rotation_euler m = Matrix.Identity(3) for e_ax in rotobj.rotation_mode: m = Matrix.Rotation(getattr(e, e_ax.lower()), 3, e_ax) * m x, y, z = m.col[:3] if not xyz: m = BlUtil.Object.matrix_parent(rotobj) x.rotate(m) y.rotate(m) z.rotate(m) xyz = x, y, z return xyz # The actual implementations are substituted other modules get_coord_summary = staticmethod( lambda summary, dflt: Vector.Fill(3, dflt)) get_normal_summary = staticmethod(lambda summary: Vector((0, 0, 1))) find_ui_context = staticmethod(lambda context: None) workplane_matrix = staticmethod(lambda context, scaled: Matrix()) _pivot_map = { 'BOUNDING_BOX_CENTER': 'CENTER', 'CURSOR': 'CURSOR', 'INDIVIDUAL_ORIGINS': 'INDIVIDUAL', 'MEDIAN_POINT': 'MEAN', 'ACTIVE_ELEMENT': 'ACTIVE', } _orientation_map = { 'GLOBAL': 'GLOBAL', 'LOCAL': 'ACTIVE', 'NORMAL': 'NORMAL', 'GIMBAL': 'GIMBAL', 'VIEW': 'VIEW', } _orientation_map_edit = { 'GLOBAL': 'GLOBAL', 'LOCAL': 'LOCAL', 'NORMAL': 'NORMAL', 'GIMBAL': 'GIMBAL', 'VIEW': 'VIEW', } def calc_matrix(self, context, obj, local_xyzt=None): if self._cached_all: return self._cached_all persp = Vector((1, 1, 0)) pm = None lm = None am = None wplm = None L_mode = self.L[0] # Note: in POSE mode the manipulator is displayed only at the root selected bone, active bone or cursor, # and rotation always happens around the base of the root selected bone if L_mode == 'PIVOT': L_mode = self._pivot_map[self.sv.space_data.pivot_point] t = self._cached_t if not t: if L_mode == 'LOCAL': if self.active_xyzt: # in mesh/curve/lattice/bone edit modes, treat active object as parent if not am: am = self.calc_active_matrix(context) t = am.translation self._cached_t = t else: if not pm: pm = BlUtil.Object.matrix_parent(obj) t = pm.translation elif L_mode == 'PARENT': if not pm: pm = BlUtil.Object.matrix_parent(obj) t = pm.translation elif L_mode == 'INDIVIDUAL': if not lm: lm = BlUtil.Object.matrix_world(obj) t = self._xyzt_t(lm, local_xyzt) elif L_mode == 'ACTIVE': if not am: am = self.calc_active_matrix(context) t = self._xyzt_t(am, self.active_xyzt) self._cached_t = t elif L_mode == 'OBJECT': _obj = (context.scene.objects.get(self.L[1]) if self.L[1] else context.active_object) om = BlUtil.Object.matrix_world(_obj, self.L[2]) t = om.translation self._cached_t = t elif L_mode == 'CAMERA': cm, persp = self.calc_cam_matrix(context, self.L[1]) t = cm.translation self._cached_t = t elif L_mode == 'VIEW': vm, persp = self.vm, self.vp t = vm.translation self._cached_t = t elif L_mode == 'WORKPLANE': if not wplm: wplm = self.workplane_matrix(context, True) t = wplm.translation self._cached_t = t elif L_mode == 'CURSOR': t = Vector((self.sv.space_data if self.sv else context.scene).cursor_location) self._cached_t = t elif L_mode in ('MEAN', 'CENTER', 'MIN', 'MAX'): t = self.get_coord_summary(L_mode.lower(), 0.0) self._cached_t = t else: # GLOBAL, and fallback for some others t = Vector() self._cached_t = t S_mode = self.S[0] s = self._cached_s if not s: if S_mode == 'LOCAL': if self.active_xyzt: # in mesh/curve/lattice/bone edit modes, treat active object as parent if not am: am = self.calc_active_matrix(context) s = am.to_scale() self._cached_s = s else: if not pm: pm = BlUtil.Object.matrix_parent(obj) s = pm.to_scale() elif S_mode == 'PARENT': if not pm: pm = BlUtil.Object.matrix_parent(obj) s = pm.to_scale() elif S_mode == 'INDIVIDUAL': if not lm: lm = BlUtil.Object.matrix_world(obj) s = self._xyzt_s(lm, local_xyzt) elif S_mode == 'ACTIVE': if not am: am = self.calc_active_matrix(context) s = self._xyzt_s(am, self.active_xyzt) self._cached_s = s elif S_mode == 'OBJECT': _obj = (context.scene.objects.get(self.S[1]) if self.S[1] else context.active_object) om = BlUtil.Object.matrix_world(_obj, self.S[2]) s = om.to_scale() self._cached_s = s elif S_mode == 'CAMERA': cm = self.calc_cam_matrix(context, self.S[1])[0] s = cm.to_scale() self._cached_s = s elif S_mode == 'VIEW': vm = self.vm s = vm.to_scale() self._cached_s = s elif S_mode == 'WORKPLANE': if not wplm: wplm = self.workplane_matrix(context, True) s = wplm.to_scale() self._cached_s = s elif S_mode in ('RANGE', 'STDDEV'): s = self.get_coord_summary(S_mode.lower(), 1.0) self._cached_s = s else: # GLOBAL, and fallback for some others s = Vector((1, 1, 1)) self._cached_s = s # R is calculated after S for slight convenience of calculating Gimbal R_mode = self.R[0] if R_mode == 'ORIENTATION': v3d = self.sv.space_data ormap = (self._orientation_map_edit if context.mode.startswith('EDIT') else self._orientation_map) if not v3d.current_orientation: R_mode = ormap.get(v3d.transform_orientation, v3d.transform_orientation) xyz = self._cached_xyz if not xyz: if R_mode == 'LOCAL': if self.active_xyzt: # in mesh/curve/lattice/bone edit modes, treat active object as parent if not am: am = self.calc_active_matrix(context) xyz = am.col[:3] self._cached_xyz = xyz else: if not pm: pm = BlUtil.Object.matrix_parent(obj) xyz = pm.col[:3] elif R_mode == 'PARENT': if not pm: pm = BlUtil.Object.matrix_parent(obj) xyz = pm.col[:3] elif R_mode == 'INDIVIDUAL': if not lm: lm = BlUtil.Object.matrix_world(obj) xyz = self._xyzt_xyz(lm, local_xyzt) elif R_mode == 'ACTIVE': if not am: am = self.calc_active_matrix(context) xyz = self._xyzt_xyz(am, self.active_xyzt) self._cached_xyz = xyz elif R_mode == 'OBJECT': _obj = (context.scene.objects.get(self.R[1]) if self.R[1] else context.active_object) om = BlUtil.Object.matrix_world(_obj, self.R[2]) xyz = om.col[:3] self._cached_xyz = xyz elif R_mode == 'CAMERA': cm = self.calc_cam_matrix(context, self.R[1])[0] xyz = cm.col[:3] self._cached_xyz = xyz elif R_mode == 'VIEW': vm = self.vm xyz = vm.col[:3] self._cached_xyz = xyz elif R_mode == 'WORKPLANE': if not wplm: wplm = self.workplane_matrix(context, True) xyz = wplm.col[:3] self._cached_xyz = xyz elif R_mode == 'NORMAL': nm = self.get_normal_summary("mean") xyz = nm.col[:3] self._cached_xyz = xyz elif R_mode == 'GIMBAL': xyz = self._gimbal_xyz(context, am) self._cached_xyz = xyz elif R_mode == 'ORIENTATION': v3d = self.sv.space_data m = v3d.current_orientation.matrix xyz = m.col[:3] self._cached_xyz = xyz else: # GLOBAL, and fallback for some others xyz = Vector((1, 0, 0)), Vector((0, 1, 0)), Vector((0, 0, 1)) self._cached_xyz = xyz x = s.x * xyz[0].to_3d().normalized() y = s.y * xyz[1].to_3d().normalized() z = s.z * xyz[2].to_3d().normalized() self.__base_matrix = matrix_compose(x, y, z, t) final_matrix = self.__base_matrix * self.extra_matrix res = (L_mode, R_mode, S_mode, final_matrix, persp) if self._cached_t and self._cached_xyz and self._cached_s: self._cached_all = res return res def base_matrix(self, context=None, obj=None): self.calc_matrix(context or self.context, obj) return self.__base_matrix def final_matrix(self, context=None, obj=None): L_mode, R_mode, S_mode, to_m, persp = self.calc_matrix( context or self.context, obj) return to_m def get_LRS(self, context, obj, rotation_mode='QUATERNION', rotation4=False): L_mode, R_mode, S_mode, to_m, persp = self.calc_matrix(context, obj) in_m = matrix_inverted_safe(to_m) * BlUtil.Object.matrix_world(obj) if L_mode == 'BASIS': L = Vector(obj.location) elif L_mode == 'INDIVIDUAL': L = Vector() else: L = in_m.translation if L_mode in ('CAMERA', 'VIEW'): inv_z = ((1.0 / abs(L.z)) if L.z != 0.0 else 1.0) L = Vector((L.x * persp.x, L.y * persp.y, -L.z)).lerp( Vector( (L.x * inv_z * persp.x, L.y * inv_z * persp.y, -L.z)), persp.z) if R_mode == 'BASIS': R = BlUtil.Object.rotation_convert(obj.rotation_mode, obj.rotation_quaternion, obj.rotation_axis_angle, obj.rotation_euler, rotation_mode, rotation4) elif R_mode == 'INDIVIDUAL': R = BlUtil.Object.rotation_convert('QUATERNION', Quaternion((1, 0, 0, 0)), None, None, rotation_mode, rotation4) else: R = BlUtil.Object.rotation_convert('QUATERNION', in_m.to_quaternion(), None, None, rotation_mode, rotation4) if S_mode == 'BASIS': S = Vector(obj.scale) elif S_mode == 'INDIVIDUAL': S = Vector((1, 1, 1)) else: S = in_m.to_scale() return (L, R, S) def set_LRS(self, context, obj, LRS, rotation_mode='QUATERNION'): L, R, S = LRS L_mode, R_mode, S_mode, to_m, persp = self.calc_matrix(context, obj) mL = (L is not None) and (L_mode != 'BASIS') mR = (R is not None) and (R_mode != 'BASIS') mS = (S is not None) and (S_mode != 'BASIS') if mL or mR or mS: in_m = matrix_inverted_safe(to_m) * BlUtil.Object.matrix_world(obj) if not mL: in_L = in_m.to_translation() else: L = Vector(L) # make sure it's a Vector if L_mode in ('CAMERA', 'VIEW'): L = Vector((L.x / persp.x, L.y / persp.y, -L.z)).lerp( Vector( (L.x * L.z / persp.x, L.y * L.z / persp.y, -L.z)), persp.z) in_L = L L = None if not mR: in_R = in_m.to_quaternion() if not R: rotation_mode = obj.rotation_mode else: if rotation_mode == 'QUATERNION': in_R = Quaternion(R) elif rotation_mode == 'AXIS_ANGLE': in_R = Quaternion(R[1:], R[0]) else: if (len(R) == 4): R = R[1:] in_R = Euler(R).to_quaternion() R = None if not mS: in_S = in_m.to_scale() else: in_S = Vector(S) S = None x, y, z = in_R.normalized().to_matrix().col in_m = matrix_compose(x * in_S.x, y * in_S.y, z * in_S.z, in_L) BlUtil.Object.matrix_world_set(obj, to_m * in_m) if (not mL) and (not L): L = Vector(obj.location) if (not mR) and (not R): R = BlUtil.Object.rotation_convert(obj.rotation_mode, obj.rotation_quaternion, obj.rotation_axis_angle, obj.rotation_euler, rotation_mode) if (not mS) and (not S): S = Vector(obj.scale) if L: obj.location = Vector(L) if R: BlUtil.Object.rotation_apply(obj, R, rotation_mode) if S: obj.scale = Vector(S) _last_obj_hash = 0 _last_obj_matrix = None _last_obj_matrix_inv = None active_xyzt = None # supposed to be assigned directly by the using code def calc_active_xyzt(self, context=None): if context is None: context = bpy.context mode = context.mode self.active_xyzt = None if not context.object: return if mode == 'EDIT_ARMATURE': obj = context.object.data.edit_bones.active if obj: self.active_xyzt = (Vector(obj.x_axis), Vector(obj.y_axis), Vector(obj.z_axis), Vector(obj.head)) else: self.active_xyzt = (Vector((1, 0, 0)), Vector( (0, 1, 0)), Vector((0, 0, 1)), Vector()) elif mode == 'EDIT_MESH': bm = bmesh.from_edit_mesh(context.object.data) history = bm.select_history obj = (history[len(history) - 1] if history else bm.faces.active) if obj: if isinstance(obj, bmesh.types.BMVert): co = Vector(obj.co) normal = Vector(obj.normal) self.active_xyzt = (None, None, normal, co) elif isinstance(obj, bmesh.types.BMEdge): verts = tuple(obj.verts) co0 = Vector(verts[0].co) co1 = Vector(verts[1].co) self.active_xyzt = (None, None, (co1 - co0) * 0.5, (co1 + co0) * 0.5) elif isinstance(obj, bmesh.types.BMFace): verts = tuple(obj.verts) center = sum( (Vector(v.co) for v in verts), Vector()) * (1.0 / len(verts)) normal = Vector(obj.normal) self.active_xyzt = (None, None, normal, center) else: self.active_xyzt = (Vector((1, 0, 0)), Vector( (0, 1, 0)), Vector((0, 0, 1)), Vector()) elif mode == 'EDIT_LATTICE': self.active_xyzt = (Vector((1, 0, 0)), Vector( (0, 1, 0)), Vector( (0, 0, 1)), Vector()) # no API for active vertex elif mode in {'EDIT_CURVE', 'EDIT_SURFACE'}: self.active_xyzt = (Vector((1, 0, 0)), Vector( (0, 1, 0)), Vector( (0, 0, 1)), Vector()) # no API for active vertex def coord_to_L(self, context, obj, coord, local_xyzt=None): obj_hash = (0 if obj is None else obj.as_pointer()) if (self._last_obj_matrix is None) or (obj_hash != self._last_obj_hash): self._last_obj_hash = obj_hash self._last_obj_matrix = BlUtil.Object.matrix_world(obj) L_mode = self.L[0] if L_mode == 'BASIS': L = Vector(coord) elif L_mode == 'INDIVIDUAL': L = Vector() else: L_mode, R_mode, S_mode, to_m, persp = self.calc_matrix( context, obj, local_xyzt) L = matrix_inverted_safe(to_m) * (self._last_obj_matrix * Vector(coord)) if L_mode in ('CAMERA', 'VIEW'): inv_z = ((1.0 / abs(L.z)) if L.z != 0.0 else 1.0) L = Vector((L.x * persp.x, L.y * persp.y, -L.z)).lerp( Vector( (L.x * inv_z * persp.x, L.y * inv_z * persp.y, -L.z)), persp.z) return L def coord_from_L(self, context, obj, L, local_xyzt=None): obj_hash = (0 if obj is None else obj.as_pointer()) if (self._last_obj_matrix_inv is None) or (obj_hash != self._last_obj_hash): self._last_obj_hash = obj_hash self._last_obj_matrix_inv = matrix_inverted_safe( BlUtil.Object.matrix_world(obj)) L = Vector(L) L_mode = self.L[0] if L_mode == 'BASIS': coord = L else: L_mode, R_mode, S_mode, to_m, persp = self.calc_matrix( context, obj, local_xyzt) if L_mode in ('CAMERA', 'VIEW'): L = Vector((L.x / persp.x, L.y / persp.y, -L.z)).lerp( Vector((L.x * L.z / persp.x, L.y * L.z / persp.y, -L.z)), persp.z) coord = self._last_obj_matrix_inv * (to_m * L) return coord @staticmethod def current(context=None): if context is None: context = bpy.context manager = get_coordsystem_manager(context) return CoordSystemMatrix(manager.current, context=context) @staticmethod def custom(name, context=None): if context is None: context = bpy.context manager = get_coordsystem_manager(context) coordsys = manager.coordsystems.get(name) return CoordSystemMatrix(coordsys, context=context)
def center_of_mass(vertices): center = Vector.Fill(3) for v in vertices: center += v.co center /= len(vertices) return center
def execute(self, context): if any([self.rotation, self.scale]): decalmachine, _, _, _ = get_addon("DECALmachine") # only apply the scale to objects, that arent't parented themselves apply_objs = [obj for obj in context.selected_objects if not obj.parent] for obj in apply_objs: # fetch children and their current world mx children = [(child, child.matrix_world) for child in obj.children] mx = obj.matrix_world loc, rot, sca = mx.decompose() # apply the current transformations on the mesh level bm = bmesh.new() bm.from_mesh(obj.data) bm.normal_update() bm.verts.ensure_lookup_table() if self.rotation and self.scale: bmmx = get_rot_matrix(rot) @ get_sca_matrix(sca) elif self.rotation: bmmx = get_rot_matrix(rot) elif self.scale: bmmx = get_sca_matrix(sca) bmesh.ops.transform(bm, matrix=bmmx, verts=bm.verts) bm.to_mesh(obj.data) bm.clear() # zero out the transformations on the object level if self.rotation and self.scale: applymx = get_loc_matrix(loc) @ get_rot_matrix(Quaternion()) @ get_sca_matrix(Vector.Fill(3, 1)) elif self.rotation: applymx = get_loc_matrix(loc) @ get_rot_matrix(Quaternion()) @ get_sca_matrix(sca) elif self.scale: applymx = get_loc_matrix(loc) @ get_rot_matrix(rot) @ get_sca_matrix(Vector.Fill(3, 1)) obj.matrix_world = applymx # adjust the bevel width values accordingly if self.scale: mods = [mod for mod in obj.modifiers if mod.type == "BEVEL"] for mod in mods: vwidth = get_sca_matrix(sca) @ Vector((0, 0, mod.width)) mod.width = vwidth[2] # reset the children to their original state again for obj, mxw in children: obj.matrix_world = mxw # update decal backups's backup matrices as well, we can just reuse the bmesh mx here if decalmachine and obj.DM.decalbackup: backup = obj.DM.decalbackup backup.DM.backupmx = flatten_matrix(bmmx @ backup.DM.backupmx) return {'FINISHED'}
def identity_transform(obj: 'Object'): obj.location = _Vector.Fill(3, 0.0) obj.rotation_mode = 'QUATERNION' obj.rotation_quaternion = _Quaternion() obj.scale = _Vector.Fill(3, 1.0)
def __init__(self, r: Quaternion = Quaternion(), t: Vector = Vector.Fill(3), s: Vector = Vector.Fill(3, 1.0)): self.r = r self.t = t self.s = s