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
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)
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
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, ))
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
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
def cam_init(): cam.location = Vector((0, 0, 0)) cam.rotation_euler = Euler((0, 0, 0), 'XYZ')
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
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
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
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
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)
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
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
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'}
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"}
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
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'}
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
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)
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
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)
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)))
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
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, )
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
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
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
# [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 ) ))
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