def execute(self, context): obj = context.active_object scn = context.scene from mpfb.ui.makeskin.makeskinpanel import MAKESKIN_PROPERTIES if MaterialService.has_materials(obj): if not MAKESKIN_PROPERTIES.get_value("overwrite", entity_reference=scn): self.report({ 'ERROR' }, "A material for this object already exists, change 'replace' option in common settings to overwrite material" ) return {'FINISHED'} else: while len(obj.data.materials) > 0: obj.data.materials.pop(index=0) material = MaterialService.create_empty_material( "makeskinmaterial", obj) mhmat = MakeSkinMaterial() mhmat.populate_from_mhmat(self.filepath) mhmat.apply_node_tree(material) self.report({'INFO'}, "Material imported") return {'FINISHED'}
def execute(self, context): blender_object = context.active_object scene = context.scene from mpfb.ui.makeskin.makeskinpanel import MAKESKIN_PROPERTIES # pylint: disable=C0415 from mpfb.ui.makeskin import MakeSkinObjectProperties # pylint: disable=C0415 overwrite = MAKESKIN_PROPERTIES.get_value("overwrite", entity_reference=scene) if not overwrite and MaterialService.has_materials(blender_object): self.report({'ERROR'}, "Object already has a material") return {'FINISHED'} if overwrite and MaterialService.has_materials(blender_object): MaterialService.delete_all_materials(blender_object) name = MakeSkinObjectProperties.get_value( "name", entity_reference=blender_object) if not name: name = "MakeSkinMaterial" MakeSkinMaterial.create_makeskin_template_material( blender_object, scene, name) self.report({'INFO'}, "Material was created") return {'FINISHED'}
def _create_material_instances(self, importer): _LOG.enter() blender = importer["blender_entities"] ui = importer["settings_from_ui"] derived = importer["derived_settings"] if not ui["extra_vertex_groups"]: _LOG.debug("Skipping instances since we haven't created extra vertex groups") return if not ui["material_instances"]: _LOG.debug("Skipping instances since it is disabled") return if ui["skin_material_type"] == "PLAIN": _LOG.debug("Skipping instances since material type is PLAIN") return base_material = None bodyproxy = None if derived["has_body_proxy"] and "bodyproxy" in blender: bodyproxy = blender["bodyproxy"] basemesh = None if "basemesh" in blender: basemesh = blender["basemesh"] if not bodyproxy and not basemesh: _LOG.debug("Skipping instances since neither basemesh nor proxy is available") return if basemesh: base_material = MaterialService.get_material(basemesh) else: if bodyproxy: base_material = MaterialService.get_material(bodyproxy) if not base_material: _LOG.error("Skipping instances since no base material could be found. This should not have happened.") return for group_name in ["nipple", "lips", "fingernails", "toenails", "ears", "genitals"]: _LOG.debug("About to create material instance for", group_name) material_instance = base_material.copy() material_instance.name = derived["prefix"] + group_name if basemesh and ObjectService.has_vertex_group(basemesh, group_name): self._assign_material_instance(importer, basemesh, material_instance, group_name) if bodyproxy and ObjectService.has_vertex_group(bodyproxy, group_name): self._assign_material_instance(importer, bodyproxy, material_instance, group_name)
def execute(self, context): blender_object = context.active_object file_name = bpy.path.abspath(self.filepath) if not MaterialService.has_materials(blender_object): self.report({'ERROR'}, "Object does not have a material") return {'FINISHED'} material = MakeSkinMaterial() material.populate_from_object(blender_object) mhmat_string = material.as_mhmat() _LOG.dump("material", mhmat_string) image_file_error = material.check_that_all_textures_are_saved( blender_object) if not image_file_error is None: self.report({'ERROR'}, image_file_error) return {'FINISHED'} # TODO: copy normalized images with open(file_name, "w") as mhmat: mhmat.write(mhmat_string) self.report({'INFO'}, "The MHMAT file was written as " + file_name) return {'FINISHED'}
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 _populate_human_info_with_eye_material_info(human_info, basemesh): eyes = ObjectService.find_object_of_type_amongst_nearest_relatives(basemesh, "Eyes") if not eyes: return if not MaterialService.has_materials(eyes): human_info["eyes_material_type"] = "NONE" return material_settings = dict() _LOG.debug("material_slots", eyes.material_slots) slot = eyes.material_slots[0] material = slot.material group_node = NodeService.find_first_node_by_type_name(material.node_tree, "ShaderNodeGroup") if group_node: material_settings = NodeService.get_socket_default_values(group_node) if "IrisMinorColor" not in material_settings: # Material exists, but does not seem procedural. Assume it is a MAKESKIN material human_info["eyes_material_type"] = "MAKESKIN" else: human_info["eyes_material_type"] = "PROCEDURAL_EYES" human_info["eyes_material_settings"] = material_settings
def execute(self, context): _LOG.enter() _LOG.debug("click") blender_object = context.active_object if len(blender_object.material_slots) < 1: self.report({'ERROR'}, "This object does not have any material") return {'FINISHED'} if len(blender_object.material_slots) > 1: self.report({'ERROR'}, "This object has more than one material") return {'FINISHED'} material = MaterialService.get_material(blender_object) _LOG.debug("material", material) as_dict = NodeService.get_node_tree_as_dict(material.node_tree) _LOG.dump("nodes", as_dict) absolute_file_path = bpy.path.abspath(self.filepath) _LOG.debug("absolute_file_path", absolute_file_path) with open(absolute_file_path, "w") as json_file: json.dump(as_dict, json_file, indent=4, sort_keys=True) self.report({'INFO'}, "JSON file written to " + absolute_file_path) return {'FINISHED'}
def create_makeskin_template_material(blender_object, scene, name="MakeSkinMaterial"): if blender_object is None: raise ValueError('Must provide an object') if MaterialService.has_materials(blender_object): raise ValueError('Object already has material') if scene is None: raise ValueError('Must provide a scene') from mpfb.ui.makeskin.makeskinpanel import MAKESKIN_PROPERTIES template_values = dict() for part in _TEXTURE_NAMES: if MAKESKIN_PROPERTIES.get_value("create_" + part, entity_reference=scene): template_values["has_" + part] = "true" else: template_values["has_" + part] = "false" template_values[part + "_filename"] = "\"\"" material = MaterialService.create_empty_material(name, blender_object) msmat = MakeSkinMaterial() msmat.apply_node_tree(material, template_values)
def _save_material(self, context, file_name): body = ObjectService.find_object_of_type_amongst_nearest_relatives( context.object, "Basemesh") if not body: body = ObjectService.find_object_of_type_amongst_nearest_relatives( context.object, "Proxymesh") if not body: self.report( {'ERROR'}, "Could not find basemesh or body proxy amongst nearest relatives") return {'FINISHED'} if not MaterialService.has_materials(body): self.report({'ERROR'}, "Body does not have a material") return {'FINISHED'} material_settings = dict() _LOG.debug("material_slots", body.material_slots) for slot in body.material_slots: material = slot.material group_node = NodeService.find_first_node_by_type_name( material.node_tree, "ShaderNodeGroup") if group_node: values = NodeService.get_socket_default_values(group_node) if "colorMixIn" in values: # This seems to be an enhanced skin material name = material.name if "." in name: (prefix, name) = name.split(".", 2) if "." in name: (name, number) = name.split(".", 2) material_settings[name] = values _LOG.dump("material_settings", material_settings) with open(file_name, "w") as json_file: json.dump(material_settings, json_file, indent=4, sort_keys=True) UiService.rebuild_enhanced_settings_panel_list() #UiService.rebuild_importer_panel_list() self.report({'INFO'}, "Presets were written to " + file_name) return {'FINISHED'}
def _save_material(self, context, file_name): eyes = ObjectService.find_object_of_type_amongst_nearest_relatives( context.object, "Eyes") if not eyes: self.report({'ERROR'}, "Could not find eyes amongst nearest relatives") return {'FINISHED'} if not MaterialService.has_materials(eyes): self.report({'ERROR'}, "Eyes do not have a material") return {'FINISHED'} material_settings = dict() _LOG.debug("material_slots", eyes.material_slots) slot = eyes.material_slots[0] material = slot.material group_node = NodeService.find_first_node_by_type_name( material.node_tree, "ShaderNodeGroup") if group_node: material_settings = NodeService.get_socket_default_values(group_node) if "IrisMinorColor" not in material_settings: self.report({'ERROR'}, "Eyes do not seem to have procedural eyes material") return {'FINISHED'} else: self.report({'ERROR'}, "Eyes do not seem to have procedural eyes material") return {'FINISHED'} _LOG.dump("material_settings", material_settings) with open(file_name, "w") as json_file: json.dump(material_settings, json_file, indent=4, sort_keys=True) UiService.rebuild_eye_settings_panel_list() UiService.rebuild_importer_eye_settings_panel_list() self.report({'INFO'}, "Settings were written to " + file_name) return {'FINISHED'}
def execute(self, context): from mpfb.ui.loadclothes.loadclothespanel import LOAD_CLOTHES_PROPERTIES # pylint: disable=C0415 scene = context.scene object_type = LOAD_CLOTHES_PROPERTIES.get_value("object_type", entity_reference=scene) material_type = LOAD_CLOTHES_PROPERTIES.get_value( "material_type", entity_reference=scene) fit_to_body = LOAD_CLOTHES_PROPERTIES.get_value("fit_to_body", entity_reference=scene) delete_group = LOAD_CLOTHES_PROPERTIES.get_value( "delete_group", entity_reference=scene) specific_delete_group = LOAD_CLOTHES_PROPERTIES.get_value( "specific_delete_group", entity_reference=scene) set_up_rigging = LOAD_CLOTHES_PROPERTIES.get_value( "set_up_rigging", entity_reference=scene) interpolate_weights = LOAD_CLOTHES_PROPERTIES.get_value( "interpolate_weights", entity_reference=scene) makeclothes_metadata = LOAD_CLOTHES_PROPERTIES.get_value( "makeclothes_metadata", entity_reference=scene) blender_object = context.active_object rig = None basemesh = None if blender_object and not blender_object is None: if ObjectService.object_is_basemesh(blender_object): basemesh = blender_object else: basemesh = ObjectService.find_object_of_type_amongst_nearest_relatives( blender_object, "Basemesh") rig = ObjectService.find_object_of_type_amongst_nearest_relatives( blender_object, "Skeleton") if fit_to_body and basemesh is None: self.report( {'ERROR'}, "Fit to body is enabled, but active object is not a base mesh") return {'FINISHED'} if delete_group and basemesh is None: self.report({ 'ERROR' }, "Set up delete group is enabled, but active object is not a base mesh" ) return {'FINISHED'} if interpolate_weights and basemesh is None: self.report({ 'ERROR' }, "interpolate weights is enabled, but active object is not a base mesh" ) return {'FINISHED'} if set_up_rigging and rig is None: self.report({ 'ERROR' }, "set up rigging is enabled, but could not find a rig to attach to" ) return {'FINISHED'} mhclo = Mhclo() mhclo.load(self.filepath) # pylint: disable=E1101 clothes = mhclo.load_mesh(context) if not clothes or clothes is None: self.report({'ERROR'}, "failed to import the clothes mesh") return {'FINISHED'} GeneralObjectProperties.set_value("object_type", object_type, entity_reference=clothes) bpy.ops.object.shade_smooth() if not material_type == "PRINCIPLED": MaterialService.delete_all_materials(clothes) if material_type == "MAKESKIN" and not mhclo.material is None: makeskin_material = MakeSkinMaterial() makeskin_material.populate_from_mhmat(mhclo.material) name = os.path.basename(mhclo.material) blender_material = MaterialService.create_empty_material( name, clothes) makeskin_material.apply_node_tree(blender_material) if fit_to_body: ClothesService.fit_clothes_to_human(clothes, basemesh, mhclo) mhclo.set_scalings(context, basemesh) delete_name = "Delete" if delete_group: if specific_delete_group: delete_name = str(os.path.basename(self.filepath)) # 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) if set_up_rigging: clothes.location = (0.0, 0.0, 0.0) clothes.parent = rig modifier = clothes.modifiers.new("Armature", 'ARMATURE') modifier.object = rig if interpolate_weights: ClothesService.interpolate_weights(basemesh, clothes, rig, mhclo) if makeclothes_metadata: ClothesService.set_makeclothes_object_properties_from_mhclo( clothes, mhclo, delete_group_name=delete_name) self.report({'INFO'}, "Clothes were loaded") return {'FINISHED'}
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"]]
def poll(cls, context): if context.active_object is not None: return MaterialService.has_materials(context.active_object) return False
def _adjust_skin_material_settings(self, importer): _LOG.enter() blender = importer["blender_entities"] ui = importer["settings_from_ui"] derived = importer["derived_settings"] if ui["skin_material_type"] == "PLAIN": _LOG.debug("Skipping enhanced material adjustment since material type is PLAIN") return matset = ui["skin_settings_for_import"] if not matset or matset == "RAW": _LOG.debug("Skipping enhanced material adjustment since they're not requested") return best_body_object = None if "basemesh" in blender: best_body_object = blender["basemesh"] else: if derived["has_body_proxy"] and "bodyproxy" in blender: best_body_object = blender["bodyproxy"] if not best_body_object: _LOG.debug("Skipping enhanced material adjustment since there is no body") return if not MaterialService.has_materials(best_body_object): _LOG.debug("Skipping enhanced material adjustment since the body does not have any material") return _LOG.debug("Chosen material settings", matset) if matset == "CHARACTER": available_from_list = UiService.get_importer_enhanced_settings_panel_list() target = str(derived["name"]).lower() for setting in available_from_list: match = str(setting[0]).lower() _LOG.debug("Comparison", (target, match)) if match == target: matset = setting[1] if matset == "CHARACTER": matset = "default" _LOG.debug("Calculated material settings", matset) file_name = LocationService.get_user_config("enhanced_settings." + matset + ".json") if not os.path.exists(file_name): _LOG.error("Settings did not exist despite being in list:", file_name) return settings = dict() _LOG.debug("Will attempt to load", file_name) with open(file_name, "r") as json_file: settings = json.load(json_file) _LOG.dump("Material settings to apply", settings) for slot in best_body_object.material_slots: material = slot.material group_node = NodeService.find_first_node_by_type_name(material.node_tree, "ShaderNodeGroup") if group_node: values = NodeService.get_socket_default_values(group_node) if "colorMixIn" in values: # This seems to be an enhanced skin material name = material.name if "." in name: (prefix, name) = name.split(".", 1) if "." in name: (name, number) = name.split(".", 1) _LOG.debug("final name", name) if name in settings: _LOG.debug("will try to apply settings", settings[name]) NodeService.set_socket_default_values(group_node, settings[name])
def execute(self, context): _LOG.debug("filepath", self.filepath) from mpfb.ui.assetlibrary.assetsettingspanel import ASSET_SETTINGS_PROPERTIES # pylint: disable=C0415 scene = context.scene object_type = self.object_type material_type = "MAKESKIN" # TODO: some kind of operator argument fit_to_body = ASSET_SETTINGS_PROPERTIES.get_value("fit_to_body", entity_reference=scene) delete_group = ASSET_SETTINGS_PROPERTIES.get_value("delete_group", entity_reference=scene) specific_delete_group = ASSET_SETTINGS_PROPERTIES.get_value("specific_delete_group", entity_reference=scene) set_up_rigging = ASSET_SETTINGS_PROPERTIES.get_value("set_up_rigging", entity_reference=scene) interpolate_weights = ASSET_SETTINGS_PROPERTIES.get_value("interpolate_weights", entity_reference=scene) makeclothes_metadata = ASSET_SETTINGS_PROPERTIES.get_value("makeclothes_metadata", entity_reference=scene) add_subdiv_modifier = ASSET_SETTINGS_PROPERTIES.get_value("add_subdiv_modifier", entity_reference=scene) subdiv_levels = ASSET_SETTINGS_PROPERTIES.get_value("subdiv_levels", entity_reference=scene) mask_base_mesh = ASSET_SETTINGS_PROPERTIES.get_value("mask_base_mesh", entity_reference=scene) blender_object = context.active_object rig = None basemesh = None if blender_object and not blender_object is None: if ObjectService.object_is_basemesh(blender_object): basemesh = blender_object else: basemesh = ObjectService.find_object_of_type_amongst_nearest_relatives(blender_object, "Basemesh") rig = ObjectService.find_object_of_type_amongst_nearest_relatives(blender_object, "Skeleton") if fit_to_body and basemesh is None: self.report({'ERROR'}, "Fit to body is enabled, but active object is not a base mesh") return {'FINISHED'} if delete_group and basemesh is None: self.report({'ERROR'}, "Set up delete group is enabled, but active object is not a base mesh") return {'FINISHED'} if interpolate_weights and basemesh is None: self.report({'ERROR'}, "interpolate weights is enabled, but active object is not a base mesh") return {'FINISHED'} if set_up_rigging and rig is None: self.report({'ERROR'}, "set up rigging is enabled, but could not find a rig to attach to") return {'FINISHED'} mhclo = Mhclo() mhclo.load(self.filepath) # pylint: disable=E1101 clothes = mhclo.load_mesh(context) if not clothes or clothes is None: self.report({'ERROR'}, "failed to import the proxy") return {'FINISHED'} asset_dir = os.path.basename(os.path.dirname(os.path.realpath(self.filepath))) asset_source = asset_dir + "/" + os.path.basename(self.filepath) GeneralObjectProperties.set_value("object_type", "Proxymeshes", entity_reference=clothes) GeneralObjectProperties.set_value("asset_source", asset_source, entity_reference=clothes) bpy.ops.object.shade_smooth() if not material_type == "PRINCIPLED": MaterialService.delete_all_materials(clothes) if material_type == "MAKESKIN" and not mhclo.material is None: makeskin_material = MakeSkinMaterial() makeskin_material.populate_from_mhmat(mhclo.material) name = os.path.basename(mhclo.material) blender_material = MaterialService.create_empty_material(name, clothes) makeskin_material.apply_node_tree(blender_material) if fit_to_body: ClothesService.fit_clothes_to_human(clothes, basemesh, mhclo) mhclo.set_scalings(context, basemesh) if set_up_rigging: clothes.location = (0.0, 0.0, 0.0) clothes.parent = rig modifier = clothes.modifiers.new("Armature", 'ARMATURE') modifier.object = rig if interpolate_weights: ClothesService.interpolate_weights(basemesh, clothes, rig, mhclo) if add_subdiv_modifier: modifier = clothes.modifiers.new("Subdivision", 'SUBSURF') modifier.levels = 0 modifier.render_levels = subdiv_levels if mask_base_mesh: modifier = basemesh.modifiers.new("Hide base mesh", 'MASK') modifier.vertex_group = "body" modifier.invert_vertex_group = True #if makeclothes_metadata: # ClothesService.set_makeclothes_object_properties_from_mhclo(clothes, mhclo, delete_group_name=delete_name) _LOG.debug("clothes, uuid", (clothes, mhclo.uuid)) if clothes and mhclo.uuid: GeneralObjectProperties.set_value("uuid", mhclo.uuid, entity_reference=clothes) _LOG.debug("Has extra vgroups", mhclo.uuid in ALL_EXTRA_GROUPS) if mhclo.uuid in ALL_EXTRA_GROUPS: for vgroup_name in ALL_EXTRA_GROUPS[mhclo.uuid].keys(): _LOG.debug("Will create vgroup", vgroup_name) vgroup = clothes.vertex_groups.new(name=vgroup_name) vgroup.add(ALL_EXTRA_GROUPS[mhclo.uuid][vgroup_name], 1.0, 'ADD') self.report({'INFO'}, "Proxy was loaded") return {'FINISHED'}
def set_character_skin(mhmat_file, basemesh, bodyproxy=None, skin_type="ENHANCED_SSS", material_instances=True, slot_overrides=None): if bodyproxy is None: bodyproxy = ObjectService.find_object_of_type_amongst_nearest_relatives(basemesh, "Proxymeshes") material_source = os.path.basename(os.path.dirname(mhmat_file)) + "/" + os.path.basename(mhmat_file) _LOG.debug("material_source", material_source) HumanObjectProperties.set_value("material_source", material_source, entity_reference=basemesh) if not bodyproxy is None: HumanObjectProperties.set_value("material_source", material_source, entity_reference=bodyproxy) MaterialService.delete_all_materials(basemesh) if bodyproxy: MaterialService.delete_all_materials(bodyproxy) name = basemesh.name if not str(name).endswith(".body"): name = name + ".body" if skin_type == "MAKESKIN": makeskin_material = MakeSkinMaterial() makeskin_material.populate_from_mhmat(mhmat_file) blender_material = MaterialService.create_empty_material(name, basemesh) makeskin_material.apply_node_tree(blender_material) if skin_type in ["ENHANCED", "ENHANCED_SSS"]: presets = dict() presets["skin_material_type"] = skin_type scale_name = "METER" scale_factor = GeneralObjectProperties.get_value("scale_factor", entity_reference=basemesh) if scale_factor > 0.9: scale_name = "DECIMETER" if scale_factor > 9: scale_name = "CENTIMETER" presets["scale_factor"] = scale_name enhanced_material = EnhancedSkinMaterial(presets) enhanced_material.populate_from_mhmat(mhmat_file) blender_material = MaterialService.create_empty_material(name, basemesh) enhanced_material.apply_node_tree(blender_material) if material_instances: _LOG.debug("Will now attempt to create material slots for", (basemesh, bodyproxy)) MaterialService.create_and_assign_material_slots(basemesh, bodyproxy) file_name = LocationService.get_user_config("enhanced_settings.default.json") settings = dict() _LOG.debug("Will attempt to load", file_name) with open(file_name, "r") as json_file: settings = json.load(json_file) _LOG.dump("Settings before overrides", settings) _LOG.dump("Overrides", slot_overrides) if not slot_overrides is None: for slot_name in slot_overrides.keys(): _LOG.debug("Reading overrides for slot", slot_name) if not slot_name in settings: settings[slot_name] = dict() for key_name in slot_overrides[slot_name].keys(): _LOG.dump("Reading overrides for slot key", (slot_name, key_name, slot_overrides[slot_name][key_name])) settings[slot_name][key_name] = slot_overrides[slot_name][key_name] _LOG.dump("Settings after overrides", settings) for slot in basemesh.material_slots: material = slot.material group_node = NodeService.find_first_node_by_type_name(material.node_tree, "ShaderNodeGroup") if group_node: values = NodeService.get_socket_default_values(group_node) if "colorMixIn" in values: # This seems to be an enhanced skin material name = material.name _LOG.debug("Material name", name) if "." in name: name = str(name).split(".", maxsplit=1)[1] if "." in name: name = str(name).split(".", maxsplit=1)[0] _LOG.debug("final name", name) if name in settings: _LOG.debug("will try to apply settings", settings[name]) NodeService.set_socket_default_values(group_node, settings[name])
def _adjust_eye_material_settings(self, importer): _LOG.enter() blender = importer["blender_entities"] ui = importer["settings_from_ui"] derived = importer["derived_settings"] if not ui["procedural_eyes"]: _LOG.info("Skipping eye material adjustment since not using procedural eyes") return matset = ui["eye_settings_for_import"] if not matset: _LOG.info("Skipping eye material adjustment since they're not requested") return eye_object = None if "eyes" in blender: eye_object = blender["eyes"] if not eye_object: _LOG.info("Skipping eye material adjustment since there were no eyes") return if not MaterialService.has_materials(eye_object): _LOG.info("Skipping eye material adjustment since the eyes do not have any material") return _LOG.debug("Chosen material settings", matset) if matset == "CHARACTER": available_from_list = UiService.get_importer_eye_settings_panel_list() target = str(derived["name"]).lower() for setting in available_from_list: match = str(setting[0]).lower() _LOG.debug("Comparison", (target, match)) if match == target: matset = setting[1] if matset == "CHARACTER": matset = "default" _LOG.debug("Calculated material settings", matset) file_name = LocationService.get_user_config("eye_settings." + matset + ".json") if not os.path.exists(file_name): _LOG.error("Settings did not exist despite being in list:", file_name) return settings = dict() _LOG.debug("Will attempt to load", file_name) with open(file_name, "r") as json_file: settings = json.load(json_file) slot = eye_object.material_slots[0] material = slot.material group_node = NodeService.find_first_node_by_type_name(material.node_tree, "ShaderNodeGroup") if group_node: values = NodeService.get_socket_default_values(group_node) _LOG.dump("Current socket values", values) if "IrisMajorColor" in values: _LOG.debug("will try to apply settings", settings) NodeService.set_socket_default_values(group_node, settings) else: _LOG.info("Skipping eye material adjustment since material does not seem to be procedural") material.blend_method = "BLEND" material.show_transparent_back = 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 execute(self, context): _LOG.enter() if context.object is None: self.report({'ERROR'}, "Must have a selected object") return {'FINISHED'} name = ENHANCED_SETTINGS_PROPERTIES.get_value("available_settings", entity_reference=context) if not name: self.report({'ERROR'}, "Must select settings to load") return {'FINISHED'} file_name = LocationService.get_user_config("enhanced_settings." + name + ".json") if not os.path.exists(file_name): _LOG.error("Settings did not exist despite being in list:", file_name) self.report({'ERROR'}, "Settings did not exist!?") return {'FINISHED'} settings = dict() _LOG.debug("Will attempt to load", file_name) with open(file_name, "r") as json_file: settings = json.load(json_file) body = ObjectService.find_object_of_type_amongst_nearest_relatives( context.object, "Basemesh") if not body: body = ObjectService.find_object_of_type_amongst_nearest_relatives( context.object, "Proxymesh") if not body: self.report({ 'ERROR' }, "Could not find basemesh or body proxy amongst nearest relatives" ) return {'FINISHED'} if not MaterialService.has_materials(body): self.report({'ERROR'}, "Body does not have a material") return {'FINISHED'} _LOG.debug("material_slots", body.material_slots) for slot in body.material_slots: material = slot.material group_node = NodeService.find_first_node_by_type_name( material.node_tree, "ShaderNodeGroup") if group_node: values = NodeService.get_socket_default_values(group_node) if "colorMixIn" in values: # This seems to be an enhanced skin material name = material.name if "." in name: (prefix, name) = str(name).split(".", maxsplit=1) if "." in name: (name, number) = str(name).split(".", maxsplit=1) _LOG.debug("final name", name) if name in settings: _LOG.debug("will try to apply settings", settings[name]) NodeService.set_socket_default_values( group_node, settings[name]) self.report({'INFO'}, "Presets were loaded from " + file_name) return {'FINISHED'}
def skin_tweaks(self, template_values, blender_material): blender_material.diffuse_color = MaterialService.get_skin_diffuse_color() template_values["Roughness"] = "0.45"
def execute(self, context): _LOG.enter() if context.object is None: self.report({'ERROR'}, "Must have a selected object") return {'FINISHED'} name = EYE_SETTINGS_PROPERTIES.get_value("available_settings", entity_reference=context) if not name: self.report({'ERROR'}, "Must select settings to load") return {'FINISHED'} file_name = LocationService.get_user_config("eye_settings." + name + ".json") if not os.path.exists(file_name): _LOG.error("Settings did not exist despite being in list:", file_name) self.report({'ERROR'}, "Settings did not exist!?") return {'FINISHED'} settings = dict() _LOG.debug("Will attempt to load", file_name) with open(file_name, "r") as json_file: settings = json.load(json_file) eyes = ObjectService.find_object_of_type_amongst_nearest_relatives( context.object, "Eyes") if not eyes: self.report({'ERROR'}, "Could not find eyes amongst nearest relatives") return {'FINISHED'} if not MaterialService.has_materials(eyes): self.report({'ERROR'}, "Eyes do not have a material") return {'FINISHED'} _LOG.debug("material_slots", eyes.material_slots) slot = eyes.material_slots[0] material = slot.material group_node = NodeService.find_first_node_by_type_name( material.node_tree, "ShaderNodeGroup") if group_node: material_settings = NodeService.get_socket_default_values( group_node) if "IrisMinorColor" in material_settings: _LOG.debug("will try to apply settings", settings) NodeService.set_socket_default_values(group_node, settings) else: self.report( {'ERROR'}, "Eyes do not seem to have procedural eyes material") return {'FINISHED'} else: self.report({'ERROR'}, "Eyes do not seem to have procedural eyes material") return {'FINISHED'} self.report({'INFO'}, "Settings were loaded from " + file_name) return {'FINISHED'}