def __rigify_ik2fk(self, rig): fjw.activate(rig) fjw.mode("POSE") bpy.ops.pose.select_all(action='SELECT') post_fix = "" for meth in inspect.getmembers(bpy.ops.pose): if "ik2fk" in meth[0]: post_fix = meth[0].split("_")[-1] break if post_fix != "": print("post_fix:%s"%post_fix) bpy.ops.pose.select_all(action='SELECT') evalstr = 'bpy.ops.pose.rigify_leg_ik2fk_'+ post_fix +'(thigh_fk="thigh_fk.L", shin_fk="shin_fk.L", foot_fk="foot_fk.L", mfoot_fk="MCH-foot_fk.L", thigh_ik="thigh_ik.L", shin_ik="MCH-thigh_ik.L", foot_ik="MCH-thigh_ik_target.L", mfoot_ik="MCH-thigh_ik_target.L")' print(evalstr) eval(evalstr) print(evalstr) bpy.ops.pose.select_all(action='SELECT') evalstr = 'bpy.ops.pose.rigify_leg_ik2fk_'+ post_fix +'(thigh_fk="thigh_fk.R", shin_fk="shin_fk.R", foot_fk="foot_fk.R", mfoot_fk="MCH-foot_fk.R", thigh_ik="thigh_ik.R", shin_ik="MCH-thigh_ik.R", foot_ik="MCH-thigh_ik_target.R", mfoot_ik="MCH-thigh_ik_target.R")' eval(evalstr) print(evalstr) bpy.ops.pose.select_all(action='SELECT') evalstr = 'bpy.ops.pose.rigify_arm_ik2fk_'+ post_fix +'(uarm_fk="upper_arm_fk.L", farm_fk="forearm_fk.L", hand_fk="hand_fk.L", uarm_ik="upper_arm_ik.L", farm_ik="MCH-upper_arm_ik.L", hand_ik="hand_ik.L")' eval(evalstr) print(evalstr) bpy.ops.pose.select_all(action='SELECT') evalstr = 'bpy.ops.pose.rigify_arm_ik2fk_'+ post_fix +'(uarm_fk="upper_arm_fk.R", farm_fk="forearm_fk.R", hand_fk="hand_fk.R", uarm_ik="upper_arm_ik.R", farm_ik="MCH-upper_arm_ik.R", hand_ik="hand_ik.R")' eval(evalstr) print(evalstr)
def mesh_dup(self, vertex_group=""): base = fjw.active() mode = base.mode fjw.mode("OBJECT") fjw.deselect() fjw.mode("EDIT") if vertex_group != "": self.mesh_deselect() self.select_by_vertex_group(vertex_group) bpy.ops.mesh.duplicate(mode=1) bpy.ops.mesh.separate(type='SELECTED') fjw.mode("OBJECT") for obj in fjw.get_selected_list(): if obj != base: fjw.activate(obj) fjw.mode("EDIT") break dup = fjw.active() dup.data.materials.clear() self.clear_mods() # dup.parent = base return dup
def copy_shapes(self, edit_bones_data): """ 受け取ったデータのデータ通りにメタリグの形状を設定する。 """ fjw.activate(self.obj) fjw.mode("EDIT") for ebone in self.edit_bones_data.edit_bones: ebone.disconnect() #ORG-をコピー prefix="ORG-" for ebone in self.edit_bones_data.edit_bones: fixed_name = prefix + ebone.name src = edit_bones_data.get_ebone_byname(fixed_name) if src: ebone.copy_shape(src) else: print("not found:%s"%(fixed_name)) #親のtailを子のheadにあわせる for ebone in self.edit_bones_data.edit_bones: if ebone.has_parent and ebone.use_connect: edit_bone = ebone.get_ebone() parent = edit_bone.parent parent.tail = edit_bone.head for ebone in self.edit_bones_data.edit_bones: ebone.restore_connect() fjw.mode("OBJECT")
def parent_clear(self): """ ペアレントをクリアする。 """ fjw.deselect() fjw.activate(self.obj) bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')
def get_treesort(self): """ 位置操作、ルートからやらないとめちゃくちゃになる。 ので、ルートから子へとソートしたリストを作成する。 結果はボーン名のリスト。 """ fjw.activate(self.obj) fjw.mode("EDIT") """ 階層順にやっていけば間違いない? 途中で複数にわかれている場合どうするの? 探索関数いるのでは? ていうかルートボーンだけ洗い出して、あとは get_childrenメソッドがあればいいのでは """ ebones = self.obj.data.edit_bones roots = self.__get_root_ebones(ebones) result = [] for root in roots: children_list = self.__get_ebone_children(root) result.extend(children_list) return result
def bake(self, baketype): """ arguments: ベイクタイプ baketypes = ['FULL', 'AO', 'SHADOW', 'NORMALS', 'TEXTURE', 'DISPLACEMENT', 'DERIVATIVE', 'VERTEX_COLORS', 'EMIT', 'ALPHA', 'MIRROR_INTENSITY', 'MIRROR_COLOR', 'SPEC_INTENSITY', 'SPEC_COLOR'] ベイク元オブジェクト群 """ fjw.deselect() fjw.activate(self.obj) bpy.ops.object.shade_smooth() #ソリッドだとガタガタになる fjw.select(self.from_objects) img = self.get_bakeimage(baketype) img = self.reassign_image_filepath(img) tex = self.get_baketex(baketype) tex.image = img self.save_dirtyimages() self.assign_uv_face(img) self.set_tslots_state(False) render = bpy.context.scene.render render.bake_type = baketype render.use_bake_to_vertex_color = False render.use_bake_selected_to_active = True render.use_textures = True render.use_bake_normalize = False render.bake_margin = 14 bpy.context.scene.render.bake_distance = 0.2 bpy.context.scene.render.bake_bias = 0.0001 bpy.ops.object.bake_image() self.set_tslots_state(True) self.save_dirtyimages() bpy.ops.file.make_paths_relative()
def __init__(self, obj, from_objects, width=1024, height=1024, texture_dir=None): """ obj: ベイク先オブジェクト width: テクスチャ幅 height: テクスチャ高さ """ self.obj = obj self.from_objects = from_objects self.width = width self.height = height fjw_id = fjw.id(self.obj) # self.texture_dir = os.path.dirname(bpy.data.filepath) + os.sep + "textures" + os.sep + fjw_id + os.sep # if not os.path.exists(self.texture_dir): # os.makedirs(self.texture_dir) if texture_dir: self.texture_dir = texture_dir else: dirname = os.path.dirname(bpy.data.filepath) self.texture_dir = dirname + os.sep uvu = fjw.UVUtils(self.obj) if uvu.is_empty(): fjw.activate(self.obj) fjw.mode("EDIT") bpy.ops.mesh.select_all(action='SELECT') # bpy.ops.uv.smart_project() bpy.ops.uv.lightmap_pack() fjw.mode("OBJECT")
def get_avatar_objects_from_its_root(self, child_object): """ オブジェクトからルートオブジェクトを取得して、 mdobjectsに格納する。 """ fjw.deselect() root = fjw.get_root(child_object) mdobj = self.find_mdobj_by_object(root) if mdobj is not None: return mdobj fjw.activate(root) rootname = re.sub("\.\d+", "", root.name) bpy.ops.fujiwara_toolbox.command_24259() #親子選択 selection = fjw.get_selected_list() #selectionの中にMESHオブジェクトがなかったら除外する mesh_found = False for obj in selection: if obj.type == "MESH": mesh_found = True if not mesh_found: return None mdobj = MDObject(rootname, selection) self.mdobjects.append(mdobj) return mdobj
def execute(self,context): fjw.reject_notmesh() canvases = [] targets = [] #カスタムプロパティをチェック for obj in fjw.get_selected_list(): if "canvas" in obj: canvases.append(obj) continue if "asset" in obj: targets.append(obj) continue #カンバス群にパッシブ追加 fjw.deselect() fjw.activate(canvases[0]) fjw.select(canvases) bpy.ops.rigidbody.objects_add(type='PASSIVE') #ターゲット群にアクティブ追加 fjw.deselect() fjw.activate(targets[0]) fjw.select(targets) bpy.ops.rigidbody.objects_add(type='ACTIVE') #アニメーション再生 bpy.ops.screen.frame_jump() bpy.ops.screen.animation_play() #self.report({"INFO"},"") pass return {"FINISHED"}
def attouch_uraporiedge(self): fjw.deselect() fjw.activate(self.face) bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) bpy.ops.fujiwara_toolbox.command_318722()
def get_ebone(self): fjw.activate(self.obj) fjw.mode("EDIT") edit_bones = self.obj.data.edit_bones if self.name in edit_bones: ebone = edit_bones[self.name] return ebone return None
def setup(self): fjw.mode("OBJECT") fjw.deselect() fjw.activate(self.obj) fjw.mode("EDIT") for ebone in self.obj.data.edit_bones: self.edit_bones.append(EditBoneData(self.obj, ebone)) fjw.mode("POSE") for ebdata in self.edit_bones: ebdata.set_pose_matrix()
def execute(self, context): if bpy.context.scene.render.use_simplify: bpy.context.scene.render.use_simplify = False bpy.context.space_data.show_only_render = True bpy.context.space_data.lock_camera = False fjw.mode("OBJECT") curve_obj = add_drawing_curve("加筆カーブ白", (1, 1, 1), 0.003) fjw.activate(curve_obj) fjw.mode("EDIT") return {"FINISHED"}
def curve_set_bevel(obj, depth = 0.2, color=(1,1,1)): fjw.activate(obj) mat = bpy.data.materials.new("Bevel Mat") mat.diffuse_color = color obj.data.materials.append(mat) obj.data.bevel_depth = depth obj.data.bevel_resolution = 4 obj.data.fill_mode = "FULL" bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')
def execute(self,context): if bpy.data.filepath == "": self.report({"INFO"},"一度も保存されていません") return {'CANCELLED'} #self.report({"INFO"},"") #カメラにキー入れる fjw.globalview() fjw.mode("OBJECT") fjw.deselect() fjw.activate(bpy.data.objects["Camera"]) bpy.ops.anim.keyframe_insert_menu(type='LocRotScale') selfname = os.path.splitext(os.path.basename(bpy.data.filepath))[0] dir = os.path.dirname(bpy.data.filepath) pname = "page.blend" ppath = dir + os.sep + pname #ページファイルの存在確認 if not os.path.exists(ppath): self.report({"INFO"},"ページファイルが存在しません") return {'CANCELLED'} #キーフレーム対策 #キーフレームオンだと、ツールでカメラ動かした時にトランスフォームが保存されないことがある for obj in bpy.data.objects: if obj.type == "CAMERA": fjw.deselect() obj.select = True try: bpy.ops.anim.keyframe_insert_menu(type='LocRotScale') except : pass bpy.context.space_data.lock_camera = False #保存 bpy.ops.wm.save_mainfile() fjw.globalview() #レンダリング #レンダ設定 renderpath = dir + os.sep + "pageutils" + os.sep + "img" + os.sep + selfname + ".png" render(renderpath,True) #ページファイルを開く bpy.ops.wm.open_mainfile(filepath=ppath) return {"FINISHED"}
def gen_rig_and_reparent(self, metarig, unparent_at_rest=True): """ genrigして再ペアレントする。 """ if metarig.type != "ARMATURE": return False layers_current = fjw.layers_current_state() fjw.layers_showall() objects_bu = fjw.ObjectsPropBackups(bpy.context.scene.objects) objects_bu.store("hide") for obj in bpy.context.scene.objects: obj.hide = False self.set_metarig(metarig) self.set_rig(self.find_rig()) rig_old = None if self.rig: rig_old = self.rig if unparent_at_rest: self.rig.obj.data.pose_position = 'REST' self.rig.rigged_objects.parent_clear() rigdata = self.rig.obj.data fjw.delete([self.rig.obj]) bpy.data.armatures.remove(rigdata) fjw.deselect() fjw.activate(metarig) bpy.ops.pose.rigify_generate() new_rig = Rig(fjw.active()) if self.rig: new_rig.edit_bones_data.restore_info_from(self.rig.edit_bones_data) self.rig.rigged_objects.reset_rig(new_rig.obj) # bpy.ops.view3d.layers(nr=0, extend=False) if self.rig: self.rig.rigged_objects.reparent() # bpy.ops.view3d.layers(nr=0, extend=False) fjw.layers_show_list(layers_current) metarig.hide = True fjw.activate(new_rig.obj) fjw.mode("POSE") if rig_old: new_rig.restore_settings_from(rig_old) objects_bu.restore() return True
def curve_to_pancake(obj, dim_z_div = 4, color=(1,1,1)): fjw.activate(obj) mat = bpy.data.materials.new("Pancake Mat") mat.diffuse_color = color obj.data.materials.append(mat) # obj.data.dimensions = '2D' obj.data.splines[0].use_cyclic_u = True bpy.ops.object.convert(target='MESH') fjw.mode("EDIT") bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.edge_face_add() fjw.mode("OBJECT") bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS') dim_x, dim_y, dim_z = obj.dimensions dim_z = math.sqrt(dim_x*dim_x + dim_y*dim_y) / dim_z_div modu = fjw.Modutils(obj) m = modu.add("Solidify", "SOLIDIFY") m.thickness = dim_z m.offset = 0 modu.apply(m) m = modu.add("Decimate", "DECIMATE") m.decimate_type = "DISSOLVE" m.angle_limit = 0.0872665 modu.apply(m) m = modu.add("Remesh", "REMESH") m.mode = 'SMOOTH' m.octree_depth = 4 m.use_smooth_shade = True m.use_remove_disconnected = False modu.apply(m) m = modu.add("Laplacian Smooth", "LAPLACIANSMOOTH") m.iterations = 2 m.lambda_factor = 1 modu.apply(m) m = modu.add("Remesh", "REMESH") m.mode = 'SMOOTH' m.octree_depth = 4 m.use_smooth_shade = True modu.apply(m) m = modu.add("Subsurf", "SUBSURF") m.levels = 2 bpy.context.scene.render.use_simplify = False
def export(self): fjw.deselect() fjw.activate(self.obj) if len(self.obj.data.uv_textures) == 0: fjw.mode("EDIT") bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.smart_project() fjw.mode("OBJECT") if not os.path.exists(self.src_dir): os.makedirs(self.src_dir) bpy.ops.export_scene.obj(filepath=self.src_obj_path, check_existing=False, use_selection=True, use_mesh_modifiers=False)
def save_pre(context): #カメラにキー入らんでどうしようもないからこれでいれる!!!→2017/11/26 Blender2.79で修正されているのを確認 #カメラにキー入れる if bpy.context.scene.tool_settings.use_keyframe_insert_auto: if bpy.context.scene.camera != None: if not fjw.in_localview(): current = fjw.active() current_mode = "OBJECT" if current != None: current_mode = fjw.active().mode fjw.mode("OBJECT") selection = fjw.get_selected_list() fjw.deselect() fjw.activate(bpy.context.scene.camera) bpy.ops.anim.keyframe_insert_menu(type='LocRotScale') if current != None: fjw.deselect() fjw.select(selection) fjw.activate(current) fjw.mode(current_mode)
def apply_pose(self): """ ポーズをデフォルトに設定する。トランスフォームも確定する。 """ fjw.mode("OBJECT") fjw.deselect() fjw.activate(self.obj) fjw.mode("POSE") self.show_all_layers() bpy.ops.pose.reveal() for pbone in self.obj.pose.bones: pbone.bone.hide = False pbone.bone.select = True bpy.ops.pose.select_all(action='SELECT') bpy.ops.pose.visual_transform_apply() self.mute_constraints() fjw.mode("POSE") bpy.ops.pose.armature_apply() self.restore_layers() self.reset_edit_bones()
def assign_image(self, image_path): """ベイクの代わりに既にベイクしたイメージを割り当てる。""" fjw.deselect() fjw.activate(self.obj) bpy.ops.object.shade_smooth() # イメージ取得。既にロードされてたらそれを使うべき。 image = None for img in bpy.data.images: if img.is_library_indirect: continue if bpy.path.abspath(img.filepath) == bpy.path.abspath(image_path): return img if not image: # 相対パス化。 image = bpy.data.images.load(filepath=bpy.path.relpath(image_path)) dirname, name, ext = fjw.splitpath(image_path) textype = self.get_identifier(name) tex = self.get_baketex(textype) tex.image = image
def apply(self): """ アーマチュア変形やボーン相対変形を適用する。 ペアレントがクリアされている前提。 """ obj = self.obj fjw.mode("OBJECT") fjw.deselect() fjw.activate(obj) fjw.mode("OBJECT") #モディファイアの適用 if obj.type == "MESH": modu = fjw.Modutils(obj) arm = modu.find_bytype("ARMATURE") modu.apply(arm) #トランスフォームの適用 bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
def remove_not_used_materials(self, obj): if obj.type != "MESH": return current = fjw.active() fjw.activate(obj) fjw.mode("OBJECT") used_indexes = [] for face in obj.data.polygons: i = face.material_index if i not in used_indexes: used_indexes.append(i) print("used_indexes:" + str(used_indexes)) used_materials = [] for i in used_indexes: if i >= len(obj.material_slots): continue mat = obj.material_slots[i].material if mat not in used_materials: used_materials.append(mat) print(used_materials) delmats = [] for m in range(len(used_materials)): for i in range(len(obj.material_slots)): mslot = obj.material_slots[i] print("mslot:" + str(mslot.material)) print("in:" + str(mslot.material in used_materials)) if mslot.material and mslot.material not in used_materials: print("remove:" + str(i) + " " + str(mslot.material)) obj.active_material_index = i bpy.ops.object.material_slot_remove() delmats.append(mslot.material) break for mat in delmats: if mat.users == 0: bpy.data.materials.remove(mat) fjw.activate(current)
def reparent(self): """ 格納した情報に応じて再ペアレントする。 """ rig = self.get_rig() obj = self.obj modu = fjw.Modutils(self.obj) mod_arm = modu.find_bytype("ARMATURE") if not self.has_armature_mod: fjw.mode("OBJECT") fjw.deselect() obj.select = True fjw.activate(rig) if self.parent_type == "OBJECT": bpy.ops.object.parent_set(type='OBJECT', keep_transform=True) elif self.parent_type == "BONE": if self.parent_bone in rig.data.bones: fjw.mode("POSE") layerstates = [] for state in rig.data.layers: layerstates.append(state) rig.data.layers = [True for i in range(len(rig.data.layers))] rig.data.bones.active = rig.data.bones[self.parent_bone] bpy.ops.object.parent_set(type='BONE_RELATIVE') rig.data.layers = layerstates else: #既存のアーマチュアmodを除去する mod_arms = modu.find_bytype_list("ARMATURE") for mod in mod_arms: modu.remove(mod) fjw.deselect() obj.select = True fjw.activate(rig) if "rigify_parenting" in obj: bpy.ops.object.parent_set(type=obj["rigify_parenting"]) else: bpy.ops.object.parent_set(type='ARMATURE_AUTO') fjw.activate(obj) modu.sort() pass self.obj.hide = self.hide
def setup_mdwork_main(cls, self, context): if "_MDWork" not in bpy.data.filepath: fjw.framejump(cls.last_frame) dir = os.path.dirname(bpy.data.filepath) name = os.path.splitext(os.path.basename(bpy.data.filepath))[0] blend_md = dir + os.sep + name + "_MDWork.blend" bpy.ops.wm.save_as_mainfile(filepath=blend_md) bpy.context.scene.layers[0] = True for i in range(19): bpy.context.scene.layers[i + 1] = False for i in range(5): bpy.context.scene.layers[i] = True #ポーズだけついてるやつをポーズライブラリに登録する for armature_proxy in bpy.context.visible_objects: if armature_proxy.type != "ARMATURE": continue if "_proxy" not in armature_proxy.name: continue fjw.deselect() fjw.activate(armature_proxy) fjw.mode("POSE") bpy.ops.pose.select_all(action='SELECT') bpy.ops.fujiwara_toolbox.set_key() fjw.mode("OBJECT") fjw.mode("OBJECT") bpy.ops.object.select_all(action='SELECT') bpy.ops.file.make_paths_absolute() selection = fjw.get_selected_list() for obj in selection: md_garment_path_list = cls.__get_prop(obj, "md_garment_path_list") md_export_id = cls.__get_prop(obj, "md_export_id") md_garment_index = cls.__get_prop(obj, "md_garment_index") md_export_depth = cls.__get_prop(obj, "md_export_depth") # obj.dupli_group.library.filepath link_path = "" if obj.dupli_group is not None and obj.dupli_group.library is not None: link_path = obj.dupli_group.library.filepath if link_path == "" or link_path is None: continue fjw.deselect() fjw.activate(obj) bpy.ops.object.duplicates_make_real(use_base_parent=True, use_hierarchy=True) realized_objects = fjw.get_selected_list() for robj in realized_objects: robj["linked_path"] = link_path root = fjw.get_root(robj) if md_garment_path_list is not None: root["md_garment_path_list"] = md_garment_path_list if md_export_id is not None: root["md_export_id"] = md_export_id if md_garment_index is not None: root["md_garment_index"] = md_garment_index if md_export_depth is not None: root["md_export_depth"] = md_export_depth #garment_pathを絶対パス化する if "md_garment_path_list" in robj: pathlist_base = robj["md_garment_path_list"] print("*" * 15) print("* make garment path to abs") print("*" * 15) lib_dir = os.path.dirname(link_path) pathlist_new = [] for garment_path in pathlist_base: new_path = bpy.path.abspath(garment_path, start=lib_dir) pathlist_new.append(new_path) print(new_path) robj["md_garment_path_list"] = pathlist_new print("*" * 15) #proxyの処理 #同一のアーマチュアデータを使っているものを探してポーズライブラリを設定する。 for armature_proxy in bpy.data.objects: if armature_proxy.type != "ARMATURE": continue if "_proxy" not in armature_proxy.name: continue for armature in bpy.data.objects: if armature.type != "ARMATURE": continue if armature == armature_proxy: continue if armature.data == armature_proxy.data: #同一データを使用している #のでポーズライブラリの設定をコピーする armature.pose_library = armature_proxy.pose_library #回収したポーズライブラリを反映する fjw.mode("OBJECT") fjw.activate(armature) if fjw.active() is not None: aau = fjw.ArmatureActionUtils(armature) armu = fjw.ArmatureUtils(armature) fjw.active().hide = False fjw.mode("POSE") poselist = aau.get_poselist() if poselist is not None: for pose in aau.get_poselist(): frame = int( str(pose.name).replace("mdpose_", "")) fjw.framejump(frame) #ジオメトリはゼロ位置にする geo = armu.GetGeometryBone() armu.clearTrans([geo]) bpy.ops.pose.select_all(action='SELECT') armu.databone(geo.name).select = False aau.apply_pose(pose.name) #1フレームではデフォルトポーズに fjw.mode("POSE") fjw.framejump(1) bpy.ops.pose.select_all(action='SELECT') bpy.ops.pose.transforms_clear() #proxyの全削除 fjw.mode("OBJECT") prxs = fjw.find_list("_proxy") fjw.delete(prxs) # bpy.app.handlers.scene_update_post.append(process_proxy) bpy.context.space_data.show_only_render = False
def mdresult_auto_import_main(cls, self, context, attouch_fjwset=False): import_ext = ".obj" #存在確認 # blendname = os.path.splitext(os.path.basename(bpy.data.filepath))[0] # dir_path = get_mddatadir() + blendname + os.sep dir_path = get_mddatadir() self.report({"INFO"}, dir_path) if not os.path.exists(dir_path): self.report({"INFO"}, "キャンセルされました。") # bpy.ops.wm.quit_blender() return {'CANCELLED'} #既存のリザルトを処分 fjw.deselect() dellist = [] for obj in bpy.context.scene.objects: if obj.type == "MESH" and "result" in obj.name: dellist.append(obj) fjw.delete(dellist) root_objects = [] for obj in bpy.context.scene.objects: if obj.parent is None: root_objects.append(obj) mdj = MDJson() entries = mdj.get_thisfile_entries() # files = os.listdir(dir_path) # for file in files: files = [] for entry in entries: file = entry + import_ext # 対応するファイルが実際にあるかをチェックしないとだめ! filepath = dir_path + file if not os.path.exists(filepath): continue files.append(file) for file in files: self.report({"INFO"}, file) print("MDResult found:" + file) # targetname = file # dirname = os.path.basename(os.path.dirname(file)) targetname = file # rootobjでの設置だとルートがないとおかしなことになる # dupli_groupの名前でみて、同一名のもののアーマチュアを探して、 # vislble_objects内のそのデータと同一のプロクシないしアーマチュア、のジオメトリを指定すればいいのでは #グループ名だと全部"MainGroup"だからマッチしない! #グループの親ファイルパスの名前を見る!! #複製子除去 # targetname = re.sub(r"\.\d+", "", targetname) print("basename:%s, targetname:%s" % (file, targetname)) #fileと同名のdupli_groupを検索 dupli_group = None for group in bpy.data.groups: # gname = re.sub(r"\.\d+", "", group.name) if group.name == "MainGroup": if group.library is not None: g_filepath = group.library.filepath g_filename = os.path.basename(g_filepath) gname, ext = os.path.splitext(g_filename) else: gname = group.name else: gname = group.name if targetname == gname: dupli_group = group break if not dupli_group: print("!targetname not in bpy.data.groups!:%s" % targetname) else: print("*targetname found*:%s" % targetname) if dupli_group: dgroup = dupli_group #Bodyが参照しているアーマチュアのデータを取得 target_armature = None #この検索問題 名前Bodyじゃない可能性がある まずカスタムプロパティで探すべき #普通に全てのアーマチュアがシーン上のアーマチュアと一致したらそれ採用でいいのでは? # for obj in dgroup.objects: for scene_amature in bpy.context.visible_objects: if scene_amature.type != "ARMATURE": continue linked_object = scene_amature.proxy_group if linked_object: #グループが一致 if linked_object.dupli_group == dupli_group: #ルートアーマチュアを採用する target_armature = cls.__find_root_armature( scene_amature) break # if "Body" in dgroup.objects: # Body = dgroup.objects["Body"] # modu = fjw.Modutils(Body) # armt = modu.find("Armature") # if armt is not None: # armature = armt.object # if armature is not None: # armature_data = armature.data # for scene_amature in bpy.context.visible_objects: # if scene_amature.type != "ARMATURE": # continue # if scene_amature.data != armature_data: # continue # #同一のアーマチュアデータを発見したのでこいつを使用する # target_armature = scene_amature # break if not target_armature: print("!target_armature not found!") if target_armature is not None: print("target_armature:%s" % target_armature) arm = target_armature print("MDImport Step 0") fjw.mode("OBJECT") fjw.deselect() fjw.activate(arm) print("MDImport Step 1") fjw.mode("POSE") armu = fjw.ArmatureUtils(arm) geo = armu.GetGeometryBone() armu.activate(geo) print("MDImport Step 2") fjw.mode("POSE") self.report({"INFO"}, dir_path + file) print("MDImport Selecting GeoBone:" + dir_path + file) #インポート # mdresultpath = dir_path + file + os.sep + "result" + import_ext mdresultpath = dir_path + file MarvelousDesingerUtils.import_mdresult(mdresultpath, attouch_fjwset) print("MDImport Import MDResult:" + mdresultpath) fjw.mode("OBJECT") for obj in bpy.context.visible_objects: if "result" in obj.name: obj.select = True #テクスチャのパック cls.__pack_img_of_obj(obj)
def fjw_texture_export_uvmap(cls, obj): """ アクティブオブジェクトのアクティブUVマップ書き出してテクスチャ作業をする。 arguments: オブジェクト outputs: アクティブUV画像を書き出し 作業ディレクトリ/textures/uv名.png jsonにテクスチャパスを保存する?いらないかも 既にblendファイルが存在する場合はそのblendファイルを開いて完了したい。 """ if obj.type != "MESH": return export_name = "uv_map" path = cls.get_exist_filepath(obj, export_name) if path: #既に存在するのでそれを開く bpy.ops.wm.open_mainfile(filepath=path) return fjw.activate(obj) # UVをチェック if len(obj.data.uv_layers) == 0: # なければUVを作成 fjw.mode("EDIT") bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.smart_project() uv_layer = obj.data.uv_layers.active # テクスチャ作業ファイル作成 json = cls.make_texture_workingfile(obj, export_name) # if not json: # return dirname = os.path.dirname(bpy.data.filepath) basename = os.path.basename(bpy.data.filepath) name, ext = os.path.splitext(basename) print("filepath:%s" % bpy.data.filepath) # UVテクスチャ出力先 uv_dir = dirname + os.sep + "textures" if not os.path.exists(uv_dir): os.makedirs(uv_dir) uv_path = uv_dir + os.sep + name + ".png" print("uv_path:%s" % uv_path) fjw.mode("EDIT") bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.export_layout(filepath=uv_path, check_existing=False, export_all=False, modified=False, mode='PNG', size=(1024, 1024), opacity=0.25, tessellated=False) fjw.mode("OBJECT") dellist = [] for delobj in bpy.context.scene.objects: if delobj != obj: dellist.append(delobj) # 全オブジェクトを削除してUVテクスチャの読み込み fjw.delete(dellist) bpy.ops.mesh.primitive_plane_add( radius=1, calc_uvs=True, view_align=False, enter_editmode=False, location=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)) plane = fjw.active() plane.name = name mat = bpy.data.materials.new("uv_map") img = bpy.data.images.load(uv_path) # mat.use_shadeless = True # tslot = mat.texture_slots.add() # tex = bpy.data.textures.new("uv_map", "IMAGE") # tex.image = img # tslot.texture = tex plane.data.materials.append(mat) # 背景画像として追加 # https://blender.stackexchange.com/questions/6101/poll-failed-context-incorrect-example-bpy-ops-view3d-background-image-add/6105#6105 bpy.context.space_data.show_background_images = True for area in bpy.context.screen.areas: if area.type == 'VIEW_3D': space_data = area.spaces.active bg = space_data.background_images.new() bg.image = img bg.size = 2 bg.draw_depth = "FRONT" bg.view_axis = "TOP" break #SUN追加 bpy.ops.object.lamp_add(type='SUN', radius=1, view_align=False, location=(0, 0, 1), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)) bpy.ops.wm.save_as_mainfile()
def update_rig_proportion(self, rig): # self.freeze_rig(rig) #ポーズ形状から直接とってるのでもういらない self.metarig_shape_to_rig_shape(rig) metarig = self.find_metarig() fjw.activate(metarig) self.gen_rig_and_reparent(metarig, False)
def facesetup(self): """ ミラーモディファイアの適用 マテリアル割当←割り当てる前にマテリアルを作っとく必要がある 目・眉頂点グループを左右別に割り当てる 眼球用メッシュ分離→厚みマイナスつけてフチのみにする=へこます まつげ用メッシュ複製分離→まつげ用マテリアルを割り当て ・頂点グループ Eye, Mouth, Eyebrow """ fjw.deselect() fjw.activate(self.face) modu = fjw.Modutils(self.face) mod_mirror = modu.find_bytype("MIRROR") if mod_mirror: modu.apply(mod_mirror) vgu = fjw.VertexGroupUtils(self.face) ######################################## # メッシュセットアップ ######################################## #鼻線画 fjw.mode("EDIT") self.mesh_deselect() bpy.context.scene.tool_settings.mesh_select_mode = [True, False, False] self.select_by_vertex_group("Nose") bpy.ops.fujiwara_toolbox.make_skin_line() bpy.ops.transform.skin_resize(value=(0.0526974, 0.0526974, 0.0526974), constraint_axis=(False, False, False), constraint_orientation='LOCAL', mirror=True, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=0.0295401) bpy.ops.mesh.subdivide(smoothness=0) fjw.mode("OBJECT") fjw.deselect() fjw.activate(self.face) #プロジェクション設定 #肌 mat = self.get_material("Skin") self.set_projection("Shadow", mat, find=True) self.set_projection("Cheek", mat, find=True) self.assign_material_to_mesh(mat) #まつげテクスチャをつかった目の穴 mat = self.get_material("Eyehole_R") self.set_projection("Eyelid_R", mat, find=True) self.assign_material_by_vetexgroup("Eye", mat, "x") mat = self.get_material("Eyehole_L") self.set_projection("Eyelid_L", mat, find=True) self.assign_material_by_vetexgroup("Eye", mat, "-x") #口 mat = self.get_material("Mouth") self.set_projection("Mouth", mat, find=True) self.assign_material_by_vetexgroup("Mouth", mat) #まゆげ #選択したら複製する eyebrow = self.mesh_dup("Eyebrow") eyebrow.location[1] -= 0.001 eyebrow.name = "Eyebrow" mat = self.get_material("Eyebrow_R") self.set_projection("Eyebrow_R", mat, find=True) self.assign_material_by_vetexgroup("Eyebrow", mat, "x") mat = self.get_material("Eyebrow_L") self.set_projection("Eyebrow_L", mat, find=True) self.assign_material_by_vetexgroup("Eyebrow", mat, "-x") #目 fjw.mode("OBJECT") fjw.activate(self.face) fjw.mode("EDIT") eye = self.mesh_dup("Eye") eye.location[1] += 0.001 eye.name = "Eye" mat = self.get_material("Eye_R") self.set_projection("Pupil_R", mat, find=True) self.assign_material_by_vetexgroup("Eye", mat, "x") mat = self.get_material("Eye_L") self.set_projection("Pupil_L", mat, find=True) self.assign_material_by_vetexgroup("Eye", mat, "-x") #外周をすこし後ろに bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.region_to_loop() bpy.ops.transform.translate(value=(0, 0.001, 0), constraint_axis=(False, True, False), constraint_orientation='GLOBAL', mirror=True, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True, use_accurate=False) #まつげ Z処理的に、厚み付じゃだめ。座標をズラす。 fjw.mode("OBJECT") fjw.activate(self.face) fjw.mode("EDIT") eyelid = self.mesh_dup("Eye") eyelid.location[1] -= 0.001 eyelid.name = "Eyelid" mat = self.get_material("Eyelid_R") self.set_projection("Eyelid_R", mat, find=True) self.assign_material_by_vetexgroup("Eye", mat, "x") mat = self.get_material("Eyelid_L") self.set_projection("Eyelid_L", mat, find=True) self.assign_material_by_vetexgroup("Eye", mat, "-x") #外周の拡張 bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.region_to_loop() bpy.ops.fujiwara_toolbox.command_357169() bpy.ops.fujiwara_toolbox.pivot_to_individual() bpy.ops.mesh.extrude_region_move( MESH_OT_extrude_region={"mirror": False}, TRANSFORM_OT_translate={ "value": (0, 0, 0), "constraint_axis": (False, False, False), "constraint_orientation": 'GLOBAL', "mirror": False, "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH', "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST', "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0), "gpencil_strokes": False, "texture_space": False, "remove_on_cancel": False, "release_confirm": False, "use_accurate": False }) bpy.ops.transform.resize(value=(1.66677, 1.66677, 1.66677), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=True, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1) fjw.mode("OBJECT") fjw.activate(self.face) fjw.mode("OBJECT") ######################################## # マテリアルセットアップ ######################################## mat = self.get_material("Skin") self.facemat_basesetup(mat) self.facemat_skinsetup(mat) mat = self.get_material("Eyehole_R") self.facemat_basesetup(mat) self.facemat_skinsetup(mat) tslot = self.add_projectorimage_to_mat(mat, "Eyelid_R") self.tslot_setting(tslot, False, True) mat = self.get_material("Eyehole_L") self.facemat_basesetup(mat) self.facemat_skinsetup(mat) tslot = self.add_projectorimage_to_mat(mat, "Eyelid_L") self.tslot_setting(tslot, False, True) mat = self.get_material("Mouth") self.facemat_basesetup(mat) self.facemat_skinsetup(mat) tslot = self.add_projectorimage_to_mat(mat, mat.name) self.tslot_setting(tslot, True, True) mat = self.get_material("Eyebrow_R") # self.facemat_basesetup(mat) # tslot = self.add_projectorimage_to_mat(mat, mat.name) # self.tslot_setting(tslot, True, True) self.facemat_basesetup(mat) tslot = self.add_projectorimage_to_mat(mat, mat.name) prj = self.get_projector(mat.name, True) img = self.get_projector_image(prj.name) img = self.get_noalpha(img) #アルファ tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, False, True, True, True) #カラー tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, True, False) mat = self.get_material("Eyebrow_L") # self.facemat_basesetup(mat) # tslot = self.add_projectorimage_to_mat(mat, mat.name) # self.tslot_setting(tslot, True, True) self.facemat_basesetup(mat) tslot = self.add_projectorimage_to_mat(mat, mat.name) prj = self.get_projector(mat.name, True) img = self.get_projector_image(prj.name) img = self.get_noalpha(img) #アルファ tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, False, True, True, True) #カラー tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, True, False) mat = self.get_material("Eye_R") self.facemat_basesetup(mat) tslot = self.add_projectorimage_to_mat(mat, "Pupil_R") self.tslot_setting(tslot, True, False) mat = self.get_material("Eye_L") self.facemat_basesetup(mat) tslot = self.add_projectorimage_to_mat(mat, "Pupil_L") self.tslot_setting(tslot, True, False) mat = self.get_material("Eyelid_R") self.facemat_basesetup(mat) tslot = self.add_projectorimage_to_mat(mat, mat.name) prj = self.get_projector(mat.name, True) img = self.get_projector_image(prj.name) img = self.get_noalpha(img) #アルファ tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, False, True, True, True) #カラー tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, True, False) mat = self.get_material("Eyelid_L") self.facemat_basesetup(mat) prj = self.get_projector(mat.name, True) img = self.get_projector_image(prj.name) img = self.get_noalpha(img) #アルファ tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, False, True, True, True) #カラー tslot = self.set_texture_to_mat(mat, img, prj.name) self.tslot_setting(tslot, True, False) #仕上げに拡縮を適用して裏ポリエッジをつける self.attouch_uraporiedge()