Example #1
0
    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)
Example #2
0
 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
Example #3
0
def average_locations(locationslist, size=3):
    avg = Vector.Fill(size)

    for n in locationslist:
        avg += n

    return avg / len(locationslist)
Example #4
0
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)
Example #5
0
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
Example #7
0
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)
Example #12
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
Example #14
0
    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'}
Example #15
0
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