示例#1
0
    def create_ik_targets(self, bones):

        # Bug with iTaSC! cf http://developer.blender.org/T37894
        if bpymorse.version() < (2, 70, 0):
            if self._bpy_object.pose.ik_solver == 'ITASC':
                logger.warn("Due to a bug in Blender (T37894), only the standard " \
                            "IK solver can be used with IK targets. Switching " \
                            "from iTaSC to standard IK solver.")
                self._bpy_object.pose.ik_solver = 'LEGACY'

        for target in bones:
            posebone = self._get_posebone(target)
            bpymorse.add_morse_empty("ARROWS")
            empty = bpymorse.get_first_selected_object()
            empty.scale = [0.01, 0.01, 0.01]

            empty.matrix_local = posebone.bone.matrix_local
            empty.location = posebone.bone.tail_local

            existing_ik = [c for c in posebone.constraints if c.type == 'IK']
            if len(existing_ik) == 1:
                ik_constraint = existing_ik[0]
            elif existing_ik:
                raise MorseBuilderError("Bone %s has several IK constraints." \
                        "MORSE supports only one IK constraint per bone. Please " \
                        "remove other ones.")
            else:
                ik_constraint = posebone.constraints.new("IK")

            ik_constraint.ik_type = "DISTANCE"
            ik_constraint.use_rotation = True
            ik_constraint.use_tail = True
            ik_constraint.target = empty

            self.ik_targets.append((empty, target))
示例#2
0
    def _get_posebone(self, bone_name):
        """ Returns a given PoseBone in the armature.

        If the joint does not exist, throw an exception.
        """
        armature = self._bpy_object

        if bone_name not in [c.name for c in armature.pose.bones]:
            msg = "Joint <%s> does not exist in model %s." % (bone_name, armature.name)
            msg += " Did you add a skeleton to your model in MakeHuman?"
            raise MorseBuilderError(msg)

        return armature.pose.bones[bone_name]
示例#3
0
    def append(self, obj, child=None, level=1):
        """ Add a child to the current object

        Add the object given as an argument as a child of this object. The
        argument is an instance to another component. This method is generally
        used to add components to a robot.
        *e.g.*, : robot.append(sensor), will set the robot parent of the sensor.

        If child is not None, the object will be parented to the named
        child of self instead of the root of self.
        """
        obj._bpy_object.matrix_parent_inverse.identity()
        if child:
            _child = self.get_child(child)
            if _child:
                obj._bpy_object.parent = _child
            else:
                raise MorseBuilderError("No such child %s" % child)
        else:
            obj._bpy_object.parent = self._bpy_object
        obj.parent = self
        self.children.append(obj)

        import inspect
        try:
            frame = inspect.currentframe()
            builderscript_frame = inspect.getouterframes(frame)[level][
                0]  # parent frame
            cmpts = builderscript_frame.f_locals
            if "self" in cmpts:  #some silly guy decided to write a class to describe a silly robot
                tmp = copy.copy(cmpts["self"].__dict__)
                tmp.update(cmpts)
                cmpts = tmp

            for name, component in cmpts.items():
                if component == obj:
                    if not component.basename:  # do automatic renaming only if a name is not already manually set
                        component.basename = name

        finally:
            del builderscript_frame
            del frame
示例#4
0
    def __init__(self, name=None, armature_name=None, model_name=None):
        """ Initialize an armature

        Either `armature_name` or `model_name` or both must be specified.
        

        :param armature_name: Armature object name
        :param model_name: Armature model name, if any
        """

        if not armature_name and not model_name:
            raise MorseBuilderError("You need to specify either the name of " \
                    "an armature or a Blender model in order to create an " \
                    "armature actuator.")

        if model_name:
            ActuatorCreator.__init__(self,
                                     name,
                                     action=ComponentCreator.USE_BLEND,
                                     blendfile=model_name,
                                     blendobject=armature_name,
                                     make_morseable=True)

        else:
            ActuatorCreator.__init__(
                self,
                name,
                action=ComponentCreator.LINK_EXISTING_OBJECT,
                blendobject=armature_name,
                make_morseable=True)

        self.ik_targets = []

        # the user may have created IK constraints on the armature, without
        # setting an IK target. In that case, we add such a target
        for bone in self._bpy_object.pose.bones:
            for c in bone.constraints:
                if c.type == 'IK' and c.ik_type == 'DISTANCE':
                    if not c.target:
                        self.create_ik_targets([bone.name])