コード例 #1
0
ファイル: faceshift.py プロジェクト: SyedShaQutub/VPS_System
def faceshiftBvhLoad(filepath, useHead, context):
    rig = context.object
    readingBlendShapes = False
    readingMotion = False
    isFaceshift13 = False
    firstUnknown = ""

    props = {}
    bones = {}
    pmotion = {}
    bmotion = {}
    idx = 0
    R = math.pi / 180
    with open(filepath) as fp:
        for line in fp:
            words = line.split()
            if len(words) == 0:
                continue
            elif readingMotion:
                for idx, bone in bones.items():
                    angles = [float(words[idx + n]) * R for n in range(3, 6)]
                    euler = Euler(angles, 'ZXY')
                    bmotion[bone].append(euler)
                for idx, prop in props.items():
                    strength = float(words[idx + 5]) / 90.0
                    pmotion[prop].append(strength)
            else:
                key = words[0]
                if key == "JOINT":
                    joint = words[1]
                    idx += 6
                    if readingBlendShapes:
                        try:
                            prop = "Mfa%s" % FaceShiftShapes[joint]
                        except KeyError:
                            if firstUnknown == "":
                                firstUnknown = joint
                            if joint == "LipsTogether":
                                isFaceshift13 = True
                        props[idx] = prop
                        pmotion[prop] = []
                    elif joint == "Blendshapes":
                        readingBlendShapes = True
                    elif useHead:
                        try:
                            bnames = FaceShiftBones[joint]
                        except KeyError:
                            bnames = []
                        for bname in bnames:
                            try:
                                bone = rig.data.bones[bname]
                            except:
                                bone = None
                            if bone:
                                bones[idx] = bname
                                bmotion[bname] = []
                elif key == "MOTION":
                    if not readingBlendShapes:
                        raise MhxError("This is not a FaceShift BVH file")
                    readingBlendShapes = False
                elif key == "Frame":
                    readingMotion = True

    if isFaceshift13:
        warning = ("Warning: This seems to be a Faceshift 1.3 file.\n" +
                   "MHX2 only supports Faceshift 1.2 and lower.")
    elif firstUnknown:
        warning = (
            "Warning: This does not seem to be a Faceshift BVH file.\n" +
            "First unknown shape: %s" % firstUnknown)
    else:
        warning = ""

    return bmotion, pmotion, warning
コード例 #2
0
    def draw(self):
        verts = self.get_verts()
        lleft = min(verts, key=lambda v: v[0])[0]
        lright = max(verts, key=lambda v: v[0])[0]

        bleft = self.light_image.panel.point_lt[0]
        bright = self.light_image.panel.point_rb[0]

        from mathutils import Euler
        rot_translate = Vector((self.weight, 0, 0))
        rot_translate.rotate(Euler((0, 0, self.rot)))
        rot_translate_ort = Vector((-rot_translate.y, rot_translate.x))

        #       0   1
        # 0  lt.x, lt.y         0 2
        # 1  lt.x, rb.y         1 3
        # 2  rb.x, lt.y
        # 3  rb.x, rb.y

        left_verts = [
            verts[0], verts[1],
            [verts[0][0] + rot_translate.x, verts[0][1] + rot_translate.y],
            [verts[1][0] + rot_translate.x, verts[1][1] + rot_translate.y]
        ]

        right_verts = [[
            verts[2][0] - rot_translate.x, verts[2][1] - rot_translate.y
        ], [verts[3][0] - rot_translate.x, verts[3][1] - rot_translate.y],
                       verts[2], verts[3]]

        top_verts = [
            verts[0],
            [
                verts[0][0] - rot_translate_ort.x,
                verts[0][1] - rot_translate_ort.y
            ], verts[2],
            [
                verts[2][0] - rot_translate_ort.x,
                verts[2][1] - rot_translate_ort.y
            ]
        ]

        bottom_verts = [[
            verts[1][0] + rot_translate_ort.x,
            verts[1][1] + rot_translate_ort.y
        ], verts[1],
                        [
                            verts[3][0] + rot_translate_ort.x,
                            verts[3][1] + rot_translate_ort.y
                        ], verts[3]]

        border_shader2Dcolor.bind()
        bgl.glEnable(bgl.GL_BLEND)
        border_shader2Dcolor.uniform_float("color", self.color)
        border_shader2Dcolor.uniform_float("panel_point_lt",
                                           self.light_image.panel.point_lt)
        border_shader2Dcolor.uniform_float("panel_point_rb",
                                           self.light_image.panel.point_rb)
        if lleft < bleft:
            left_verts2 = deepcopy(left_verts)
            for v in left_verts2:
                v[0] += self.light_image.panel.width

            right_verts2 = deepcopy(right_verts)
            for v in right_verts2:
                v[0] += self.light_image.panel.width

            top_verts2 = deepcopy(top_verts)
            for v in top_verts2:
                v[0] += self.light_image.panel.width

            bottom_verts2 = deepcopy(bottom_verts)
            for v in bottom_verts2:
                v[0] += self.light_image.panel.width

            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": left_verts2
            }).draw(border_shader2Dcolor)
            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": right_verts2
            }).draw(border_shader2Dcolor)
            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": top_verts2
            }).draw(border_shader2Dcolor)
            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": bottom_verts2
            }).draw(border_shader2Dcolor)
        elif lright > bright:
            left_verts2 = deepcopy(left_verts)
            for v in left_verts2:
                v[0] -= self.light_image.panel.width

            right_verts2 = deepcopy(right_verts)
            for v in right_verts2:
                v[0] -= self.light_image.panel.width

            top_verts2 = deepcopy(top_verts)
            for v in top_verts2:
                v[0] -= self.light_image.panel.width

            bottom_verts2 = deepcopy(bottom_verts)
            for v in bottom_verts2:
                v[0] -= self.light_image.panel.width

            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": left_verts2
            }).draw(border_shader2Dcolor)
            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": right_verts2
            }).draw(border_shader2Dcolor)
            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": top_verts2
            }).draw(border_shader2Dcolor)
            batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
                "pos": bottom_verts2
            }).draw(border_shader2Dcolor)

        batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
            "pos": left_verts
        }).draw(border_shader2Dcolor)
        batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
            "pos": right_verts
        }).draw(border_shader2Dcolor)
        batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
            "pos": top_verts
        }).draw(border_shader2Dcolor)
        batch_for_shader(border_shader2Dcolor, 'TRI_STRIP', {
            "pos": bottom_verts
        }).draw(border_shader2Dcolor)
        bgl.glDisable(bgl.GL_BLEND)
コード例 #3
0
def FrameMatrix(f):
    t = Matrix.Translation(Vector((f.t.x, f.t.y, f.t.z)))
    r = Euler((f.rx, f.ry, f.rz), 'XYZ').to_matrix().to_4x4()
    res = t * r
    return res
コード例 #4
0
    def cache_poses(self):
        default_transform = Transform(
        )  # Ref pose used to determine if a transform is significant
        pose_transforms = []  # List of bonename->transform maps

        for marker in self.pose_lib.pose_markers:
            transforms = {}
            curves = {}
            euler_rotations = {}
            pose_transforms.append(transforms)

            for fcurve in self.pose_lib.fcurves:
                match_pb = re.match(r'^pose\.bones\["(.+)"\]\.(\w+)$',
                                    fcurve.data_path)
                if match_pb:
                    # Handle bone curves
                    bone_name = match_pb[1]
                    data_elem = match_pb[2]
                    data_idx = fcurve.array_index
                    data_value = fcurve.evaluate(marker.frame)

                    transform = transforms.get(bone_name)
                    if not transform:
                        transforms[
                            bone_name] = transform = default_transform.copy()

                    if data_elem == 'location':
                        transform.location[data_idx] = data_value
                    elif data_elem == 'rotation_euler':
                        # Need the whole rotation to convert, so save it for later
                        euler_rotations[bone_name] = euler_rotations.get(
                            bone_name, Euler())
                        euler_rotations[bone_name][data_idx] = data_value
                    elif data_elem == 'rotation_axis_angle':
                        pass  # Not implemented
                    elif data_elem == 'rotation_quaternion':
                        transform.rotation[data_idx] = data_value
                    elif data_elem == 'scale':
                        transform.scale[data_idx] = data_value
                else:
                    pass
                    # TODO
                    # print(fcurve.data_path)
                    # curves[fcurve.data_path] = fcurve.evaluate(marker.frame)

            # Convert eulers to quaternions
            for bone_name, euler in euler_rotations.items():
                transforms[bone_name].rotation = euler.to_quaternion()

            # Remove bones that don't contribute to the pose
            for bone_name in list(transforms.keys()):
                if transforms[bone_name].equals(default_transform):
                    del transforms[bone_name]

        # Collect the names of the bones used in the poses
        self.relevant_bones = sorted(
            set(
                chain.from_iterable(transforms.keys()
                                    for transforms in pose_transforms)))

        # Finalize poses, changing dicts to lists for performance. The indices correspond
        # to relevant_bones, relevant_curves etc. and have None where the pose isn't affected
        self.poses.clear()
        for marker, transforms in zip(self.pose_lib.pose_markers,
                                      pose_transforms):
            if marker.name == "bind_pose":
                continue
            transforms = [
                transforms.get(bone_name) for bone_name in self.relevant_bones
            ]
            pose = Pose(self, marker.name, transforms)
            self.poses.append(pose)

        # Make additive relative to the chosen base pose
        self.base_pose = None
        if self.additive and self.poses:
            try:
                self.base_pose = next(pose for pose in self.poses
                                      if pose.name == "base_pose")
            except StopIteration:
                # TODO allow user to choose
                self.base_pose = self.poses[0]

            self.poses.remove(self.base_pose)

            for pose in self.poses:
                for transform, base_transform in zip(
                        pose.transforms, self.base_pose.transforms):
                    if transform:
                        transform.make_additive(base_transform
                                                or default_transform)
                # for curve, base_curve in zip(pose.curves, base_pose.curves):
                #     curve.value -= base_curve.value

        self.pose_names = {pose.name: pose for pose in self.poses}

        # Put poses in pairs where there are symmetric poses
        self.pose_rows.clear()
        pose_names = [pose.name for pose in self.poses]
        pose_names.reverse()
        while pose_names:
            pose_name = pose_names.pop()
            flipped_name = get_flipped_name(pose_name)

            if flipped_name and flipped_name in pose_names:
                pose_names.remove(flipped_name)
                # R/L is more intuitive since you usually pose the character in front view
                self.pose_rows.append((flipped_name, pose_name))
            else:
                self.pose_rows.append((pose_name, ))
コード例 #5
0
def _init_brick(brick, cfg_brick):
    brick.location = cfg_brick['location']

    _set_brick_color([cfg_brick['color']], brick, random_color=True)

    ##    if len(brick.children) >= 1:  # brick with multiple parts
    ##        logging.debug('brick with multiple objects: %s', brick.children)
    ##        #scene = bpy.context.scene
    ##        # join sub-elements to a new brick
    ##        for obj in brick.children:
    ##            logging.info(obj)
    ##            #scene.collection.objects.link(obj)
    ##            #obj.select_set(True) #obj.select = True
    ##            #bpy.context.collection.objects.link(obj)  # bpy.context.scene.collection.objects.active(obj)
    ##            #logging.info(obj.dimensions)
    ##
    ##        #bpy.ops.object.collection_objects_select()
    ##        logging.info(bpy.context.selected_objects)
    ##        logging.debug(brick.dimensions)
    ##        #bpy.ops.object.join()  # combine sub-elements
    ##
    #bpy.ops.object.parent_clear(type='CLEAR')  # move group outside the parent

    #remove old brick
    #bpy.data.objects.remove(bpy.data.objects[brick.name], do_unlink = True)

    # set the new brick
    ##        logging.info("Selected=",bpy.context.selected_objects[0].name)
    ##        new = False
    ##        for obj in bpy.data.objects:
    ##            if obj.name == bpy.context.selected_objects[0].name:
    ##                new = True
    ##                logging.debug('object name: %s', obj.name)
    ##                brick = obj
    ##                logging.debug('new brick selected: %s', brick)
    ##        if not new:
    ##            e = 'new brick could not be selected'
    ##            logging.error(e)
    ##            raise ValueError(e)

    # size normalization: set longest dimension to target size
    multiple_obj = False
    if cfg_brick['size_normalization']['enabled']:
        dim_target = cfg_brick['size_normalization']['target_dim']
        try:
            logging.debug(brick.dimensions)
            if brick.dimensions[0] == 0.0000:
                logging.debug(bpy.context.object.dimensions)
                scale_factor = dim_target / max(bpy.context.object.dimensions)
                bpy.context.object.dimensions = bpy.context.object.dimensions * scale_factor
                bpy.context.object.location = cfg_brick['location']
                #bpy.context.object.rotation_euler = Euler(deg2rad(cfg_brick['rotation']))
                multiple_obj = True
            else:
                scale_factor = dim_target / max(brick.dimensions)
                brick.dimensions = brick.dimensions * scale_factor
                logging.debug(scale_factor)
                logging.debug(brick.dimensions)
                brick.location = cfg_brick['location']
                brick.rotation_euler = Euler(deg2rad(cfg_brick['rotation']))
                logging.debug(brick.rotation_euler)
                logging.debug(brick.scale)
                logging.debug(brick.location)
        except Exception as e:
            logging.error(e)
            raise e

    # set new origin to geometry center
    bpy.ops.object.select_all(action='DESELECT')

    for obj in bpy.context.scene.objects:
        if bpy.context.object.name == obj.name:
            obj.select_set(True)
            bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY',
                                      center='BOUNDS')  # set origin to center
            bpy.context.object.location = cfg_brick['location']
            obj.select_set(False)

    # bpy.context.scene.update()
    if multiple_obj:
        brick = bpy.context.object
        bpy.ops.object.select_all(action='DESELECT')
    else:
        bpy.ops.object.select_all(action='DESELECT')
        for obj in bpy.context.scene.objects:
            if brick.name == obj.name:
                obj.select_set(True)
                bpy.ops.object.origin_set(
                    type='ORIGIN_GEOMETRY',
                    center='BOUNDS')  # set origin to center
                bpy.context.object.location = cfg_brick['location']
                obj.select_set(False)
    return brick
