def _input_check(name, mode):
        assert mode in (None, 'all')
        assert isinstance(name, (str, list)) or name is None
        assert not (mode == 'all' and name is None)

        regex_flag = False
        regex = re.compile('[.^$*+}{|)(]')
        if isinstance(name, str):
            if regex.search(name) is not None:  # not a normal string
                name = env.Props().search(name)
                regex_flag = True

        if isinstance(name, list):  # if name is a list of regular expressions
            checked_name = []
            for this_name in name:
                if regex.search(this_name) is not None:
                    checked_name += env.Props().search(this_name)
                    regex_flag = True
                else:
                    checked_name += [this_name]
            name = list(np.unique(checked_name))
            name = [n for n in name if '/' not in n]
            if len(name) == 1:
                name = name[0]
        return name, mode, regex_flag
def readattr(names,
             frames=1,
             attrs='location',
             fname=False,
             sheet_name='animation',
             columns=('object', 'keyframe', 'attribute', 'value')):
    """
    Get location and rotation information of mesh objects from the current blender scene.
    
    Created to save weight in and weight out nutational positions of bones.
    Generalizes to saving location and rotation information for any mesh objects.

    Inputs:
        names: list of names in the blender file, ['Foot_R', 'Leg_R', 'Spine']
            each 'name' can be a blender collection, a parent object (empty), or the name of an object itself
        frames: keyframe numbers in the blender scene to grab location and rotation information from
        attrs: list of attributes ['location', 'rotation_euler', 'scale']
        fname: target file name 'somefile.xlsx'
    
    Returns:
        p: a pandas dataframe containing the name of the mesh, keyframe, location and rotation vectors
        To save contents to an excel file, supply strings to fname, and sheet_name variables

    Example:
        (load skeletalSystem.blend in blender)
        fname = 'D:\\Workspace\\blenderPython\\apps\\anatomy\\nutations.xlsx'
        p2 = bpn.io.readattr('Skeletal_Sys', [1, 100], ['location', 'rotation_euler'], fname)
    """
    if isinstance(names, str):
        names = [names]  # convert to list if a string is passed
    if isinstance(frames, int):
        frames = [frames]
    if isinstance(attrs, str):
        attrs = [attrs]

    # make sure names has only valid things in it
    names = [i for i in names if env.Props()(i)]

    p = []
    for frame in frames:
        bpy.context.scene.frame_set(frame)
        for name in names:
            thisProp = env.Props().get(name)[0]
            if isinstance(thisProp, bpy.types.Collection):
                all_objects = bpy.data.collections[name].all_objects
            elif isinstance(thisProp, bpy.types.Object):
                all_objects = env.Props().get_children(name)

            all_objects = [o for o in all_objects if o.type == 'MESH']
            for obj in all_objects:
                for attr in attrs:
                    p.append([obj.name, frame, attr, list(getattr(obj, attr))])

    p = pd.DataFrame(p, columns=list(columns))
    if isinstance(fname, str):
        p.to_excel(fname, index=False, sheet_name=sheet_name)
    return p
 def get_obj_list(obj_name):
     prop_list = env.Props().get(obj_name)
     if len(prop_list) > 1:  # multiple props detected, only keep objects
         prop_list = [
             o for o in prop_list if isinstance(o, bpy.types.Object)
         ]
     return prop_list
示例#4
0
    def __init__(self, rig_name='CircularRig', size=0.20):
        assert not env.Props().get(rig_name)
        super().__init__(rig_name)  
        self.rig_name = rig_name
        self.size = size
        
        self.targ = empty('target', 'SPHERE', size=self.size, coll_name=self.rig_name)
        self.targ.scl = size

        cam = core.Thing('Camera', 'Camera')
        self.camera = ObjectOnCircle(cam, self.rig_name, 2, self.size, self.targ)
        self.camera.scl = size

        key_light = core.Thing('Key', 'Light', 'SUN', energy=2.5, angle=0.2, color=(1., 1., 1.))
        self.key_light = ObjectOnCircle(key_light, self.rig_name, 2.5, self.size, self.targ)

        fill_light = core.Thing('Fill', 'Light', 'SUN', energy=0.2, angle=0.2, color=(1., 1., 1.))
        self.fill_light = ObjectOnCircle(fill_light, self.rig_name, 3, self.size, self.targ)

        back_light = core.Thing('Back', 'Light', 'SPOT', energy=15, spot_size=np.pi/6, spot_blend=0.15, shadow_soft_size=0.1, color=(1., 1., 1.))
        self.back_light = ObjectOnCircle(back_light, self.rig_name, 5, self.size, self.targ)

        self.key_light.theta = self.camera.theta - np.pi/4
        self.fill_light.theta = self.camera.theta + np.pi/3
        self.back_light.theta = self.camera.theta + 5*np.pi/6

        self.key_light.center = (0, 0, 0.15)
        self.fill_light.center = (0, 0, 0.15)
        self.back_light.center = (0, 0, 1)
 def _get_one_with_name(name):
     """Returns one dispatched object."""
     all_items = env.Props().get(name)
     if all_items:  # at least one item found
         all_obj_items = [
             item for item in all_items if type(item).__name__ == priority
         ]
         if all_obj_items:  # one of the items was object item
             return enhance(all_obj_items[0])
         return enhance(all_items[0])
     print('No prop found with name: ' + name)
     return []
