def apply_node_tree(self, blender_material, tweaks="SKIN", group_name=None): template_values = self.default_settings(blender_material, group_name) if tweaks == "SKIN": self.skin_tweaks(template_values, blender_material) # TODO: check if the group node is already there, and figure out if we should recreate # or reuse it. Atm, the group will always be recreated. # group_node = NodeService.find_node_by_name(blender_material.node_tree, template_values["group_name"]) _LOG.dump("template_values", template_values) tree_dir = LocationService.get_mpfb_data("node_trees") json_file = os.path.join(tree_dir, "enhanced_skin.json") template_data = Path(json_file).read_text() _LOG.dump("template data before replace", template_data) for key in template_values: value = re.sub(r'\\+', '/', template_values[key]) template_data = template_data.replace("\"$" + key + "\"", value) _LOG.dump("template data after replace", template_data) node_tree_dict = json.loads(template_data) _LOG.dump("node_tree_dict", node_tree_dict) NodeService.apply_node_tree_from_dict(blender_material.node_tree, node_tree_dict, True)
def execute(self, context): _LOG.enter() _LOG.debug("click") blender_object = context.active_object if len(blender_object.material_slots) > 0: self.report({'ERROR'}, "This object already has a material") return {'FINISHED'} absolute_file_path = bpy.path.abspath(self.filepath) _LOG.debug("absolute_file_path", absolute_file_path) as_dict = dict() with open(absolute_file_path, "r") as json_file: json_data = json_file.read() import time ts = int(time.time()) json_data = str(json_data).replace("$group_name", "node_group." + str(ts)) as_dict = json.loads(json_data) self.report({'INFO'}, "JSON data read") _LOG.dump("loaded json data", as_dict) material = MaterialService.create_empty_material( "nodes_material", blender_object) NodeService.apply_node_tree_from_dict(material.node_tree, as_dict, True) return {'FINISHED'}
def apply_node_tree(self, blender_material, template_values=None): tree_dir = LocationService.get_mpfb_data("node_trees") json_file = os.path.join(tree_dir, "makeskin.json") if template_values is None: template_values = dict() self._template(template_values, "has_bumpmap", "bumpmap_filename", "bumpMapTexture") self._template(template_values, "has_diffuse", "diffuse_filename", "diffuseTexture") self._template(template_values, "has_displacementmap", "displacementmap_filename", "displacementMapTexture") self._template(template_values, "has_metallicmap", "metallicmap_filename", "metallicMapTexture") self._template(template_values, "has_normalmap", "normalmap_filename", "normalMapTexture") self._template(template_values, "has_roughnessmap", "roughnessmap_filename", "roughnessMapTexture") self._template(template_values, "has_transmissionmap", "transmissionmap_filename", "transmissionMapTexture") template_values["bump_or_normal"] = "false" if template_values["has_bumpmap"] == "true": template_values["bump_or_normal"] = "true" if template_values["has_normalmap"] == "true": template_values["bump_or_normal"] = "true" _LOG.dump("template_values", template_values) template_data = Path(json_file).read_text() for key in template_values: template_data = template_data.replace("\"$" + key + "\"", template_values[key]) _LOG.dump("Template data", template_data) node_tree_dict = dict() parse_error = None try: node_tree_dict = json.loads(template_data) except Exception as exc: _LOG.error( "An error was thrown when trying to parse the template data:", exc) _LOG.error("Full contents of template data", "\n\n" + str(template_data) + "\n\n") parse_error = "Failed to parse material: " + str( exc) + ". See material.makeskinmaterial log for more info." if not parse_error is None: raise ValueError(parse_error) _LOG.dump("node_tree", node_tree_dict) NodeService.apply_node_tree_from_dict(blender_material.node_tree, node_tree_dict, True)
def add_mhclo_asset(mhclo_file, basemesh, asset_type="Clothes", subdiv_levels=1, material_type="MAKESKIN"): mhclo = Mhclo() mhclo.load(mhclo_file) # pylint: disable=E1101 clothes = mhclo.load_mesh(bpy.context) clothes.location = (0.0, 0.0, 0.0) if not clothes or clothes is None: raise IOError("failed to import the clothes mesh: object was None after import") afn = os.path.abspath(mhclo_file) asset_source = os.path.basename(os.path.dirname(afn)) + "/" + os.path.basename(afn) GeneralObjectProperties.set_value("asset_source", asset_source, entity_reference=clothes) atype = str(asset_type).lower().capitalize() GeneralObjectProperties.set_value("object_type", atype, entity_reference=clothes) bpy.ops.object.shade_smooth() name = basemesh.name if "." in name: name = str(name).split(".")[0] name = name + "." + str(os.path.basename(mhclo_file)).replace(".mhclo", "").replace(".proxy", "") clothes.name = name _LOG.debug("Given name (basemesh, variable, clothes)", (basemesh.name, name, clothes.name)) colors = MaterialService.get_diffuse_colors() _LOG.dump("Colors, atype, exists, mhclo.material, material_type", (colors, atype, atype in colors, mhclo.material, material_type)) color = (0.8, 0.8, 0.8, 1.0) if atype in colors: color = colors[atype] if not mhclo.material: _LOG.debug("Material is not set in mhclo") if not mhclo.material is None and material_type == "MAKESKIN": _LOG.debug("Setting up MAKESKIN material", mhclo.material) MaterialService.delete_all_materials(clothes) makeskin_material = MakeSkinMaterial() makeskin_material.populate_from_mhmat(mhclo.material) blender_material = MaterialService.create_empty_material(name, clothes) makeskin_material.apply_node_tree(blender_material) blender_material.diffuse_color = color if material_type == "PROCEDURAL_EYES": MaterialService.delete_all_materials(clothes) _LOG.debug("Setting up procedural eyes") tree_dir = LocationService.get_mpfb_data("node_trees") json_file_name = os.path.join(tree_dir, "procedural_eyes.json") with open(json_file_name, "r") as json_file: node_tree_dict = json.load(json_file) _LOG.dump("procedural_eyes", node_tree_dict) blender_material = MaterialService.create_empty_material(name, clothes) NodeService.apply_node_tree_from_dict(blender_material.node_tree, node_tree_dict, True) blender_material.blend_method = "BLEND" blender_material.show_transparent_back = True blender_material.diffuse_color = color ClothesService.fit_clothes_to_human(clothes, basemesh, mhclo) mhclo.set_scalings(bpy.context, basemesh) delete_name = str(os.path.basename(mhclo_file)) # pylint: disable=E1101 delete_name = delete_name.replace(".mhclo", "") delete_name = delete_name.replace(".MHCLO", "") delete_name = delete_name.replace(" ", "_") delete_name = "Delete." + delete_name ClothesService.update_delete_group(mhclo, basemesh, replace_delete_group=False, delete_group_name=delete_name) rig = ObjectService.find_object_of_type_amongst_nearest_relatives(basemesh, "Skeleton") if rig: clothes.parent = rig modifier = clothes.modifiers.new("Armature", 'ARMATURE') modifier.object = rig ClothesService.interpolate_weights(basemesh, clothes, rig, mhclo) else: clothes.parent = basemesh ClothesService.set_makeclothes_object_properties_from_mhclo(clothes, mhclo, delete_group_name=delete_name) if subdiv_levels > 0: modifier = clothes.modifiers.new("Subdivision", 'SUBSURF') modifier.levels = 0 modifier.render_levels = subdiv_levels if mhclo.uuid: GeneralObjectProperties.set_value("uuid", mhclo.uuid, entity_reference=clothes) return clothes
def _assign_material(self, importer, blender_object, proxy_info=None): blender = importer["blender_entities"] ui = importer["settings_from_ui"] derived = importer["derived_settings"] name = None if not proxy_info: basic_type = "Basemesh" name = "body" else: basic_type = proxy_info["basic_proxy_type"] name = proxy_info["name"] if basic_type in ["Bodyproxy", "Basemesh"]: name = "body" material_name = derived["prefix"] + name if "materials" in blender and material_name in blender["materials"]: blender_object.data.materials.append(blender["materials"][material_name]) return mh_material = None if basic_type in ["Bodyproxy", "Basemesh"]: if ui["skin_material_type"] == "PLAIN": mh_material = MakeSkinMaterial() else: mh_material = EnhancedSkinMaterial(ui) if basic_type in ["Bodypart", "Eyes", "Clothes"]: if "Eye" in basic_type and ui["procedural_eyes"]: mh_material = "procedural_eyes" else: mh_material = MakeSkinMaterial() if mh_material: blender_material = MaterialService.create_empty_material(material_name, blender_object) if not "materials" in blender: blender["materials"] = dict() blender["materials"][material_name] = blender_material if basic_type == "Basemesh": mh_material.populate_from_body_material_socket_call() else: if mh_material != "procedural_eyes": mh_material.populate_from_proxy_material_socket_call(proxy_info["uuid"]) if isinstance(mh_material, EnhancedSkinMaterial): name = derived["prefix"] + derived["name"] mh_material.apply_node_tree(blender_material, group_name=material_name) else: if mh_material != "procedural_eyes": mh_material.apply_node_tree(blender_material) else: tree_dir = LocationService.get_mpfb_data("node_trees") json_file_name = os.path.join(tree_dir, "procedural_eyes.json") with open(json_file_name, "r") as json_file: node_tree_dict = json.load(json_file) _LOG.dump("procedural_eyes", node_tree_dict) NodeService.apply_node_tree_from_dict(blender_material.node_tree, node_tree_dict, True) diffuse_colors = MaterialService.get_diffuse_colors() if basic_type in diffuse_colors: blender_material.diffuse_color = diffuse_colors[basic_type] if proxy_info and proxy_info["type"] in diffuse_colors: blender_material.diffuse_color = diffuse_colors[proxy_info["type"]]