コード例 #6
0
def duplicateObject(self):
    if self.Instantiate:
        bpy.ops.object.duplicate_move_linked(
            OBJECT_OT_duplicate={
                "linked": True,
                "mode": 'TRANSLATION',
            },
            TRANSFORM_OT_translate={
                "value": (0, 0, 0),
            },
        )
    else:
        bpy.ops.object.duplicate_move(
            OBJECT_OT_duplicate={
                "linked": False,
                "mode": 'TRANSLATION',
            },
            TRANSFORM_OT_translate={
                "value": (0, 0, 0),
            },
        )

    ob_new = bpy.context.active_object

    ob_new.location = self.CurLoc
    v = Vector()
    v.x = v.y = 0.0
    v.z = self.BrushDepthOffset
    ob_new.location += self.qRot * v

    if self.ObjectMode:
        ob_new.scale = self.ObjectBrush.scale
    if self.ProfileMode:
        ob_new.scale = self.ProfileBrush.scale

    e = Euler()
    e.x = e.y = 0.0
    e.z = self.aRotZ / 25.0

    # If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
    if (self.alt is True) and ((self.nbcol + self.nbrow) < 3):
        if self.RandomRotation:
            e.z += random.random()

    qe = e.to_quaternion()
    qRot = self.qRot * qe
    ob_new.rotation_mode = 'QUATERNION'
    ob_new.rotation_quaternion = qRot
    ob_new.rotation_mode = 'XYZ'

    if (ob_new.display_type == "WIRE") and (self.BrushSolidify is False):
        ob_new.hide_viewport = True

    if self.BrushSolidify:
        ob_new.display_type = "SOLID"
        ob_new.show_in_front = False

    for o in bpy.context.selected_objects:
        UndoAdd(self, "DUPLICATE", o)

    if len(bpy.context.selected_objects) > 0:
        bpy.ops.object.select_all(action='TOGGLE')
    for o in self.all_sel_obj_list:
        o.select_set(True)

    bpy.context.view_layer.objects.active = self.OpsObj
コード例 #7
0
ファイル: gen.py プロジェクト: aiyl/Diploma
def cam_init():
    cam.location = Vector((0, 0, 0))
    cam.rotation_euler = Euler((0, 0, 0), 'XYZ')
コード例 #8
0
ファイル: k2_import.py プロジェクト: maboelfotoh/K2-Blender
def getTransformMatrix(motions,bone,i,version):
    motion = motions[bone.name]
    #translation
    if i >= len(motion[MKEY_X]):
        x = motion[MKEY_X][-1]
    else:
        x = motion[MKEY_X][i]
    
    if i >= len(motion[MKEY_Y]):
        y = motion[MKEY_Y][-1]
    else:
        y = motion[MKEY_Y][i]
    
    if i >= len(motion[MKEY_Z]):
        z = motion[MKEY_Z][-1]
    else:
        z = motion[MKEY_Z][i]

    #rotation
    if i >= len(motion[MKEY_PITCH]):
        rx = motion[MKEY_PITCH][-1]
    else:
        rx = motion[MKEY_PITCH][i]
    
    if i >= len(motion[MKEY_ROLL]):
        ry = motion[MKEY_ROLL][-1]
    else:
        ry = motion[MKEY_ROLL][i]

    if i >= len(motion[MKEY_YAW]):
        rz = motion[MKEY_YAW][-1]
    else:
        rz = motion[MKEY_YAW][i]
    
    #scaling
    if version == 1:
        if i >= len(motion[MKEY_SCALE_X]):
            sx = motion[MKEY_SCALE_X][-1]
        else:
            sx = motion[MKEY_SCALE_X][i]
        sy = sz = sx
    else:
        if i >= len(motion[MKEY_SCALE_X]):
            sx = motion[MKEY_SCALE_X][-1]
        else:
            sx = motion[MKEY_SCALE_X][i]
        
        if i >= len(motion[MKEY_SCALE_Y]):
            sy = motion[MKEY_SCALE_Y][-1]
        else:
            sy = motion[MKEY_SCALE_Y][i]

        if i >= len(motion[MKEY_SCALE_Z]):
            sz = motion[MKEY_SCALE_Z][-1]
        else:
            sz = motion[MKEY_SCALE_Z][i]
    scale = Vector([sx,sy,sz])
    bone_rotation_matrix = Euler((math.radians(rx),math.radians(ry),math.radians(rz)),'YXZ').to_matrix().to_4x4()

    bone_rotation_matrix = Matrix.Translation(\
        Vector((x,y,z))) * bone_rotation_matrix

    return bone_rotation_matrix,scale
コード例 #9
0
    def createRig(self, name):
        # Create armature and object
        if self.coords != None:
            bpy.ops.object.armature_add(enter_editmode=True,
                                        location=self.coords)
        else:
            bpy.ops.object.armature_add(enter_editmode=True)
        ob = bpy.context.object
        if self.coords != None:
            ob.rotation_euler = self.rot
        self.armature_object = ob
        ob.show_x_ray = True
        if self.cust_name:
            ob.name = self.cust_name
        else:
            ob.name = name
        arm = ob.data

        arm.name = name + '_arm'
        arm.show_axes = True
        self.arm = arm
        # Create bones
        bpy.ops.object.mode_set(mode='EDIT')
        # arm.edit_bones.remove(arm.edit_bones[0])
        bone_list = []
        for bone in self.MDL.theMdlFileData.theBones:  # type: MDL_DATA.SourceMdlBone
            bone_list.append((arm.edit_bones.new(bone.name), bone))
        for bone_, bone in bone_list:  # type: Tuple[bpy.types.EditBone, MDL_DATA.SourceMdlBone]
            if bone.parentBoneIndex != -1:
                parent_, parent = bone_list[bone.parentBoneIndex]
                bone_.parent = parent_
                # bone_.head = Vector([bone.position.x,bone.position.z,bone.position.y])+parent_.head
                bone_.use_connect = False

            else:
                pass
                # bone_.head = Vector([bone.position.x,bone.position.z,bone.position.y])
                # rot = Matrix.Translation([bone.rotation.x,bone.rotation.y,bone.rotation.z])  # identity matrix
            # bone_.tail = rot * Vector([1,1,1]) + bone_.head
            if self.forRig:
                bone_.tail = Vector([0, 0, 1]) + bone_.head
            else:
                bone_.tail = Vector([0, 0, 1])
            # print('bone {0} created\n'
            #       'x {1:.3f},y {2:.3f},z {3:.3f}\n'
            #       'xr {4:.3f}, yr {5:.3f}, zr {6:.3f}'.format(bone.name, bone.position.x, bone.position.z,
            #                                                   bone.position.y, bone.rotation.x, bone.rotation.y,
            #                                                   bone.rotation.z))

        bpy.ops.object.mode_set(mode='POSE')
        for bone_ in self.MDL.theMdlFileData.theBones:  # type: MDL_DATA.SourceMdlBone
            bone = ob.pose.bones.get(bone_.name)
            pos = Vector(
                [bone_.position.x, bone_.position.y, bone_.position.z])
            rot = Euler([bone_.rotation.x, bone_.rotation.y, bone_.rotation.z])
            mat = Matrix.Translation(pos) * rot.to_matrix().to_4x4()
            bone.matrix_basis.identity()
            if bone.parent:
                bone.matrix = bone.parent.matrix * mat
            else:
                bone.matrix = mat
        bpy.ops.pose.armature_apply()
        bpy.ops.object.mode_set(mode='OBJECT')
        if self.forRig:
            bpy.ops.object.mode_set(mode='EDIT')
            for bone_, bone in bone_list:
                if bone_.parent:
                    parent = bone_.parent
                    if len(parent.children) > 1:
                        bone_.use_connect = False
                        parent.tail = sum([ch.head for ch in parent.children],
                                          mathutils.Vector()) / len(
                                              parent.children)
                    else:
                        parent.tail = bone_.head
                        bone_.use_connect = True
                    if bone_.children == 0:
                        par = bone_.parent
                        if par.children > 1:
                            pass
                        bone_.tail = bone_.head + (par.tail - par.head)
                if bone_.parent == 0 and bone_.children > 1:
                    bone_.tail = (bone_.head + bone_.tail) * 2
                bone_.select = True
            bpy.ops.armature.calculate_roll(type='GLOBAL_POS_Z')
        bpy.ops.object.mode_set(mode='OBJECT')
        return ob
コード例 #10
0
ファイル: import_bvh.py プロジェクト: VERTlG0/Blender
def bvh_node_dict2armature(
    context,
    bvh_name,
    bvh_nodes,
    bvh_frame_time,
    rotate_mode='XYZ',
    frame_start=1,
    IMPORT_LOOP=False,
    global_matrix=None,
    use_fps_scale=False,
):

    if frame_start < 1:
        frame_start = 1

    # Add the new armature,
    scene = context.scene
    for obj in scene.objects:
        obj.select = False

    arm_data = bpy.data.armatures.new(bvh_name)
    arm_ob = bpy.data.objects.new(bvh_name, arm_data)

    scene.objects.link(arm_ob)

    arm_ob.select = True
    scene.objects.active = arm_ob

    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)

    bvh_nodes_list = sorted_nodes(bvh_nodes)

    # Get the average bone length for zero length bones, we may not use this.
    average_bone_length = 0.0
    nonzero_count = 0
    for bvh_node in bvh_nodes_list:
        l = (bvh_node.rest_head_local - bvh_node.rest_tail_local).length
        if l:
            average_bone_length += l
            nonzero_count += 1

    # Very rare cases all bones could be zero length???
    if not average_bone_length:
        average_bone_length = 0.1
    else:
        # Normal operation
        average_bone_length = average_bone_length / nonzero_count

    # XXX, annoying, remove bone.
    while arm_data.edit_bones:
        arm_ob.edit_bones.remove(arm_data.edit_bones[-1])

    ZERO_AREA_BONES = []
    for bvh_node in bvh_nodes_list:

        # New editbone
        bone = bvh_node.temp = arm_data.edit_bones.new(bvh_node.name)

        bone.head = bvh_node.rest_head_world
        bone.tail = bvh_node.rest_tail_world

        # Zero Length Bones! (an exceptional case)
        if (bone.head - bone.tail).length < 0.001:
            print("\tzero length bone found:", bone.name)
            if bvh_node.parent:
                ofs = bvh_node.parent.rest_head_local - bvh_node.parent.rest_tail_local
                if ofs.length:  # is our parent zero length also?? unlikely
                    bone.tail = bone.tail - ofs
                else:
                    bone.tail.y = bone.tail.y + average_bone_length
            else:
                bone.tail.y = bone.tail.y + average_bone_length

            ZERO_AREA_BONES.append(bone.name)

    for bvh_node in bvh_nodes_list:
        if bvh_node.parent:
            # bvh_node.temp is the Editbone

            # Set the bone parent
            bvh_node.temp.parent = bvh_node.parent.temp

            # Set the connection state
            if ((not bvh_node.has_loc)
                    and (bvh_node.parent.temp.name not in ZERO_AREA_BONES) and
                (bvh_node.parent.rest_tail_local == bvh_node.rest_head_local)):
                bvh_node.temp.use_connect = True

    # Replace the editbone with the editbone name,
    # to avoid memory errors accessing the editbone outside editmode
    for bvh_node in bvh_nodes_list:
        bvh_node.temp = bvh_node.temp.name

    # Now Apply the animation to the armature

    # Get armature animation data
    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

    pose = arm_ob.pose
    pose_bones = pose.bones

    if rotate_mode == 'NATIVE':
        for bvh_node in bvh_nodes_list:
            bone_name = bvh_node.temp  # may not be the same name as the bvh_node, could have been shortened.
            pose_bone = pose_bones[bone_name]
            pose_bone.rotation_mode = bvh_node.rot_order_str

    elif rotate_mode != 'QUATERNION':
        for pose_bone in pose_bones:
            pose_bone.rotation_mode = rotate_mode
    else:
        # Quats default
        pass

    context.scene.update()

    arm_ob.animation_data_create()
    action = bpy.data.actions.new(name=bvh_name)
    arm_ob.animation_data.action = action

    # Replace the bvh_node.temp (currently an editbone)
    # With a tuple  (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv)
    num_frame = 0
    for bvh_node in bvh_nodes_list:
        bone_name = bvh_node.temp  # may not be the same name as the bvh_node, could have been shortened.
        pose_bone = pose_bones[bone_name]
        rest_bone = arm_data.bones[bone_name]
        bone_rest_matrix = rest_bone.matrix_local.to_3x3()

        bone_rest_matrix_inv = Matrix(bone_rest_matrix)
        bone_rest_matrix_inv.invert()

        bone_rest_matrix_inv.resize_4x4()
        bone_rest_matrix.resize_4x4()
        bvh_node.temp = (pose_bone, bone, bone_rest_matrix,
                         bone_rest_matrix_inv)

        if 0 == num_frame:
            num_frame = len(bvh_node.anim_data)

    # Choose to skip some frames at the beginning. Frame 0 is the rest pose
    # used internally by this importer. Frame 1, by convention, is also often
    # the rest pose of the skeleton exported by the motion capture system.
    skip_frame = 1
    if num_frame > skip_frame:
        num_frame = num_frame - skip_frame

    # Create a shared time axis for all animation curves.
    time = [float(frame_start)] * num_frame
    if use_fps_scale:
        dt = scene.render.fps * bvh_frame_time
        for frame_i in range(1, num_frame):
            time[frame_i] += float(frame_i) * dt
    else:
        for frame_i in range(1, num_frame):
            time[frame_i] += float(frame_i)

    # print("bvh_frame_time = %f, dt = %f, num_frame = %d"
    #      % (bvh_frame_time, dt, num_frame]))

    for i, bvh_node in enumerate(bvh_nodes_list):
        pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv = bvh_node.temp

        if bvh_node.has_loc:
            # Not sure if there is a way to query this or access it in the
            # PoseBone structure.
            data_path = 'pose.bones["%s"].location' % pose_bone.name

            location = [(0.0, 0.0, 0.0)] * num_frame
            for frame_i in range(num_frame):
                bvh_loc = bvh_node.anim_data[frame_i + skip_frame][:3]

                bone_translate_matrix = Matrix.Translation(
                    Vector(bvh_loc) - bvh_node.rest_head_local)
                location[frame_i] = (bone_rest_matrix_inv *
                                     bone_translate_matrix).to_translation()

            # For each location x, y, z.
            for axis_i in range(3):
                curve = action.fcurves.new(data_path=data_path, index=axis_i)
                keyframe_points = curve.keyframe_points
                keyframe_points.add(num_frame)

                for frame_i in range(num_frame):
                    keyframe_points[frame_i].co = (
                        time[frame_i],
                        location[frame_i][axis_i],
                    )

        if bvh_node.has_rot:
            data_path = None
            rotate = None

            if 'QUATERNION' == rotate_mode:
                rotate = [(1.0, 0.0, 0.0, 0.0)] * num_frame
                data_path = ('pose.bones["%s"].rotation_quaternion' %
                             pose_bone.name)
            else:
                rotate = [(0.0, 0.0, 0.0)] * num_frame
                data_path = ('pose.bones["%s"].rotation_euler' %
                             pose_bone.name)

            prev_euler = Euler((0.0, 0.0, 0.0))
            for frame_i in range(num_frame):
                bvh_rot = bvh_node.anim_data[frame_i + skip_frame][3:]

                # apply rotation order and convert to XYZ
                # note that the rot_order_str is reversed.
                euler = Euler(bvh_rot, bvh_node.rot_order_str[::-1])
                bone_rotation_matrix = euler.to_matrix().to_4x4()
                bone_rotation_matrix = (bone_rest_matrix_inv *
                                        bone_rotation_matrix *
                                        bone_rest_matrix)

                if len(rotate[frame_i]) == 4:
                    rotate[frame_i] = bone_rotation_matrix.to_quaternion()
                else:
                    rotate[frame_i] = bone_rotation_matrix.to_euler(
                        pose_bone.rotation_mode, prev_euler)
                    prev_euler = rotate[frame_i]

            # For each euler angle x, y, z (or quaternion w, x, y, z).
            for axis_i in range(len(rotate[0])):
                curve = action.fcurves.new(data_path=data_path, index=axis_i)
                keyframe_points = curve.keyframe_points
                keyframe_points.add(num_frame)

                for frame_i in range(num_frame):
                    keyframe_points[frame_i].co = (
                        time[frame_i],
                        rotate[frame_i][axis_i],
                    )

    for cu in action.fcurves:
        if IMPORT_LOOP:
            pass  # 2.5 doenst have cyclic now?

        for bez in cu.keyframe_points:
            bez.interpolation = 'LINEAR'

    # finally apply matrix
    arm_ob.matrix_world = global_matrix
    bpy.ops.object.transform_apply(rotation=True)

    return arm_ob