示例#6
0
        The coordinate frame in which articulation center is specified (specifies the frame in world coordinates)
    :param articulation angle: (radians) how much to articulate that joint
    """
    for tkf in range(1, n_keyframes):
        articulation_center = trf.PointCloud(
            articulation_center_rel,
            articulation_center_frames[tkf]).in_world().co[0, :]
        progress = (tkf / n_keyframes)**1
        q = trf.Quat([1, 0, 0], articulation_angle * progress,
                     trf.CoordFrame(origin=articulation_center))
        for b in bones:
            all_frames[b.name][tkf] = q * all_frames[b.name][tkf]


# get all leg bones from the right leg
leg_bones = env.Props().get_children('Leg_Bones_R')
leg_bones = [utils.enhance(b) for b in leg_bones]

# Initialize coordinate frames for every keyframe for every bone
all_frames = {}
for bone in leg_bones:
    all_frames[bone.name] = {}
    for kf in range(n_keyframes):
        all_frames[bone.name][kf] = bone.frame  # original frame

# apply transformation around the hip joint
exc_list = ['Ilium_R']
bone_list = [b for b in leg_bones if b.name not in exc_list]
_transform_bones(bone_list, hip_articulation_center_rel_ilium,
                 all_frames['Ilium_R'], hip_articulation_angle)
def get(name=None, mode=None, priority='Object'):
    """
    Dispatcher for the bpn module.
    Takes as input the name of a prop in the blender environment.
    Returns a 'wrapped' version of the object.

    MESH bpy.types.Object - core.MeshObject
    Other bpy.types.Object - core.Object
    Prop in bpy.data.* - core.Thing
    
    bpn.obj('sphere')
    :param obj_name: (str) name of the object in blender's environment
    :param mode: (None, 'all') if 'all', returns all things with the name (priority given to objects)

    If there are objects and curves with the same name, then use
        utils.get(['x_label', 'y_label'], priority='Curve') to get the curves
        utils.get(['x_label', 'y_label']) to get the objects
        utils.get(['x_label', 'y_label'], 'all') to get both objects and curves

    Regular expressions: (With regular expression input, generic 'Thing' objects are filtered out.)
        utils.get('abe.*') to get all objects that contain 'abe'
        utils.get('abe.*', 'all') to get all items that contain 'abe'
        utils.get('^z') to get things starting with 'z'
        utils.get('^z') to get things ending with '_R'
        utils.get(['^my', '_R$']) to get things starting with my OR ending with '_R$'    

    Return all objects of a certain type:
        utils.get('collections')
    """
    def _input_check(name, mode):
        assert mode in (None, 'all')
        assert isinstance(name, (str, list)) or name is None
        assert not (mode == 'all' and name is None)

        regex_flag = False
        regex = re.compile('[.^$*+}{|)(]')
        if isinstance(name, str):
            if regex.search(name) is not None:  # not a normal string
                name = env.Props().search(name)
                regex_flag = True

        if isinstance(name, list):  # if name is a list of regular expressions
            checked_name = []
            for this_name in name:
                if regex.search(this_name) is not None:
                    checked_name += env.Props().search(this_name)
                    regex_flag = True
                else:
                    checked_name += [this_name]
            name = list(np.unique(checked_name))
            name = [n for n in name if '/' not in n]
            if len(name) == 1:
                name = name[0]
        return name, mode, regex_flag

    def _get_one_with_name(name):
        """Returns one dispatched object."""
        all_items = env.Props().get(name)
        if all_items:  # at least one item found
            all_obj_items = [
                item for item in all_items if type(item).__name__ == priority
            ]
            if all_obj_items:  # one of the items was object item
                return enhance(all_obj_items[0])
            return enhance(all_items[0])
        print('No prop found with name: ' + name)
        return []

    def _get_all_with_name(name):
        """Returns a list of dispatched objects (even if there is only one)."""
        assert isinstance(name, str)
        return [
            enhance(item) for item in env.Props().get(name) if enhance(item)
        ]

    def _dispatcher(name, mode):
        if mode is None and name is None:  # no inputs given, return the last object
            return _get_one_with_name([o.name for o in bpy.data.objects][-1])
        if mode is None and isinstance(name, str):  # return one object
            return _get_one_with_name(name)
        if mode is None and isinstance(name, list):
            return [_get_one_with_name(this_name) for this_name in name]
        if mode == 'all' and isinstance(name, str):
            return _get_all_with_name(name)
        if mode == 'all' and isinstance(
                name, list):  # here for completeness, don't recommend using it
            ret_list = []
            for this_name in name:
                ret_list += _get_all_with_name(this_name)
            return ret_list
        return []  # In theory, this statement should never be reached

    if isinstance(
            name, str
    ) and name in env.PROP_FIELDS:  # special case: return all items of a given type
        return [enhance(t) for t in env.Props()(return_empty=True)[name]]

    name, mode, regex_flag = _input_check(name, mode)
    ret_list = _dispatcher(name, mode)
    if regex_flag and isinstance(ret_list, list):
        ret_list = [o for o in ret_list if o.__class__.__name__ != 'Thing']
        if len(ret_list) == 1:  # after filtering, there was only one element
            ret_list = ret_list[0]
    return ret_list
 def _get_all_with_name(name):
     """Returns a list of dispatched objects (even if there is only one)."""
     assert isinstance(name, str)
     return [
         enhance(item) for item in env.Props().get(name) if enhance(item)
     ]