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 _set_eyes(human_info, basemesh): _LOG.enter() eyes = ObjectService.find_object_of_type_amongst_nearest_relatives(basemesh, "Eyes") if not eyes: _LOG.debug("There are no eyes") return if not "eyes_material_type" in human_info or not human_info["eyes_material_type"]: _LOG.debug("Eyes material type not specified") return if human_info["eyes_material_type"] != "PROCEDURAL_EYES": _LOG.debug("Eyes material is not procedural") return if not "eyes_material_settings" in human_info or not human_info["eyes_material_settings"]: _LOG.debug("There are no eye material overrides, going with the default") return settings = human_info["eyes_material_settings"] _LOG.dump("Eye material overrides", settings) 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.dump("will try to apply settings", settings) NodeService.set_socket_default_values(group_node, settings) else: _LOG.warn("Material group node did not have expected key -> not procedural eyes") else: _LOG.warn("Material had no group node -> not procedural eyes")
def _populate_human_info_with_skin_info(human_info, basemesh): proxymesh = ObjectService.find_object_of_type_amongst_nearest_relatives(basemesh, "Proxymeshes") bodyobject = basemesh if proxymesh and not proxymesh is None: bodyobject = proxymesh skin = HumanObjectProperties.get_value("material_source", entity_reference=bodyobject) if skin is None: skin = "" human_info["skin_mhmat"] = skin slots = bodyobject.material_slots if not slots or len(slots) < 1: return material = slots[0].material group_node = NodeService.find_first_node_by_type_name(material.node_tree, "ShaderNodeGroup") values = None if group_node: values = NodeService.get_socket_default_values(group_node) if values is None or not "colorMixIn" in values: human_info["skin_material_type"] = "MAKESKIN" return human_info["skin_material_type"] = "ENHANCED" if "SSS Color" in values: human_info["skin_material_type"] = "ENHANCED_SSS" for slot in 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: name = str(name).split(".", maxsplit=1)[1] if "." in name: name = str(name).split(".", maxsplit=1)[0] human_info["skin_material_settings"][name] = 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 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 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'}
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 _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 _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])