コード例 #11
0
    def getTransform(self):
        """
        returned transform matrix is of the form translation*parentMatrix*rotation
        parent is dependent of parent mode, that is either Euler or DH
        either translation or rotation is I_4 dependent of the joint type,
        whereas a revolute joints contributes a rotation only and a
        prismatic joint contributes a translation only
        """

        translation = Matrix()  # initialize as I_4 matrix
        rotation = Matrix()  # initialize as I_4 matrix
        axis_matrix = Matrix()  # contains axis information which should be applied to parentMatrix

        if self.axis_revert:
            inverted = -1
        else:
            inverted = 1

        if self.parentMode == 'EULER':
            parentMatrix = self.Euler.getTransformFromParent()
        else:  # self.parentMode == 'DH'
            parentMatrix = self.DH.getTransformFromParent()

        if self.jointMode == 'REVOLUTE':
            if self.axis == 'X':
                rotation = Euler(
                        (radians(self.theta.value + self.theta.offset), 0, 0),
                        'XYZ').to_matrix()
                rotation.resize_4x4()
                axis_matrix = Euler((radians(180 * (1 - inverted) / 2), 0, 0),
                                    'XYZ').to_matrix()
                axis_matrix.resize_4x4()
            elif self.axis == 'Y':
                rotation = Euler(
                        (0, radians(self.theta.value + self.theta.offset), 0),
                        'XYZ').to_matrix()
                rotation.resize_4x4()
                axis_matrix = Euler((0, radians(180 * (1 - inverted) / 2), 0),
                                    'XYZ').to_matrix()
                axis_matrix.resize_4x4()
            elif self.axis == 'Z':
                rotation = Euler(
                        (0, 0, radians(self.theta.value + self.theta.offset)),
                        'XYZ').to_matrix()
                rotation.resize_4x4()
                axis_matrix = Euler((0, 0, radians(180 * (1 - inverted) / 2)),
                                    'XYZ').to_matrix()
                axis_matrix.resize_4x4()

        if self.jointMode == 'PRISMATIC':
            if self.axis == 'X':
                translation = Matrix.Translation(
                        (inverted * (self.d.value + self.d.offset), 0, 0, 1))
            elif self.axis == 'Y':
                translation = Matrix.Translation(
                        (0, inverted * (self.d.value + self.d.offset), 0, 1))
            elif self.axis == 'Z':
                translation = Matrix.Translation(
                        (0, 0, inverted * (self.d.value + self.d.offset), 1))

        if self.jointMode == 'FIXED' or self.jointMode == 'REVOLUTE2' or self.jointMode == 'UNIVERSAL' or self.jointMode == 'BALL':  # todo: check if this is right for fixed joint type
            translation = Matrix.Translation((0, 0, 0, 1))

        return parentMatrix * axis_matrix, translation * rotation
コード例 #12
0

def createSphere(origin=(0, 0, 0)):
    # Create icosphere
    bpy.ops.mesh.primitive_ico_sphere_add(location=origin)
    obj = bpy.context.object
    return obj


# Remove all elements
utils.removeAll()

# Create camera
bpy.ops.object.add(type='CAMERA', location=(0, -3.5, 0))
cam = bpy.context.object
cam.rotation_euler = Euler((pi / 2, 0, 0), 'XYZ')
# Make this the current camera
bpy.context.scene.camera = cam

# Create lamps
utils.rainbowLights()

# Create object and its material
sphere = createSphere()
utils.setSmooth(sphere, 3)

# Specify folder to save rendering
render_folder = os.path.join(cwd, 'rendering')
if (not os.path.exists(render_folder)):
    os.mkdir(render_folder)
コード例 #13
0
def parse_mapping(node: bpy.types.ShaderNodeMapping,
                  out_socket: bpy.types.NodeSocket,
                  state: ParserState) -> vec3str:
    # Only "Point", "Texture" and "Vector" types supported for now..
    # More information about the order of operations for this node:
    # https://docs.blender.org/manual/en/latest/render/shader_nodes/vector/mapping.html#properties

    input_vector: bpy.types.NodeSocket = node.inputs[0]
    input_location: bpy.types.NodeSocket = node.inputs['Location']
    input_rotation: bpy.types.NodeSocket = node.inputs['Rotation']
    input_scale: bpy.types.NodeSocket = node.inputs['Scale']
    out = c.parse_vector_input(
        input_vector) if input_vector.is_linked else c.to_vec3(
            input_vector.default_value)
    location = c.parse_vector_input(
        input_location) if input_location.is_linked else c.to_vec3(
            input_location.default_value)
    rotation = c.parse_vector_input(
        input_rotation) if input_rotation.is_linked else c.to_vec3(
            input_rotation.default_value)
    scale = c.parse_vector_input(
        input_scale) if input_scale.is_linked else c.to_vec3(
            input_scale.default_value)

    # Use inner functions because the order of operations varies between
    # mapping node vector types. This adds a slight overhead but makes
    # the code much more readable.
    # - "Point" and "Vector" use Scale -> Rotate -> Translate
    # - "Texture" uses Translate -> Rotate -> Scale
    def calc_location(output: str) -> str:
        # Vectors and Eulers support the "!=" operator
        if input_scale.is_linked or input_scale.default_value != Vector(
            (1, 1, 1)):
            if node.vector_type == 'TEXTURE':
                output = f'({output} / {scale})'
            else:
                output = f'({output} * {scale})'

        return output

    def calc_scale(output: str) -> str:
        if input_location.is_linked or input_location.default_value != Vector(
            (0, 0, 0)):
            # z location is a little off sometimes?...
            if node.vector_type == 'TEXTURE':
                output = f'({output} - {location})'
            else:
                output = f'({output} + {location})'
        return output

    out = calc_location(out) if node.vector_type == 'TEXTURE' else calc_scale(
        out)

    if input_rotation.is_linked or input_rotation.default_value != Euler(
        (0, 0, 0)):
        var_name = c.node_name(node.name) + "_rotation"
        if node.vector_type == 'TEXTURE':
            state.curshader.write(
                f'mat3 {var_name}X = mat3(1.0, 0.0, 0.0, 0.0, cos({rotation}.x), sin({rotation}.x), 0.0, -sin({rotation}.x), cos({rotation}.x));'
            )
            state.curshader.write(
                f'mat3 {var_name}Y = mat3(cos({rotation}.y), 0.0, -sin({rotation}.y), 0.0, 1.0, 0.0, sin({rotation}.y), 0.0, cos({rotation}.y));'
            )
            state.curshader.write(
                f'mat3 {var_name}Z = mat3(cos({rotation}.z), sin({rotation}.z), 0.0, -sin({rotation}.z), cos({rotation}.z), 0.0, 0.0, 0.0, 1.0);'
            )
        else:
            # A little bit redundant, but faster than 12 more multiplications to make it work dynamically
            state.curshader.write(
                f'mat3 {var_name}X = mat3(1.0, 0.0, 0.0, 0.0, cos(-{rotation}.x), sin(-{rotation}.x), 0.0, -sin(-{rotation}.x), cos(-{rotation}.x));'
            )
            state.curshader.write(
                f'mat3 {var_name}Y = mat3(cos(-{rotation}.y), 0.0, -sin(-{rotation}.y), 0.0, 1.0, 0.0, sin(-{rotation}.y), 0.0, cos(-{rotation}.y));'
            )
            state.curshader.write(
                f'mat3 {var_name}Z = mat3(cos(-{rotation}.z), sin(-{rotation}.z), 0.0, -sin(-{rotation}.z), cos(-{rotation}.z), 0.0, 0.0, 0.0, 1.0);'
            )

        # XYZ-order euler rotation
        out = f'{out} * {var_name}X * {var_name}Y * {var_name}Z'

    out = calc_scale(out) if node.vector_type == 'TEXTURE' else calc_location(
        out)

    return out
コード例 #14
0
def get_top_mesh(context, prefs):
    me = context.blend_data.meshes.new('temp_mesh')
    bm = bmesh.new()
    bm.from_mesh(me)
    mat = Matrix()
    tt = prefs.lp_Tree_Type

    if tt == 'lp_Tree_Oak':
        mat.translation = (0, 0, prefs.trunk_depth)
        tsmin = prefs.lp_Tree_Top_Scale_Min
        tsmax = prefs.lp_Tree_Top_Scale_Max
        mat[0][0], mat[1][1], mat[2][2] = (uniform(tsmin[0], tsmax[0]),
                                           uniform(tsmin[1], tsmax[1]),
                                           uniform(tsmin[2], tsmax[2]))
        bmesh.ops.create_icosphere(bm,
                                   subdivisions=prefs.lp_Tree_Top_Subdivisions,
                                   diameter=1.0,
                                   matrix=mat)
    elif tt == 'lp_Tree_Pine':
        segments = get_random(prefs.lp_Tree_Top_Stage_Segments_Min,
                              prefs.lp_Tree_Top_Stage_Segments_Max)
        stages = get_random(prefs.lp_Tree_Top_Stages_Min,
                            prefs.lp_Tree_Top_Stages_Max)
        td = prefs.trunk_depth - 0.7
        sstep = uniform(prefs.lp_Tree_Top_Stage_Step_Min,
                        prefs.lp_Tree_Top_Stage_Step_Max)
        ssmin = prefs.lp_Tree_Top_Stage_Size_Min
        ssmax = prefs.lp_Tree_Top_Stage_Size_Max
        ssize = (uniform(ssmin[0], ssmax[0]), uniform(ssmin[1], ssmax[1]),
                 uniform(ssmin[2], ssmax[2]))
        for i in range(0, stages):
            mult = prefs.lp_Tree_Top_Stage_Shrink_Multiplier * (i / 4)
            sc = (1 - i * prefs.lp_Tree_Top_Stage_Shrink * mult) * 0.9
            if sc < 0.01:
                sc = 0.01
            mat[0][0], mat[1][1], mat[2][2] = (sc * ssize[0], sc * ssize[1],
                                               sc * ssize[2])
            mat.translation = (0, 0,
                               (td + ((ssize[2] - 1) / 2) + i * sstep) * 0.85)
            if prefs.lp_Tree_Top_Rotate_Stages:
                e = Euler((0, 0, uniform(0, 3.14)), 'XYZ')
                mat = mat * e.to_matrix().to_4x4()
            bmesh.ops.create_cone(bm,
                                  cap_ends=True,
                                  cap_tris=True,
                                  segments=segments,
                                  diameter1=(prefs.lp_Tree_Top_Stage_Diameter),
                                  diameter2=0,
                                  depth=(0.85),
                                  matrix=mat)
            mat = Matrix()
    elif tt == 'lp_Tree_Palm':
        trunk_length = prefs.palm_stage_length * prefs.palm_stages
        leaf_length = get_random(prefs.lp_Tree_Palm_Top_Leaf_Length_Min,
                                 prefs.lp_Tree_Palm_Top_Leaf_Length_Max)
        leaf_size = uniform(prefs.lp_Tree_Palm_Top_Leaf_Size_Min,
                            prefs.lp_Tree_Palm_Top_Leaf_Size_Max)

        mat.translation = (0, 0, trunk_length)
        leaves = get_random(prefs.lp_Tree_Palm_Top_Leaves_Min,
                            prefs.lp_Tree_Palm_Top_Leaves_Max)
        bmesh.ops.create_cone(bm,
                              cap_ends=True,
                              cap_tris=True,
                              segments=leaves,
                              diameter1=leaf_size,
                              diameter2=leaf_size,
                              depth=0.1,
                              matrix=mat)
        faces = bm.faces[:]
        for face in faces:
            nor = face.normal  # Asume normalized normal
            dir = (nor.x * 0.3, nor.y * 0.3, -0.12)
            if nor.z == 0:
                for i in range(0, leaf_length):
                    r = bmesh.ops.extrude_discrete_faces(bm, faces=[face])
                    bmesh.ops.translate(bm, vec=dir, verts=r['faces'][0].verts)
                    face = r['faces'][0]
                    dir = (dir[0], dir[1], dir[2] - 0.08)
                # Align last face verts
                mid = [0, 0, 0]
                for v in face.verts:
                    mid[0] += v.co.x
                    mid[1] += v.co.y
                    mid[2] += v.co.z
                mid[0] /= len(face.verts)
                mid[1] /= len(face.verts)
                mid[2] /= len(face.verts)
                for v in face.verts:
                    v.co.x, v.co.y, v.co.z = mid[0], mid[1], mid[2]

    bm.to_mesh(me)
    return me
コード例 #15
0
    def execute(self, context):
        """SETTINGS"""
        keep_breasts = True
        keep_twist_weights = True
        belly_locators = True

        arm_bend = 45
        finger_bend = -15

        scene = bpy.context.scene
        obj = bpy.context.object
        meshes = obj.children

        #gyaz stamp
        obj.data['GYAZ_rig'] = True

        #remove all modifiers except for armature modifier
        for mesh in meshes:
            for m in mesh.modifiers:
                if m.type != 'ARMATURE':
                    mesh.modifiers.remove(m)

        #################################################################################
        #raycast function
        my_tree = BVHTree.FromObject(scene.objects[meshes[0].name],
                                     bpy.context.depsgraph)

        rig = obj

        def cast_ray_from_bone(start_bone, head_tail, ebone_pbone, direction,
                               distance):
            #set ray start and direction
            if ebone_pbone == 'ebone':
                bpy.ops.object.mode_set(mode='EDIT')
                if head_tail == 'head':
                    ray_start = rig.data.edit_bones[start_bone].head
                elif head_tail == 'tail':
                    ray_start = rig.data.edit_bones[start_bone].tail
            elif ebone_pbone == 'pbone':
                bpy.ops.object.mode_set(mode='POSE')
                if head_tail == 'head':
                    ray_start = rig.pose.bones[start_bone].head
                elif head_tail == 'tail':
                    ray_start = rig.pose.bones[start_bone].tail
            ray_direction = direction
            ray_distance = 10

            #cast ray
            hit_loc, hit_nor, hit_index, hit_dist = my_tree.ray_cast(
                ray_start, ray_direction, ray_distance)

            return (hit_loc, hit_nor, hit_index, hit_dist)

        #################################################################################

        if obj.type == 'ARMATURE':
            rig = obj

            sides = [['_L', '_l'], ['_R', '_r']]

            names_central = [['root', 'root'], ['pelvis', 'hips'],
                             ['spine01', 'spine_1'], ['spine02', 'spine_2'],
                             ['spine03', 'spine_3'], ['neck', 'neck'],
                             ['head', 'head']]

            names_side = [
                ['clavicle', 'shoulder'],
                ['upperarm', 'upperarm'],
                ['lowerarm', 'forearm'],
                ['hand', 'hand'],
                ['thigh', 'thigh'],
                ['calf', 'shin'],
                ['foot', 'foot'],
                ['toes', 'toes'],
                #        ['breast', 'spring_chest']
            ]

            finger_names = [['thumb', 'thumb'], ['index', 'pointer'],
                            ['middle', 'middle'], ['ring', 'ring'],
                            ['pinky', 'pinky']]

            counters = [['01', '_1'], ['02', '_2'], ['03', '_3']]

            twist_names = ['upperarm', 'lowerarm', 'thigh', 'calf']
            new_twist_names = ['upperarm', 'forearm', 'thigh', 'shin']

            metacarpal_names = ['index', 'middle', 'ring', 'pinky']

            extra_names = ['root']

            breast_names = ['breast', 'spring_chest']  # old name, new name

            bpy.ops.object.mode_set(mode='OBJECT')
            """WEIGHTS"""
            def merge_and_remove_weight(weight_to_merge, weight_to_merge_to):
                for mesh in meshes:
                    bpy.ops.object.select_all(action='DESELECT')
                    mesh.select_set(True)
                    bpy.context.view_layer.objects.active = mesh
                    #mix weights if mesh has those weights
                    vgroups = mesh.vertex_groups
                    if vgroups.get(weight_to_merge) != None:
                        if vgroups.get(weight_to_merge_to) == None:
                            vgroups.new(name=weight_to_merge_to)
                        m = mesh.modifiers.new(type='VERTEX_WEIGHT_MIX',
                                               name="Mix Twist Weight")
                        m.mix_mode = 'ADD'
                        m.mix_set = 'ALL'
                        m.vertex_group_a = weight_to_merge_to
                        m.vertex_group_b = weight_to_merge
                        bpy.ops.object.modifier_apply(
                            apply_as='DATA', modifier="Mix Twist Weight")
                        #delete surplus weights
                        vgroups = mesh.vertex_groups
                        vgroups.remove(vgroups[weight_to_merge])

            if keep_twist_weights == False:
                for old_side, new_side in sides:
                    for name in twist_names:
                        weight_to_merge = name + '_twist' + old_side
                        weight_to_merge_to = name + old_side

                        merge_and_remove_weight(weight_to_merge,
                                                weight_to_merge_to)

            for old_side, new_side in sides:
                for name in metacarpal_names:
                    weight_to_merge = name + '00' + old_side
                    weight_to_merge_to = 'hand' + old_side

                    merge_and_remove_weight(weight_to_merge,
                                            weight_to_merge_to)

            if keep_breasts == False:
                for old_side, new_side in sides:
                    weight_to_merge = breast_names[0] + old_side
                    weight_to_merge_to = 'spine03'

                    merge_and_remove_weight(weight_to_merge,
                                            weight_to_merge_to)

            for mesh in meshes:
                mesh.data.update()

            bpy.ops.object.select_all(action='DESELECT')
            rig.select_set(True)
            bpy.context.view_layer.objects.active = rig
            bpy.ops.object.mode_set(mode='EDIT')
            ebones = rig.data.edit_bones
            """RENAME"""

            for old_name, new_name in names_central:
                ebones[old_name].name = new_name

            for old_side, new_side in sides:
                for old_name, new_name in names_side:
                    ebones[old_name + old_side].name = new_name + new_side

            for old_side, new_side in sides:
                for old_finger, new_finger in finger_names:
                    for old_counter, new_counter in counters:
                        ebones[
                            old_finger + old_counter +
                            old_side].name = new_finger + new_counter + new_side

            for old_side, new_side in sides:
                ebone = ebones[breast_names[0] +
                               old_side].name = breast_names[1] + new_side

            for old_side, new_side in sides:
                for index, name in enumerate(twist_names):
                    ebone = ebones[name + '_twist' + old_side]
                    ebone.name = 'twist_1_' + new_twist_names[index] + new_side
            """REMOVE BONES"""

            for old_side, new_side in sides:
                for name in new_twist_names:
                    ebone = ebones['twist_1_' + name + new_side]
                    ebones.remove(ebone)

            for old_side, new_side in sides:
                for name in metacarpal_names:
                    ebone = ebones[name + '00' + old_side]
                    ebones.remove(ebone)

            for name in extra_names:
                ebone = ebones[name]
                ebones.remove(ebone)

            if keep_breasts == False:
                for old_side, new_side in sides:
                    ebone = ebones[breast_names[1] + new_side]
                    ebones.remove(ebone)
            """POSITION BONES"""

            ebones = rig.data.edit_bones

            for ebone in ebones:
                ebone.use_connect = False

#            for old_side, new_side in sides:
#                foot = ebones['foot'+new_side]
#                foot.tail = foot.head[0], foot.tail[1], foot.head[2]
#
#                toes = ebones['toes'+new_side]
#                toes.head = foot.head[0], toes.head[1], toes.head[2]
#                toes.tail = foot.head[0], toes.tail[1], toes.head[2]
#
#                foot.roll = 0
#                toes.roll = 0

            ebones['hips'].head = (ebones['thigh_l'].head +
                                   ebones['thigh_r'].head) / 2
            ebones['spine_3'].tail = ebones['neck'].head

            for old_side, new_side in sides:
                ebone = ebones['shoulder' + new_side]
                ebone.head = ebone.head[0], ebone.tail[1], ebone.tail[2]

            ebone = ebones['head']
            ebone.tail = ebone.head[0], ebone.head[1], ebone.tail[2]

            spine_names = [
                'hips', 'spine_1', 'spine_2', 'spine_3', 'neck', 'head'
            ]

            for name in spine_names:
                ebones[name].roll = 0

            for old_side, new_side in sides:
                ebone = ebones['hand' + new_side]
                roll = ebone.roll
                print(degrees(roll))
                ebone.tail = (ebone.tail - ebone.head) + ebone.tail
                ebone.roll = roll
            """REST POSE"""

            bpy.ops.object.mode_set(mode='POSE')

            pbones = rig.pose.bones

            for old_side, side in sides:
                pbone = pbones['forearm' + side]

                eu = Euler((radians(arm_bend), 0, 0), 'XYZ')
                qu = eu.to_quaternion()
                pbone.rotation_quaternion = qu

                for old_name, name in finger_names:
                    for n in range(1, 4):
                        pbone = pbones[name + '_' + str(n) + side]
                        if 'thumb_1' not in pbone.name:

                            eu = Euler((radians(finger_bend), 0, 0), 'XYZ')
                            qu = eu.to_quaternion()
                            pbone.rotation_quaternion = qu

            if len(meshes) > 0:
                for mesh in meshes:
                    bpy.ops.object.mode_set(mode='OBJECT')
                    bpy.ops.object.select_all(action='DESELECT')
                    mesh.select_set(True)
                    bpy.context.view_layer.objects.active = mesh

                    #remove shape keys
                    try:
                        bpy.ops.object.shape_key_remove(all=True)
                    except:
                        'do nothing'

                    #apply armature modifier
                    old_mesh = mesh.data
                    new_mesh = mesh.to_mesh(bpy.context.depsgraph,
                                            apply_modifiers=True,
                                            calc_undeformed=False)
                    mesh.data = new_mesh
                    bpy.data.meshes.remove(old_mesh)

            bpy.ops.object.mode_set(mode='OBJECT')
            bpy.ops.object.select_all(action='DESELECT')
            rig.select_set(True)
            bpy.context.view_layer.objects.active = rig

            #apply pose
            bpy.ops.object.mode_set(mode='POSE')
            bpy.ops.pose.select_all(action='SELECT')
            bpy.ops.pose.armature_apply()

            #adjust spine

            #spine_1, spine_2
            bpy.ops.object.mode_set(mode='EDIT')
            ebones = rig.data.edit_bones
            loc = (ebones['spine_1'].head + ebones['spine_2'].tail) / 2
            ebones['spine_1'].tail = loc
            ebones['spine_2'].head = loc

            #spine chain
            def adjust_spine_point(lower_bone, upper_bone):
                forward = (0, -1, 0)
                backward = (0, 1, 0)
                hit_loc, hit_nor, hit_index, hit_dist = cast_ray_from_bone(
                    lower_bone, 'tail', 'ebone', forward, 10)
                front = hit_loc
                hit_loc, hit_nor, hit_index, hit_dist = cast_ray_from_bone(
                    lower_bone, 'tail', 'ebone', backward, 10)
                back = hit_loc
                middle = (front + back) / 2

                bpy.ops.object.mode_set(mode='EDIT')
                ebones = rig.data.edit_bones
                ebones[lower_bone].tail = middle
                ebones[upper_bone].head = middle

                return front

            loc_pelvis_front = adjust_spine_point('hips', 'spine_1')
            adjust_spine_point('spine_1', 'spine_2')
            loc_sternum_lower = adjust_spine_point('spine_2', 'spine_3')
            adjust_spine_point('spine_3', 'neck')

            #additional locator bones
            if belly_locators == True:
                ebone = rig.data.edit_bones.new(name='loc_pelvis_front')
                ebone.head = loc_pelvis_front
                ebone.tail = loc_pelvis_front + Vector((0, 0, 0.05))
                ebone.parent = rig.data.edit_bones['hips']

                ebone = rig.data.edit_bones.new(name='loc_sternum_lower')
                ebone.head = loc_sternum_lower
                ebone.tail = loc_sternum_lower + Vector((0, 0, 0.05))
                ebone.parent = rig.data.edit_bones['spine_3']

            #enforce roll values
            bpy.ops.object.mode_set(mode='EDIT')
            ebones = rig.data.edit_bones
            bpy.ops.armature.select_all(action='SELECT')
            bpy.ops.armature.symmetrize()

            #finalize
            bpy.ops.object.mode_set(mode='OBJECT')
            bpy.ops.object.select_all(action='DESELECT')
            rig.select_set(True)
            bpy.context.view_layer.objects.active = rig

            #GYAZ stamp
            rig.data['GYAZ_game_rig'] = True

        return {'FINISHED'}
コード例 #16
0
	def execute(self, context):
		vars = context.scene
		target = bpy.data.objects[vars.Target]
		tool = bpy.data.objects[vars.Tool]
		get_Euler = target.rotation_euler
		get_Location = target.location
		print(get_Euler)
		print(get_Location)
		orig_eul = rot_eul = [get_Euler[0],get_Euler[1],get_Euler[2]]
		orig_loc = slide_loc = [get_Location[0],get_Location[1],get_Location[2]]
		toolRotRads = [radians(vars.MMToolXVal),radians(vars.MMToolYVal),radians(vars.MMToolZVal)]
		toolSlideUnits = [vars.MMToolXVal,vars.MMToolYVal,vars.MMToolZVal]
		prestepRotRads = [radians(vars.MMPreStepXVal),radians(vars.MMPreStepYVal),radians(vars.MMPreStepZVal)]
		prestepSlideUnits = [vars.MMPreStepXVal,vars.MMPreStepYVal,vars.MMPreStepZVal]

#		print(context.scene.Target)
#		print(context.scene.Tool)
		print(orig_eul,orig_loc)
		print(rot_eul,slide_loc)
		print(toolRotRads,toolSlideUnits)
		print(prestepRotRads,prestepSlideUnits)
		
		for r in range(0, vars.RepeaterCnt):
			if (vars.LimSteps > vars.NumSteps):
				vars.LimSteps = vars.NumSteps

			if (vars.MMPreStep =='Rotate'):
				rot_eul = Euler([sum(z) for z in zip(rot_eul, prestepRotRads)], "XYZ")
				target.rotation_euler = rot_eul
			elif (vars.MMPreStep =='Slide'):
				slide_loc = Vector([sum(z) for z in zip(slide_loc, prestepSlideUnits)])
				target.location = slide_loc
			
			print(rot_eul)
			print(slide_loc)
			
			for i in range(0, vars.LimSteps+1):
				print(i)
				# At step 0 these are the original euler\location (or location after pre-step),
				#   else the location set at end of previous "i" iteration step
				target.rotation_euler = rot_eul 
				target.location = slide_loc
				bpy.ops.object.select_all(action='DESELECT')
				target.select = True
				bpy.context.scene.objects.active = target
				
				if (i >= vars.StartSteps): # Execute tool action at this step
					bpy.ops.object.modifier_add(type='BOOLEAN')
					mod = target.modifiers
					mod[0].name = "MMTool"
					if (vars.MMAction == 'Diff'):
						 mod[0].operation = 'DIFFERENCE'
					else: # Assumes 'Union'
						 mod[0].operation = 'UNION'
					mod[0].object = tool
					bpy.ops.object.modifier_apply(apply_as='DATA', modifier=mod[0].name)
					
				if (vars.MMMove == 'Rotate'):
					rot_eul = Euler([sum(z) for z in zip(rot_eul, toolRotRads)], "XYZ")
				else: # Assumes 'Slide'
					slide_loc = Vector([sum(z) for z in zip(slide_loc, toolSlideUnits)])
				i += 1
			r += 1
			
		if self.country == '':
			print('Done')
		else:
			print("Don't Make Cuts from %s!" % self.country)
		return {"FINISHED"}
コード例 #17
0
def add_object_align_init(context, operator):
    """
    Return a matrix using the operator settings and view context.

    :arg context: The context to use.
    :type context: :class:`bpy.types.Context`
    :arg operator: The operator, checked for location and rotation properties.
    :type operator: :class:`bpy.types.Operator`
    :return: the matrix from the context and settings.
    :rtype: :class:`mathutils.Matrix`
    """

    from mathutils import Matrix, Vector, Euler
    properties = operator.properties if operator is not None else None

    space_data = context.space_data
    if space_data and space_data.type != 'VIEW_3D':
        space_data = None

    # location
    if operator and properties.is_property_set("location"):
        location = Matrix.Translation(Vector(properties.location))
    else:
        if space_data:  # local view cursor is detected below
            location = Matrix.Translation(space_data.cursor_location)
        else:
            location = Matrix.Translation(context.scene.cursor_location)

        if operator:
            properties.location = location.to_translation()

    # rotation
    view_align = (context.user_preferences.edit.object_align == 'VIEW')
    view_align_force = False
    if operator:
        if properties.is_property_set("view_align"):
            view_align = view_align_force = operator.view_align
        else:
            if properties.is_property_set("rotation"):
                # ugh, 'view_align' callback resets
                value = properties.rotation[:]
                properties.view_align = view_align
                properties.rotation = value
                del value
            else:
                properties.view_align = view_align

    if operator and (properties.is_property_set("rotation") and
                     not view_align_force):

        rotation = Euler(properties.rotation).to_matrix().to_4x4()
    else:
        if view_align and space_data:
            rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
            rotation.resize_4x4()
        else:
            rotation = Matrix()

        # set the operator properties
        if operator:
            properties.rotation = rotation.to_euler()

    return location @ rotation
コード例 #18
0
def read_chan(context, filepath, z_up, rot_ord, sensor_width, sensor_height):

    # get the active object
    scene = context.scene
    obj = context.active_object
    camera = obj.data if obj.type == 'CAMERA' else None

    # prepare the correcting matrix
    rot_mat = Matrix.Rotation(radians(90.0), 4, 'X').to_4x4()

    # read the file
    filehandle = open(filepath, 'r')

    # iterate through the files lines
    for line in filehandle:
        # reset the target objects matrix
        # (the one from which one we'll extract the final transforms)
        m_trans_mat = Matrix()

        # strip the line
        data = line.split()

        # test if the line is not commented out
        if data and not data[0].startswith("#"):

            # set the frame number basing on the chan file
            scene.frame_set(int(data[0]))

            # read the translation values from the first three columns of line
            v_transl = Vector((float(data[1]), float(data[2]), float(data[3])))
            translation_mat = Matrix.Translation(v_transl)
            translation_mat.to_4x4()

            # read the rotations, and set the rotation order basing on the
            # order set during the export (it's not being saved in the chan
            # file you have to keep it noted somewhere
            # the actual objects rotation order doesn't matter since the
            # rotations are being extracted from the matrix afterwards
            e_rot = Euler((radians(float(data[4])), radians(float(data[5])),
                           radians(float(data[6]))))
            e_rot.order = rot_ord
            mrot_mat = e_rot.to_matrix()
            mrot_mat.resize_4x4()

            # merge the rotation and translation
            m_trans_mat = translation_mat @ mrot_mat

            # correct the world space
            # (nuke's and blenders scene spaces are different)
            if z_up:
                m_trans_mat = rot_mat @ m_trans_mat

            # break the matrix into a set of the coordinates
            trns = m_trans_mat.decompose()

            # set the location and the location's keyframe
            obj.location = trns[0]
            obj.keyframe_insert("location")

            # convert the rotation to euler angles (or not)
            # basing on the objects rotation mode
            if obj.rotation_mode == 'QUATERNION':
                obj.rotation_quaternion = trns[1]
                obj.keyframe_insert("rotation_quaternion")
            elif obj.rotation_mode == 'AXIS_ANGLE':
                tmp_rot = trns[1].to_axis_angle()
                obj.rotation_axis_angle = (tmp_rot[1], *tmp_rot[0])
                obj.keyframe_insert("rotation_axis_angle")
                del tmp_rot
            else:
                obj.rotation_euler = trns[1].to_euler(obj.rotation_mode)
                obj.keyframe_insert("rotation_euler")

            # check if the object is camera and fov data is present
            if camera and len(data) > 7:
                camera.sensor_fit = 'HORIZONTAL'
                camera.sensor_width = sensor_width
                camera.sensor_height = sensor_height
                camera.angle_y = radians(float(data[7]))
                camera.keyframe_insert("lens")
    filehandle.close()

    return {'FINISHED'}
コード例 #19
0
def bvh_node_dict2armature(context,
                           bvh_name,
                           bvh_nodes,
                           rotate_mode='XYZ',
                           frame_start=1,
                           IMPORT_LOOP=False):

    if frame_start < 1:
        frame_start = 1

    # Add the new armature,
    scene = context.scene
    for obj in scene.objects:
        obj.select = False

    arm_data = bpy.data.armatures.new(bvh_name)
    arm_ob = bpy.data.objects.new(bvh_name, arm_data)

    scene.objects.link(arm_ob)

    arm_ob.select = True
    scene.objects.active = arm_ob

    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)

    # Get the average bone length for zero length bones, we may not use this.
    average_bone_length = 0.0
    nonzero_count = 0
    for bvh_node in bvh_nodes.values():
        l = (bvh_node.rest_head_local - bvh_node.rest_tail_local).length
        if l:
            average_bone_length += l
            nonzero_count += 1

    # Very rare cases all bones couldbe zero length???
    if not average_bone_length:
        average_bone_length = 0.1
    else:
        # Normal operation
        average_bone_length = average_bone_length / nonzero_count

    # XXX, annoying, remove bone.
    while arm_data.edit_bones:
        arm_ob.edit_bones.remove(arm_data.edit_bones[-1])

    ZERO_AREA_BONES = []
    for name, bvh_node in bvh_nodes.items():
        # New editbone
        bone = bvh_node.temp = arm_data.edit_bones.new(name)

        bone.head = bvh_node.rest_head_world
        bone.tail = bvh_node.rest_tail_world

        # ZERO AREA BONES.
        if (bone.head - bone.tail).length < 0.001:
            if bvh_node.parent:
                ofs = bvh_node.parent.rest_head_local - bvh_node.parent.rest_tail_local
                if ofs.length:  # is our parent zero length also?? unlikely
                    bone.tail = bone.tail + ofs
                else:
                    bone.tail.y = bone.tail.y + average_bone_length
            else:
                bone.tail.y = bone.tail.y + average_bone_length

            ZERO_AREA_BONES.append(bone.name)

    for bvh_node in bvh_nodes.values():
        if bvh_node.parent:
            # bvh_node.temp is the Editbone

            # Set the bone parent
            bvh_node.temp.parent = bvh_node.parent.temp

            # Set the connection state
            if not bvh_node.has_loc and\
            bvh_node.parent and\
            bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
            bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
                bvh_node.temp.use_connect = True

    # Replace the editbone with the editbone name,
    # to avoid memory errors accessing the editbone outside editmode
    for bvh_node in bvh_nodes.values():
        bvh_node.temp = bvh_node.temp.name

    # Now Apply the animation to the armature

    # Get armature animation data
    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

    pose = arm_ob.pose
    pose_bones = pose.bones

    if rotate_mode == 'NATIVE':
        for bvh_node in bvh_nodes.values():
            bone_name = bvh_node.temp  # may not be the same name as the bvh_node, could have been shortened.
            pose_bone = pose_bones[bone_name]
            pose_bone.rotation_mode = bvh_node.rot_order_str

    elif rotate_mode != 'QUATERNION':
        for pose_bone in pose_bones:
            pose_bone.rotation_mode = rotate_mode
    else:
        # Quats default
        pass

    context.scene.update()

    arm_ob.animation_data_create()
    action = bpy.data.actions.new(name=bvh_name)
    arm_ob.animation_data.action = action

    # Replace the bvh_node.temp (currently an editbone)
    # With a tuple  (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv)
    for bvh_node in bvh_nodes.values():
        bone_name = bvh_node.temp  # may not be the same name as the bvh_node, could have been shortened.
        pose_bone = pose_bones[bone_name]
        rest_bone = arm_data.bones[bone_name]
        bone_rest_matrix = rest_bone.matrix_local.to_3x3()

        bone_rest_matrix_inv = Matrix(bone_rest_matrix)
        bone_rest_matrix_inv.invert()

        bone_rest_matrix_inv.resize_4x4()
        bone_rest_matrix.resize_4x4()
        bvh_node.temp = (pose_bone, bone, bone_rest_matrix,
                         bone_rest_matrix_inv)

    # Make a dict for fast access without rebuilding a list all the time.

    # KEYFRAME METHOD, SLOW, USE IPOS DIRECT
    # TODO: use f-point samples instead (Aligorith)
    if rotate_mode != 'QUATERNION':
        prev_euler = [Euler() for i in range(len(bvh_nodes))]

    # Animate the data, the last used bvh_node will do since they all have the same number of frames
    for frame_current in range(len(bvh_node.anim_data) -
                               1):  # skip the first frame (rest frame)
        # print frame_current

        # if frame_current==40: # debugging
        # 	break

        scene.frame_set(frame_start + frame_current)

        # Dont neet to set the current frame
        for i, bvh_node in enumerate(bvh_nodes.values()):
            pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv = bvh_node.temp
            lx, ly, lz, rx, ry, rz = bvh_node.anim_data[frame_current + 1]

            if bvh_node.has_rot:
                # apply rotation order and convert to XYZ
                # note that the rot_order_str is reversed.
                bone_rotation_matrix = Euler(
                    (rx, ry, rz),
                    bvh_node.rot_order_str[::-1]).to_matrix().to_4x4()
                bone_rotation_matrix = bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix

                if rotate_mode == 'QUATERNION':
                    pose_bone.rotation_quaternion = bone_rotation_matrix.to_quaternion(
                    )
                else:
                    euler = bone_rotation_matrix.to_euler(
                        bvh_node.rot_order_str, prev_euler[i])
                    pose_bone.rotation_euler = euler
                    prev_euler[i] = euler

            if bvh_node.has_loc:
                pose_bone.location = (
                    bone_rest_matrix_inv * Matrix.Translation(
                        Vector((lx, ly, lz)) -
                        bvh_node.rest_head_local)).to_translation()

            if bvh_node.has_loc:
                pose_bone.keyframe_insert("location")
            if bvh_node.has_rot:
                if rotate_mode == 'QUATERNION':
                    pose_bone.keyframe_insert("rotation_quaternion")
                else:
                    pose_bone.keyframe_insert("rotation_euler")

    for cu in action.fcurves:
        if IMPORT_LOOP:
            pass  # 2.5 doenst have cyclic now?

        for bez in cu.keyframe_points:
            bez.interpolation = 'LINEAR'

    return arm_ob
コード例 #20
0
    def _core(self, context, ob, verts, to_del=[]):
        mat_wrld = np.array(ob.matrix_world)
        in_editmode = context.mode == 'EDIT_MESH'

        if self.align_to_axes:
            # If we align sources to world axes, we are interested in
            # the bounds in world coordinates.
            verts = sbt.transf_pts(mat_wrld, verts)
            # If we align sources to axes, we ignore ob's rotation.
            rotation = Euler()

        bounds, center = sbio.get_bounds_and_center(verts)

        if not self.align_to_axes:
            # Even though we want the ob bounds in object space if align
            # to axes is false, we still are interested in world scale
            # and center.
            bounds *= np.array(ob.matrix_world.to_scale())
            center = sbt.transf_point(mat_wrld, center)
            rotation = ob.matrix_world.to_euler()

        if self.delete_original and in_editmode:
            mode = context.tool_settings.mesh_select_mode
            if mode[0]:
                del_type = 'VERTS'
            elif mode[1]:
                del_type = 'EDGES'
            else:
                del_type = 'FACES'
            for o in to_del:
                sbmm.remove_selection(o.data, type=del_type)

        if self.replace_by == 'CYLINDER_Z':
            bpy.ops.mesh.primitive_cylinder_add(
                {'active_object': ob},
                vertices=self.resolution,
                radius=self.metric(bounds[:2]) * 0.5,
                depth=bounds[2],
                end_fill_type='TRIFAN',
                location=center,
                rotation=rotation)
        elif self.replace_by == 'CYLINDER_Y':
            rotation.rotate(Euler((1.57, 0.0, 0.0)))
            bpy.ops.mesh.primitive_cylinder_add(
                {'active_object': ob},
                vertices=self.resolution,
                radius=self.metric(bounds[::2]) * 0.5,
                depth=bounds[1],
                end_fill_type='TRIFAN',
                location=center,
                rotation=rotation)
        elif self.replace_by == 'CYLINDER_X':
            rotation.rotate(Euler((0.0, 1.57, 0.0)))
            bpy.ops.mesh.primitive_cylinder_add(
                {'active_object': ob},
                vertices=self.resolution,
                radius=self.metric(bounds[1:]) * 0.5,
                depth=bounds[0],
                end_fill_type='TRIFAN',
                location=center,
                rotation=rotation)
        elif self.replace_by == 'CUBOID':
            if in_editmode:
                sbmm.add_box_to_obj(
                    ob=ob,
                    location=center,
                    rotation=rotation,
                    size=bounds)
            else:
                sbmm.add_box_to_scene(context, center, rotation, bounds)
        elif self.replace_by == 'SPHERE':
            bpy.ops.mesh.primitive_uv_sphere_add(
                {'active_object': ob},
                segments=self.resolution * 2,
                ring_count=self.resolution,
                radius=self.metric(bounds) * 0.5,
                location=center,
                rotation=rotation)

        if not in_editmode:
            # apply material if existent in original
            try:
                mat = ob.data.materials[0]
            except IndexError:
                pass
            else:
                context.object.data.materials.append(mat)

            if self.delete_original:
                for o in to_del:
                    bpy.data.objects.remove(o)
コード例 #21
0
def blen_read_object(fbx_tmpl, fbx_obj, object_data):
    elem_name, elem_class = elem_split_name_class(fbx_obj)
    elem_name_utf8 = elem_name.decode('utf-8')

    const_vector_zero_3d = 0.0, 0.0, 0.0
    const_vector_one_3d = 1.0, 1.0, 1.0

    # Object data must be created already
    obj = bpy.data.objects.new(name=elem_name_utf8, object_data=object_data)

    fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
                 elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
    assert(fbx_props[0] is not None)

    # ----
    # Misc Attributes

    obj.color[0:3] = elem_props_get_color_rgb(fbx_props, b'Color', (0.8, 0.8, 0.8))

    # ----
    # Transformation

    # This is quite involved, 'fbxRNode.cpp' from openscenegraph used as a reference

    loc = elem_props_get_vector_3d(fbx_props, b'Lcl Translation', const_vector_zero_3d)
    rot = elem_props_get_vector_3d(fbx_props, b'Lcl Rotation', const_vector_zero_3d)
    sca = elem_props_get_vector_3d(fbx_props, b'Lcl Scaling', const_vector_one_3d)

    rot_ofs = elem_props_get_vector_3d(fbx_props, b'RotationOffset', const_vector_zero_3d)
    rot_piv = elem_props_get_vector_3d(fbx_props, b'RotationPivot', const_vector_zero_3d)
    sca_ofs = elem_props_get_vector_3d(fbx_props, b'ScalingOffset', const_vector_zero_3d)
    sca_piv = elem_props_get_vector_3d(fbx_props, b'ScalingPivot', const_vector_zero_3d)

    is_rot_act = elem_props_get_bool(fbx_props, b'RotationActive', False)

    if is_rot_act:
        pre_rot = elem_props_get_vector_3d(fbx_props, b'PreRotation', const_vector_zero_3d)
        pst_rot = elem_props_get_vector_3d(fbx_props, b'PostRotation', const_vector_zero_3d)
        rot_ord = {
            0: 'XYZ',
            1: 'XYZ',
            2: 'XZY',
            3: 'YZX',
            4: 'YXZ',
            5: 'ZXY',
            6: 'ZYX',
            }.get(elem_props_get_enum(fbx_props, b'RotationOrder', 0))
    else:
        pre_rot = const_vector_zero_3d
        pst_rot = const_vector_zero_3d
        rot_ord = 'XYZ'

    from mathutils import Matrix, Euler
    from math import pi

    # translation
    lcl_translation = Matrix.Translation(loc)

    # rotation
    if obj.type == 'CAMERA':
        rot_alt_mat = Matrix.Rotation(pi / -2.0, 4, 'Y')
    elif obj.type == 'LAMP':
        rot_alt_mat = Matrix.Rotation(pi / -2.0, 4, 'X')
    else:
        rot_alt_mat = Matrix()

    # rotation
    lcl_rot = Euler(tuple_deg_to_rad(rot), rot_ord).to_matrix().to_4x4() * rot_alt_mat
    pre_rot = Euler(tuple_deg_to_rad(pre_rot), rot_ord).to_matrix().to_4x4()
    pst_rot = Euler(tuple_deg_to_rad(pst_rot), rot_ord).to_matrix().to_4x4()

    rot_ofs = Matrix.Translation(rot_ofs)
    rot_piv = Matrix.Translation(rot_piv)
    sca_ofs = Matrix.Translation(sca_ofs)
    sca_piv = Matrix.Translation(sca_piv)

    # scale
    lcl_scale = Matrix()
    lcl_scale[0][0], lcl_scale[1][1], lcl_scale[2][2] = sca

    obj.matrix_basis = (
        lcl_translation *
        rot_ofs *
        rot_piv *
        pre_rot *
        lcl_rot *
        pst_rot *
        rot_piv.inverted() *
        sca_ofs *
        sca_piv *
        lcl_scale *
        sca_piv.inverted()
        )

    return obj
コード例 #22
0
def main():
    # time logging
    global start_time
    start_time = time.time()

    import argparse
    
    # parse commandline arguments
    log_message(sys.argv)
    parser = argparse.ArgumentParser(description='Generate synth dataset images.')
    parser.add_argument('--idx', type=int,
                        help='idx of the requested sequence')
    parser.add_argument('--name', type=str,
                            help='name of the requested sequence')
    parser.add_argument('--ishape', type=int,
                        help='requested cut, according to the stride')
    parser.add_argument('--stride', type=int,
                        help='stride amount, default 50')
    parser.add_argument('--direction', type=str,
                            help='subject direction, default forward')
    parser.add_argument('--subject_id', type=int,
                                help='local subject id, default 0')

    args = parser.parse_args(sys.argv[sys.argv.index("---") + 1:])
    
    idx = args.idx
    name = args.name
    ishape = args.ishape
    stride = args.stride
    direction = args.direction
    subject_id = args.subject_id


    log_message("input idx: %d" % idx)
    log_message("input name: %s" % name)
    log_message("input ishape: %d" % ishape)
    log_message("input stride: %d" % stride)
    log_message("Subject direction: %s" % direction)
    log_message("Local subject id: %d" % subject_id)

    if idx == None:
        exit(1)
    if ishape == None:
        exit(1)
    if stride == None:
        log_message("WARNING: stride not specified, using default value 50")
        stride = 50
    
    # import idx info (name, split)
    idx_info = load(open("pkl/idx_info.pickle", 'rb'))
    # get runpass
    (runpass, idx) = divmod(idx, len(idx_info))
    
    log_message("runpass: %d" % runpass)
    log_message("output idx: %d" % idx)
    
    for dic in idx_info:
        if dic['name'] == name:
            idx_info = dic
            break
    else:
        idx_info = idx_info[idx]

    log_message("sequence: %s" % idx_info['name'])
    log_message("nb_frames: %f" % idx_info['nb_frames'])
    #log_message("use_split: %s" % idx_info['use_split'])

    # import configuration
    log_message("Importing configuration")
    import config
    params = config.load_file('config', 'SYNTH_DATA')
   
    smpl_data_folder = params['smpl_data_folder']
    smpl_data_filename = params['smpl_data_filename']
    bg_path = params['bg_path']
    resy = params['resy']
    resx = params['resx']
    clothing_option = params['clothing_option'] # grey, nongrey or all
    tmp_path = params['tmp_path']
    output_path = params['output_path']
    output_types = params['output_types']
    stepsize = params['stepsize']
    clipsize = params['clipsize']
    openexr_py2_path = params['openexr_py2_path']

    # compute number of cuts
    nb_ishape = max(1, int(np.ceil((idx_info['nb_frames'] - (clipsize - stride))/stride)))
    log_message("Max ishape: %d" % (nb_ishape - 1))
    
    if ishape == None:
        exit(1)
    
    assert(ishape < nb_ishape)
    
    # name is set given idx
    name = idx_info['name']
    output_path = join(output_path, 'run%d' % runpass, name.replace(" ", ""))
    params['output_path'] = output_path
    tmp_path = join(tmp_path, 'run%d_%s_c%04d' % (runpass, name.replace(" ", ""), (ishape + 1)))
    params['tmp_path'] = tmp_path
    
    # check if already computed
    #  + clean up existing tmp folders if any
    if exists(tmp_path) and tmp_path != "" and tmp_path != "/":
        os.system('rm -rf %s' % tmp_path)
    rgb_vid_filename = "%s_c%04d.mp4" % (join(output_path, name.replace(' ', '')), (ishape + 1))
    
    # create tmp directory
    if not exists(tmp_path):
        mkdir_safe(tmp_path)
    
    # >> don't use random generator before this point <<

    # initialize RNG with seeds from sequence id
    import hashlib
    s = "synth_data:%d:%d:%d" % (idx, runpass,ishape)
    seed_number = int(hashlib.sha1(s.encode('utf-8')).hexdigest(), 16) % (10 ** 8)
    log_message("GENERATED SEED %d from string '%s'" % (seed_number, s))
    random.seed(seed_number)
    np.random.seed(seed_number)
    
    if(output_types['vblur']):
        vblur_factor = np.random.normal(0.5, 0.5)
        params['vblur_factor'] = vblur_factor
    
    log_message("Setup Blender")

    # create copy-spher.harm. directory if not exists
    sh_dir = join(tmp_path, 'spher_harm')
    if not exists(sh_dir):
        mkdir_safe(sh_dir)
    sh_dst = join(sh_dir, 'sh_%02d_%05d.osl' % (runpass, idx))
    os.system('cp spher_harm/sh.osl %s' % sh_dst)

    genders = {0: 'male', 1: 'female'}
    # pick random gender
    gender = genders[subject_id % 2]#choice(genders)

    scene = bpy.data.scenes['Scene']
    scene.render.engine = 'CYCLES'
    bpy.data.materials['Material'].use_nodes = True
    scene.cycles.shading_system = True
    scene.use_nodes = True

    log_message("Listing background images")
    #bg_names = join(bg_path, '%s_img.txt' % idx_info['use_split'])
    bg_names = join(bg_path, 'bg.txt')
    nh_txt_paths = []
    with open(bg_names) as f:
        for line in f:
            nh_txt_paths.append(join(bg_path, line))

    # grab clothing names
    log_message("clothing: %s" % clothing_option)
    with open( join(smpl_data_folder, 'textures', '%s_train.txt' % gender) ) as f:
        txt_paths = f.read().splitlines()

    # if using only one source of clothing
    if clothing_option == 'nongrey':
        txt_paths = [k for k in txt_paths if 'nongrey' in k]
    elif clothing_option == 'grey':
        txt_paths = [k for k in txt_paths if 'nongrey' not in k]
    
    # random clothing texture
    cloth_img_name = txt_paths[subject_id]#choice(txt_paths)
    cloth_img_name = join(smpl_data_folder, cloth_img_name)
    cloth_img = bpy.data.images.load(cloth_img_name)

    # random background
    bg_img_name = choice(nh_txt_paths)[:-1]
    bg_img = bpy.data.images.load(bg_img_name)

    log_message("Loading parts segmentation")
    beta_stds = np.load(join(smpl_data_folder, ('%s_beta_stds.npy' % gender)))
    
    log_message("Building materials tree")
    mat_tree = bpy.data.materials['Material'].node_tree
    create_sh_material(mat_tree, sh_dst, cloth_img)
    res_paths = create_composite_nodes(scene.node_tree, params, img=bg_img, idx=idx)

    log_message("Loading smpl data")
    smpl_data = np.load(join(smpl_data_folder, smpl_data_filename))
    
    log_message("Initializing scene")
    camera_distance = 11.#np.random.normal(8.0, 1)
    params['camera_distance'] = camera_distance
    ob, obname, arm_ob, cam_ob = init_scene(scene, params, gender)

    setState0()
    ob.select = True
    bpy.context.scene.objects.active = ob
    segmented_materials = True #True: 0-24, False: expected to have 0-1 bg/fg
    
    log_message("Creating materials segmentation")
    # create material segmentation
    if segmented_materials:
        materials = create_segmentation(ob, params)
        prob_dressed = {'leftLeg':.5, 'leftArm':.9, 'leftHandIndex1':.01,
                        'rightShoulder':.8, 'rightHand':.01, 'neck':.01,
                        'rightToeBase':.9, 'leftShoulder':.8, 'leftToeBase':.9,
                        'rightForeArm':.5, 'leftHand':.01, 'spine':.9,
                        'leftFoot':.9, 'leftUpLeg':.9, 'rightUpLeg':.9,
                        'rightFoot':.9, 'head':.01, 'leftForeArm':.5,
                        'rightArm':.5, 'spine1':.9, 'hips':.9,
                        'rightHandIndex1':.01, 'spine2':.9, 'rightLeg':.5}
    else:
        materials = {'FullBody': bpy.data.materials['Material']}
        prob_dressed = {'FullBody': .6}

    orig_pelvis_loc = None
    random_zrot = get_zrot(name, direction)
    if direction == 'forward':
        orig_pelvis_loc = (arm_ob.matrix_world.copy() * arm_ob.pose.bones[obname+'_Pelvis'].head.copy()) - Vector((-1., 0.75, -1.15))
    elif direction == 'backward':
        orig_pelvis_loc = (arm_ob.matrix_world.copy() * arm_ob.pose.bones[obname+'_Pelvis'].head.copy()) - Vector((-1., 0.75, 3.1))

    orig_cam_loc = cam_ob.location.copy()
    print ("CAM LOC:", orig_cam_loc, type(orig_cam_loc))

    # unblocking both the pose and the blendshape limits
    for k in ob.data.shape_keys.key_blocks.keys():
        bpy.data.shape_keys["Key"].key_blocks[k].slider_min = -10
        bpy.data.shape_keys["Key"].key_blocks[k].slider_max = 10

    log_message("Loading body data")
    cmu_parms, fshapes, name = load_body_data(smpl_data, ob, obname, name, gender=gender)
    
    log_message("Loaded body data for %s" % name)
    
    nb_fshapes = len(fshapes)
    #if idx_info['use_split'] == 'train':
    #    fshapes = fshapes[:int(nb_fshapes*0.8)]
    #elif idx_info['use_split'] == 'test':
    #    fshapes = fshapes[int(nb_fshapes*0.8):]
    
    # pick random real body shape
    shape = fshapes[subject_id]#choice(fshapes) #+random_shape(.5) can add noise
    #shape = random_shape(3.) # random body shape
    
    ndofs = 10

    scene.objects.active = arm_ob
    orig_trans = np.asarray(arm_ob.pose.bones[obname+'_Pelvis'].location).copy()
	
    # create output directory
    if not exists(output_path):
        mkdir_safe(output_path)

    # spherical harmonics material needs a script to be loaded and compiled
    scs = []
    for mname, material in materials.items():
        scs.append(material.node_tree.nodes['Script'])
        scs[-1].filepath = sh_dst
        scs[-1].update()

    rgb_dirname = name.replace(" ", "") + '_c%04d.mp4' % (ishape + 1)
    rgb_path = join(tmp_path, rgb_dirname)

    data = cmu_parms[name]
    data = cut_sequence(name, data)

    fbegin = ishape*stepsize*stride
    fend = min(ishape*stepsize*stride + stepsize*clipsize, len(data['poses']))
    
    log_message("Computing how many frames to allocate")
    N = len(data['poses'][fbegin:fend:stepsize])
    log_message("Allocating %d frames in mat file" % N)

    # force recomputation of joint angles unless shape is all zeros
    curr_shape = np.zeros_like(shape)
    nframes = len(data['poses'][::stepsize])

    matfile_info = join(output_path, name.replace(" ", "") + "_c%04d_info.mat" % (ishape+1))
    log_message('Working on %s' % matfile_info)

    # allocate
    dict_info = {}
    dict_info['bg'] = np.zeros((N,), dtype=np.object) # background image path
    dict_info['camLoc'] = np.empty(3) # (1, 3)
    dict_info['clipNo'] = ishape +1
    dict_info['cloth'] = np.zeros((N,), dtype=np.object) # clothing texture image path
    dict_info['gender'] = np.empty(N, dtype='uint8') # 0 for male, 1 for female
    dict_info['joints2D'] = np.empty((2, 24, N), dtype='float32') # 2D joint positions in pixel space
    dict_info['joints3D'] = np.empty((3, 24, N), dtype='float32') # 3D joint positions in world coordinates
    dict_info['light'] = np.empty((9, N), dtype='float32')
    dict_info['pose'] = np.empty((data['poses'][0].size, N), dtype='float32') # joint angles from SMPL (CMU)
    dict_info['sequence'] = name.replace(" ", "") + "_c%04d" % (ishape + 1)
    dict_info['shape'] = np.empty((ndofs, N), dtype='float32')
    dict_info['zrot'] = np.empty(N, dtype='float32')
    dict_info['camDist'] = camera_distance
    dict_info['stride'] = stride

    if name.replace(" ", "").startswith('h36m'):
        dict_info['source'] = 'h36m'
    else:
        dict_info['source'] = 'cmu'

    if(output_types['vblur']):
        dict_info['vblur_factor'] = np.empty(N, dtype='float32')

    # for each clipsize'th frame in the sequence
    get_real_frame = lambda ifr: ifr
    reset_loc = False
    batch_it = 0
    curr_shape = reset_joint_positions(orig_trans, shape, ob, arm_ob, obname, scene,
                                       cam_ob, smpl_data['regression_verts'], smpl_data['joint_regressor'])
    arm_ob.animation_data_clear()
    cam_ob.animation_data_clear()

    # create a keyframe animation with pose, translation, blendshapes and camera motion
    # LOOP TO CREATE 3D ANIMATION
    mocap_pose, mocap_shape = read_mocap('/home/local/mocap/3d_smpl/samples/model_gt_2d/gait_pretrained_'+str(subject_id)+'.mat')
    #mocap_pose, mocap_shape = read_mocap('/home/local/mocap/3d_smpl/samples/model_reconstruct_2d/gait_pretrained_'+str(subject_id)+'.mat')
    #stepsize = 8
    for seq_frame, (pose, trans) in enumerate(zip(data['poses'][fbegin:fend:stepsize], data['trans'][fbegin:fend:stepsize])):
        iframe = seq_frame
        if iframe == 122:
            break
        scene.frame_set(get_real_frame(seq_frame))
        
        # apply the translation, pose and shape to the character
        mocap_pose[iframe][:3] = pose[:3]
        apply_trans_pose_shape(Vector(trans), mocap_pose[iframe], mocap_shape, ob, arm_ob, obname, scene, cam_ob, get_real_frame(seq_frame))
        #apply_trans_pose_shape(Vector(trans), pose, shape, ob, arm_ob, obname, scene, cam_ob, get_real_frame(seq_frame))
        dict_info['shape'][:, iframe] = shape[:ndofs]
        dict_info['pose'][:, iframe] = pose
        dict_info['gender'][iframe] = list(genders)[list(genders.values()).index(gender)]
        if(output_types['vblur']):
            dict_info['vblur_factor'][iframe] = vblur_factor

        arm_ob.pose.bones[obname+'_root'].rotation_quaternion = Quaternion(Euler((0, 0, random_zrot), 'XYZ'))
        arm_ob.pose.bones[obname+'_root'].keyframe_insert('rotation_quaternion', frame=get_real_frame(seq_frame))
        dict_info['zrot'][iframe] = random_zrot

        scene.update()

        # Bodies centered only in each minibatch of clipsize frames
        if seq_frame == 0 or reset_loc: 
            reset_loc = False
            new_pelvis_loc = arm_ob.matrix_world.copy() * arm_ob.pose.bones[obname+'_Pelvis'].head.copy()
            cam_ob.location = orig_cam_loc.copy() + (new_pelvis_loc.copy() - orig_pelvis_loc.copy())
            cam_ob.keyframe_insert('location', frame=get_real_frame(seq_frame))
            dict_info['camLoc'] = np.array(cam_ob.location)

    scene.node_tree.nodes['Image'].image = bg_img

    for part, material in materials.items():
        material.node_tree.nodes['Vector Math'].inputs[1].default_value[:2] = (0, 0)

    # random light
    sh_coeffs = .7 * (2 * np.random.rand(9) - 1)
    sh_coeffs[0] = .5 + .9 * np.random.rand() # Ambient light (first coeff) needs a minimum  is ambient. Rest is uniformly distributed, higher means brighter.
    sh_coeffs[1] = -.7 * np.random.rand()

    for ish, coeff in enumerate(sh_coeffs):
        for sc in scs:
            sc.inputs[ish+1].default_value = coeff

    # iterate over the keyframes and render
    # LOOP TO RENDER
    for seq_frame, (pose, trans) in enumerate(zip(data['poses'][fbegin:fend:stepsize], data['trans'][fbegin:fend:stepsize])):
        scene.frame_set(get_real_frame(seq_frame))
        iframe = seq_frame
        
        if iframe == 122:#60:
            break

        dict_info['bg'][iframe] = bg_img_name
        dict_info['cloth'][iframe] = cloth_img_name
        dict_info['light'][:, iframe] = sh_coeffs

        img_path = join(rgb_path, 'Image%04d.png' % get_real_frame(seq_frame))
        scene.render.use_antialiasing = False
        scene.render.filepath = img_path

        log_message("Rendering frame %d" % seq_frame)
        
        # disable render output
        logfile = '/dev/null'
        open(logfile, 'a').close()
        old = os.dup(1)
        sys.stdout.flush()
        os.close(1)
        os.open(logfile, os.O_WRONLY)

        # Render
        bpy.ops.render.render(write_still=True)

        # disable output redirection
        os.close(1)
        os.dup(old)
        os.close(old)

        # bone locations should be saved after rendering so that the bones are updated
        bone_locs_2D, bone_locs_3D = get_bone_locs(obname, arm_ob, scene, cam_ob)
        dict_info['joints2D'][:, :, iframe] = np.transpose(bone_locs_2D)
        dict_info['joints3D'][:, :, iframe] = np.transpose(bone_locs_3D)

        if is_visualization:
            draw_skeleton(img_path, dict_info['joints2D'][:, :, iframe])

        reset_loc = (bone_locs_2D.max(axis=-1) > 256).any() or (bone_locs_2D.min(axis=0) < 0).any()
        arm_ob.pose.bones[obname+'_root'].rotation_quaternion = Quaternion((1, 0, 0, 0))

    # save a .blend file for debugging:
    # bpy.ops.wm.save_as_mainfile(filepath=join(tmp_path, 'pre.blend'))
    
    # save RGB data with ffmpeg (if you don't have h264 codec, you can replace with another one and control the quality with something like -q:v 3)
    cmd_ffmpeg = 'ffmpeg -y -r 25 -i ''%s'' -c:v h264 -pix_fmt yuv420p -crf 23 ''%s_c%04d.mp4''' % (join(rgb_path, 'Image%04d.png'), join(output_path, name.replace(' ', '')), (ishape + 1))
    log_message("Generating RGB video (%s)" % cmd_ffmpeg)
    os.system(cmd_ffmpeg)
    
    if(output_types['vblur']):
        cmd_ffmpeg_vblur = 'ffmpeg -y -r 25 -i ''%s'' -c:v h264 -pix_fmt yuv420p -crf 23 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" ''%s_c%04d.mp4''' % (join(res_paths['vblur'], 'Image%04d.png'), join(output_path, name.replace(' ', '')+'_vblur'), (ishape + 1))
        log_message("Generating vblur video (%s)" % cmd_ffmpeg_vblur)
        os.system(cmd_ffmpeg_vblur)
   
    if(output_types['fg']):
        cmd_ffmpeg_fg = 'ffmpeg -y -r 25 -i ''%s'' -c:v h264 -pix_fmt yuv420p -crf 23 ''%s_c%04d.mp4''' % (join(res_paths['fg'], 'Image%04d.png'), join(output_path, name.replace(' ', '')+'_fg'), (ishape + 1))
        log_message("Generating fg video (%s)" % cmd_ffmpeg_fg)
        os.system(cmd_ffmpeg_fg)
   
    cmd_tar = 'tar -czvf %s/%s.tar.gz -C %s %s' % (output_path, rgb_dirname, tmp_path, rgb_dirname)
    log_message("Tarballing the images (%s)" % cmd_tar)
    os.system(cmd_tar)
    
    # save annotation excluding png/exr data to _info.mat file
    import scipy.io
    scipy.io.savemat(matfile_info, dict_info, do_compression=True)
コード例 #23
0
faces = [(0, 1, 2, 3), (4, 5, 6, 7)]
mesh = bpy.data.meshes.new("Xpos")
obj = bpy.data.objects.new("Xpos", mesh)
bpy.context.scene.objects.link(obj)
mesh.from_pydata(verts, [], faces)
mesh.update(calc_edges=True)
bpy.data.objects["Xpos"].data.materials.append(
    material_options["wall"][randint(0,
                                     len(material_options["wall"]) - 1)])

# place corridor Y+
bpy.ops.object.select_all(action="DESELECT")
bpy.data.objects["Xpos"].select = True
bpy.ops.object.duplicate()
bpy.data.objects["Xpos.001"].name = "Ypos"
bpy.data.objects["Ypos"].rotation_euler = Euler((0, 0, math.radians(90)))

# place corridor X-
bpy.ops.object.select_all(action="DESELECT")
bpy.data.objects["Xpos"].select = True
bpy.ops.object.duplicate()
bpy.data.objects["Xpos.001"].name = "Xneg"
bpy.data.objects["Xneg"].rotation_euler = Euler((0, 0, math.radians(180)))

# place corridor Y-
bpy.ops.object.select_all(action="DESELECT")
bpy.data.objects["Xpos"].select = True
bpy.ops.object.duplicate()
bpy.data.objects["Xpos.001"].name = "Yneg"
bpy.data.objects["Yneg"].rotation_euler = Euler((0, 0, math.radians(-90)))
コード例 #24
0
ファイル: loader.py プロジェクト: REDxEYE/SourceIO
    def build_armature(self):
        data_block = self.get_data_block(block_name='DATA')[0]
        model_skeleton = data_block.data['m_modelSkeleton']
        bone_names = model_skeleton['m_boneName']
        bone_positions = model_skeleton['m_bonePosParent']
        bone_rotations = model_skeleton['m_boneRotParent']
        bone_parents = model_skeleton['m_nParent']

        armature_obj = bpy.data.objects.new(
            self.name + "_ARM",
            bpy.data.armatures.new(self.name + "_ARM_DATA"))
        armature_obj['MODE'] = 'SourceIO'
        armature_obj.show_in_front = True
        bpy.context.scene.collection.objects.link(armature_obj)
        bpy.ops.object.select_all(action="DESELECT")
        armature_obj.select_set(True)
        bpy.context.view_layer.objects.active = armature_obj

        armature_obj.rotation_euler = Euler(
            [math.radians(180), 0, math.radians(90)])
        armature = armature_obj.data

        bpy.ops.object.mode_set(mode='EDIT')

        bones = []
        for bone_name in bone_names:
            bl_bone = armature.edit_bones.new(name=bone_name)
            bl_bone.tail = Vector([0, 0, 1]) + bl_bone.head * self.scale
            bones.append((bl_bone, bone_name))

        for n, bone_name in enumerate(bone_names):
            bl_bone = armature.edit_bones.get(bone_name)
            parent_id = bone_parents[n]
            if parent_id != -1:
                bl_parent, parent = bones[parent_id]
                bl_bone.parent = bl_parent

        bpy.ops.object.mode_set(mode='POSE')
        for n, (bl_bone, bone_name) in enumerate(bones):
            pose_bone = armature_obj.pose.bones.get(bone_name)
            if pose_bone is None:
                print("Missing", bone_name, 'bone')
            parent_id = bone_parents[n]
            bone_pos = bone_positions[n]
            bone_rot = bone_rotations[n]
            bone_pos = Vector([bone_pos[1], bone_pos[0], -bone_pos[2]
                               ]) * self.scale
            # noinspection PyTypeChecker
            bone_rot = Quaternion(
                [-bone_rot[3], -bone_rot[1], -bone_rot[0], bone_rot[2]])
            mat = (
                Matrix.Translation(bone_pos) @ bone_rot.to_matrix().to_4x4())
            pose_bone.matrix_basis.identity()

            if parent_id != -1:
                parent_bone = armature_obj.pose.bones.get(
                    bone_names[parent_id])
                pose_bone.matrix = parent_bone.matrix @ mat
            else:
                pose_bone.matrix = mat
        bpy.ops.pose.armature_apply()
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.select_all(action="DESELECT")
        armature_obj.select_set(True)
        bpy.context.view_layer.objects.active = armature_obj
        bpy.ops.object.transform_apply(location=True,
                                       rotation=True,
                                       scale=False)
        bpy.context.scene.collection.objects.unlink(armature_obj)
        return armature_obj
コード例 #25
0
    def render_context_create(engine, objects_ignored):
        if engine == '__SCENE':
            backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data = [
                ()
            ] * 6
            scene = bpy.context.screen.scene
            exclude_props = {('world', ), ('camera', ), ('tool_settings', ),
                             ('preview', )}
            backup_scene = tuple(
                rna_backup_gen(scene, exclude_props=exclude_props))
            world = scene.world
            camera = scene.camera
            if camera:
                camera_data = camera.data
            else:
                backup_camera, backup_camera_data = [None] * 2
                camera_data = bpy.data.cameras.new(
                    "TEMP_preview_render_camera")
                camera = bpy.data.objects.new("TEMP_preview_render_camera",
                                              camera_data)
                camera.rotation_euler = Euler(
                    (1.1635528802871704, 0.0, 0.7853981852531433),
                    'XYZ')  # (66.67, 0.0, 45.0)
                scene.camera = camera
                scene.objects.link(camera)
            # TODO: add lamp if none found in scene?
            lamp = None
            lamp_data = None
        else:
            backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data = [
                None
            ] * 6

            scene = bpy.data.scenes.new("TEMP_preview_render_scene")
            world = bpy.data.worlds.new("TEMP_preview_render_world")
            camera_data = bpy.data.cameras.new("TEMP_preview_render_camera")
            camera = bpy.data.objects.new("TEMP_preview_render_camera",
                                          camera_data)
            lamp_data = bpy.data.lamps.new("TEMP_preview_render_lamp", 'SPOT')
            lamp = bpy.data.objects.new("TEMP_preview_render_lamp", lamp_data)

            objects_ignored.add((camera.name, lamp.name))

            scene.world = world

            camera.rotation_euler = Euler(
                (1.1635528802871704, 0.0, 0.7853981852531433),
                'XYZ')  # (66.67, 0.0, 45.0)
            scene.camera = camera
            scene.objects.link(camera)

            lamp.rotation_euler = Euler(
                (0.7853981852531433, 0.0, 1.7453292608261108),
                'XYZ')  # (45.0, 0.0, 100.0)
            lamp_data.falloff_type = 'CONSTANT'
            lamp_data.spot_size = 1.0471975803375244  # 60
            scene.objects.link(lamp)

            if engine == 'BLENDER_RENDER':
                scene.render.engine = 'BLENDER_RENDER'
                scene.render.alpha_mode = 'TRANSPARENT'

                world.use_sky_blend = True
                world.horizon_color = 0.9, 0.9, 0.9
                world.zenith_color = 0.5, 0.5, 0.5
                world.ambient_color = 0.1, 0.1, 0.1
                world.light_settings.use_environment_light = True
                world.light_settings.environment_energy = 1.0
                world.light_settings.environment_color = 'SKY_COLOR'
            elif engine == 'CYCLES':
                scene.render.engine = 'CYCLES'
                scene.cycles.film_transparent = True
                # TODO: define Cycles world?

        scene.render.image_settings.file_format = 'PNG'
        scene.render.image_settings.color_depth = '8'
        scene.render.image_settings.color_mode = 'RGBA'
        scene.render.image_settings.compression = 25
        scene.render.resolution_x = RENDER_PREVIEW_SIZE
        scene.render.resolution_y = RENDER_PREVIEW_SIZE
        scene.render.resolution_percentage = 100
        scene.render.filepath = os.path.join(bpy.app.tempdir,
                                             'TEMP_preview_render.png')
        scene.render.use_overwrite = True
        scene.render.use_stamp = False

        image = bpy.data.images.new("TEMP_render_image",
                                    RENDER_PREVIEW_SIZE,
                                    RENDER_PREVIEW_SIZE,
                                    alpha=True)
        image.source = 'FILE'
        image.filepath = scene.render.filepath

        return RenderContext(
            scene.name,
            world.name if world else None,
            camera.name,
            lamp.name if lamp else None,
            camera_data.name,
            lamp_data.name if lamp_data else None,
            image.name,
            backup_scene,
            backup_world,
            backup_camera,
            backup_lamp,
            backup_camera_data,
            backup_lamp_data,
        )
コード例 #26
0
def post_rotate_quaternion(quat, angle):
    post = Euler((angle, 0.0, 0.0)).to_matrix()
    mqtn = quat.to_matrix()
    quat = (mqtn*post).to_quaternion()
    return quat
コード例 #27
0
objs = ObjectLoader.load(args.scene)

# define a light and set its location and energy level
light = Light()
light.set_type("POINT")
light.set_location([5, -5, 5])
light.set_energy(1000)

# define the camera intrinsics
CameraUtility.set_intrinsics_from_blender_params(1, 512, 512, lens_unit="FOV")

# read the camera positions file and convert into homogeneous camera-world transformation
with open(args.camera, "r") as f:
    for line in f.readlines():
        line = [float(x) for x in line.split()]
        matrix_world = Matrix.Translation(Vector(line[:3])) @ Euler(line[3:6], 'XYZ').to_matrix().to_4x4()
        CameraUtility.add_camera_pose(matrix_world)

# activate normal and distance rendering
RendererUtility.enable_normals_output()
RendererUtility.enable_distance_output()
# set the amount of samples, which should be used for the color rendering
RendererUtility.set_samples(350)

# render the whole pipeline
data = RendererUtility.render()

# post process the data and remove the redundant channels in the distance image
data["distance"] = PostProcessingUtility.trim_redundant_channels(data["distance"])

# write the data to a .hdf5 container
コード例 #28
0
def scan_advanced(scanner_object, simulation_fps=24, evd_file=None,noise_mu=0.0, evd_last_scan=True, add_blender_mesh = False, add_noisy_blender_mesh = False, simulation_time = 0.0,laser_mirror_distance=0.05, world_transformation=Matrix()):
    
    
    angle_resolution=scanner_object.generic_angle_resolution
    max_distance=scanner_object.generic_max_dist
    start_angle=scanner_object.generic_start_angle
    end_angle=scanner_object.generic_end_angle
    noise_mu = scanner_object.generic_noise_mu
    noise_sigma=scanner_object.generic_noise_sigma
    laser_angles = scanner_object.generic_laser_angles
    rotation_speed = scanner_object.generic_rotation_speed

    inv_scan_x = scanner_object.inv_scan_x
    inv_scan_y = scanner_object.inv_scan_y
    inv_scan_z = scanner_object.inv_scan_z    

    """Standard Error model is a Gaussian Distribution"""
    model = gaussian_error_model.GaussianErrorModel(noise_mu, noise_sigma)
    if scanner_object.generic_advanced_error_model:
      """Advanced error model is a list of distance,mu,sigma tuples"""
      model = advanced_error_model.AdvancedErrorModel(scanner_object.generic_advanced_error_model)


    start_time = time.time()

    current_time = simulation_time
    delta_rot = angle_resolution*math.pi/180

    evd_storage = evd.evd_file(evd_file)

    xaxis = Vector([1,0,0])
    yaxis = Vector([0,1,0])
    zaxis = Vector([0,0,1])

    rays = []
    ray_info = []

    angles = end_angle-start_angle
    steps_per_rotation = angles/angle_resolution
    time_per_step = (1.0/rotation_speed) / steps_per_rotation

    lines = (end_angle-start_angle)/angle_resolution

    laser_angles = angles_from_string(laser_angles)


    rays = []
    ray_info = []

    #Bad code???
    #steps_per_rotation = 360.0/angle_resolution
    #time_per_step = (1.0 / rotation_speed) / steps_per_rotation
    #angles = end_angle-start_angle
  
    lines = (end_angle-start_angle)/angle_resolution
    ray = Vector([0.0,0.0,0.0])
    for line in range(int(lines)):
        for laser_idx in range(len(laser_angles)):
            ray.xyz = [0,0,max_distance]
            rot_angle = 1e-6 + start_angle+float(line)*angle_resolution + 180.0
            timestamp = ( (rot_angle-180.0)/angle_resolution) * time_per_step 
            rot_angle = rot_angle%360.0
            ray_info.append([deg2rad(rot_angle), deg2rad(laser_angles[laser_idx]), timestamp])
            
            rotator = Euler( [deg2rad(-laser_angles[laser_idx]), deg2rad(rot_angle), 0.0] )
            ray.rotate( rotator )
            rays.extend([ray[0],ray[1],ray[2]])


    returns = blensor.scan_interface.scan_rays(rays, max_distance, inv_scan_x = inv_scan_x, inv_scan_y = inv_scan_y, inv_scan_z = inv_scan_z)

    reusable_vector = Vector([0.0,0.0,0.0,0.0])
    if len(laser_angles) != len(laser_noise):
      randomize_distance_bias(len(laser_angles), noise_mu,noise_sigma)
      
    for i in range(len(returns)):
        idx = returns[i][-1]
        reusable_vector.xyzw = [returns[i][1],returns[i][2],returns[i][3],1.0]
        vt = (world_transformation * reusable_vector).xyz
        v = [returns[i][1],returns[i][2],returns[i][3]]

        vector_length = math.sqrt(v[0]**2+v[1]**2+v[2]**2)
        distance_noise =  laser_noise[idx%len(laser_noise)] + model.drawErrorFromModel(vector_length) 
        norm_vector = [v[0]/vector_length, v[1]/vector_length, v[2]/vector_length]
        vector_length_noise = vector_length+distance_noise
        reusable_vector.xyzw = [norm_vector[0]*vector_length_noise, norm_vector[1]*vector_length_noise, norm_vector[2]*vector_length_noise,1.0]
        v_noise = (world_transformation * reusable_vector).xyz

        evd_storage.addEntry(timestamp = ray_info[idx][2], yaw =(ray_info[idx][0]+math.pi)%(2*math.pi), pitch=ray_info[idx][1], distance=vector_length, distance_noise=vector_length_noise, x=vt[0], y=vt[1], z=vt[2], x_noise=v_noise[0], y_noise=v_noise[1], z_noise=v_noise[2], object_id=returns[i][4], color=returns[i][5])


    current_angle = start_angle+float(float(int(lines))*angle_resolution)
            
    if evd_file:
        evd_storage.appendEvdFile()

    if not evd_storage.isEmpty():
        scan_data = numpy.array(evd_storage.buffer)
        additional_data = None
        if scanner_object.store_data_in_mesh:
            additional_data = evd_storage.buffer

        if add_blender_mesh:
            mesh_utils.add_mesh_from_points_tf(scan_data[:,5:8], "Scan", world_transformation, buffer=additional_data)

        if add_noisy_blender_mesh:
            mesh_utils.add_mesh_from_points_tf(scan_data[:,8:11], "NoisyScan", world_transformation, buffer=additional_data) 

        bpy.context.scene.update()

    end_time = time.time()
    scan_time = end_time-start_time
    print ("Elapsed time: %.3f"%(scan_time))

    return True, current_angle, scan_time
コード例 #29
0
#         [m12, m13, m14, m15]))
#
#    m = Matrix(
#        ([m00, m10, m20, m30],
#         [m01, m11, m21, m31],
#         [m02, m12, m22, m32],
#         [m03, m13, m23, m33]))
#         
#    return m.transposed()


def quat_equals(q1,q2):
    return q1.w == q2.w and q1.x == q2.x and q1.y == q2.y and q1.z == q2.z


quat_transform_y_positive = Euler((pi/2, 0, 0),"XYZ").to_quaternion()

m4 = Matrix(
        ([1, 0, 0, 0],
         [0, 0, -1, 0],
         [0, 1, 0, 0],
         [0, 0, 0, 1]))

m3 = Matrix(
        ([1, 0, 0],
         [0, 0, -1],
         [0, 1, 0]))

matrix_3_transform_y_positive = Matrix((( 1, 0, 0 )   ,( 0, 0, 1 )   ,( 0,-1, 0 )                  ))
matrix_4_transform_y_positive = Matrix((( 1, 0, 0, 0 ),( 0, 0, 1, 0 ),( 0,-1, 0, 0 ),( 0, 0, 0, 1 )))
matrix_3_transform_z_positive = Matrix((( 1, 0, 0 )   ,( 0, 0,-1 )   ,( 0, 1, 0 )                  ))
コード例 #30
0
def set_fr_steps(self, context):
    if self.anim:
        rig = context.object
        #awc = rig.data.aut_walk_cycle
        torso = self.torso
        bone = rig.pose.bones[torso]
        rot_mode = bone.rotation_mode
        if rot_mode == 'QUATERNION':
            rtype = '.rotation_quaternion'
        elif rot_mode == 'AXIS_ANGLE':
            rtype = '.rotation_axis_angle'
        else:
            rtype = '.rotation_euler'

        dp = 'pose.bones["%s"]' % torso

        fc_loc = {}
        fc_rot = {}
        if rig.animation_data.action:
            for fc in rig.animation_data.action.fcurves:
                if dp in fc.data_path:
                    ldp = fc.data_path
                    type = ldp[ldp.rfind("."):]
                    if type == '.location':
                        fc_loc[fc.array_index] = fc
                    elif type == rtype:
                        fc_rot[fc.array_index] = fc
        else:
            rig.data.aut_walk_cycle.anim = False

        if not fc_loc:
            rig.data["frame_steps"] = {}
            return
        if self.step_by_frames:
            dist = self.step_frames
        else:
            dist = self.step / 2
        fr_start = context.scene.frame_start
        fr_end = context.scene.frame_end
        bone_dat = rig.data.bones[torso]
        m_loc = bone_dat.matrix_local.copy()
        parent = bone.parent.matrix * bone_dat.parent.matrix_local.inverted()
        frame_steps = {}
        for fr in range(fr_start, fr_end + 1):
            vec = Vector((fc_loc[0].evaluate(fr) if 0 in fc_loc else 0,
                          fc_loc[1].evaluate(fr) if 1 in fc_loc else 0,
                          fc_loc[2].evaluate(fr) if 2 in fc_loc else 0))
            if fr in {fr_start, fr_end}:
                d = dist
            elif self.step_by_frames:
                d = fr - lframe
            else:
                d = (lvec - vec).length
            if d >= dist:
                if rot_mode == 'QUATERNION':
                    rot = Quaternion(
                        (fc_rot[0].evaluate(fr) if 0 in fc_rot else 1,
                         fc_rot[1].evaluate(fr) if 1 in fc_rot else 0,
                         fc_rot[2].evaluate(fr) if 2 in fc_rot else 0,
                         fc_rot[3].evaluate(fr)
                         if 3 in fc_rot else 0)).normalized()
                elif rot_mode == 'AXIS_ANGLE':
                    rot = Quaternion(
                        (fc_rot[1].evaluate(fr) if 1 in fc_rot else 0,
                         fc_rot[2].evaluate(fr) if 2 in fc_rot else 1,
                         fc_rot[3].evaluate(fr) if 3 in fc_rot else 0),
                        fc_rot[0].evaluate(fr)
                        if 0 in fc_rot else 0).normalized()
                else:
                    rot = Euler((fc_rot[0].evaluate(fr) if 0 in fc_rot else 0,
                                 fc_rot[1].evaluate(fr) if 1 in fc_rot else 0,
                                 fc_rot[2].evaluate(fr) if 2 in fc_rot else 0),
                                rot_mode)
                mbasis = Matrix.Translation(vec) * rot.to_matrix().to_4x4()
                mglobal = parent * m_loc * mbasis * m_loc.inverted()
                #rvec.rotate(m_loc.inverted())
                #ant = int((fr - lframe) * (1 - self.anticipation))
                gvec, rot, _ = mglobal.decompose()
                frame_steps[str(fr)] = [gvec, rot]
                lvec = vec
                lframe = fr
        rig.data["frame_steps"] = frame_steps