Skip to content
This repository has been archived by the owner on Jul 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #251 from TetoTheSquirrelFox/dev
Browse files Browse the repository at this point in the history
Character Library Tools (WIP)
  • Loading branch information
animate1978 authored Mar 13, 2020
2 parents 1e7199a + 978a462 commit 491285b
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 17 deletions.
76 changes: 63 additions & 13 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3233,6 +3233,7 @@ def draw(self, context):
if hasattr(obj, prop) and not prop.startswith("Expressions_"):
box_fast_creators.prop(obj, prop)
box_fast_creators.operator("mbast.reset_categoryonly", icon="RECOVER_LAST")
#----------
box_fast_creators.separator(factor=0.5)
box_fast_creators.label(text="Phenotype Creator", icon='SORT_ASC')
body_type = morphcreator.get_body_type()
Expand All @@ -3245,11 +3246,31 @@ def draw(self, context):
box_fast_creators.label(text="Name : " + pheno_name, icon='INFO')
if morphcreator.is_phenotype_exists(body_type, pheno_name):
box_fast_creators.label(text="File already exists !", icon='ERROR')
else :
box_fast_creators.operator('mbcrea.button_save_phenotype', icon="FREEZE")
box_fast_creators.operator('mbcrea.button_save_phenotype', icon="FREEZE")
#----------
box_fast_creators.separator(factor=0.5)
box_fast_creators.label(text="Preset Creator", icon='SORT_ASC')
preset_folder = mblab_humanoid.presets_data_folder
path = os.path.join("data", "presets", preset_folder)
box_fast_creators.label(text="File saved under " + path, icon='INFO')
box_fast_creators.label(text="(age, mass & tone are used here)", icon='FORWARD')
box_fast_creators.prop(scn, 'mbcrea_preset_name_filter')
if len(scn.mbcrea_preset_name_filter) > 0:
box_fast_creators.prop(scn, 'mbcrea_special_preset') # Common or Special ?
preset_name = ""
if scn.mbcrea_special_preset:
preset_name = "special"
tmp = algorithms.split_name(scn.mbcrea_preset_name_filter, '-²&=¨^$£%µ,?;!§+*/').lower()
if not tmp.startswith("type_"):
preset_name += "type_"
preset_name += tmp
box_fast_creators.label(text="Name : " + preset_name, icon='INFO')
if morphcreator.is_preset_exists(preset_folder, preset_name):
box_fast_creators.label(text="File already exists !", icon='ERROR')
box_fast_creators.operator('mbcrea.button_save_preset', icon="FREEZE")
else:
box_combinexpression.label(text="! NO COMPATIBLE MODEL !", icon='ERROR')
box_combinexpression.enabled = False
box_fast_creators.label(text="! NO COMPATIBLE MODEL !", icon='ERROR')
box_fast_creators.enabled = False
#----------------------------------
box_adaptation_tools.separator(factor=0.5)

Expand Down Expand Up @@ -3549,7 +3570,17 @@ def morphs_items_minmax(box, items_str, minmax_str):
maxlen=1024,
subtype='FILE_NAME')

bpy.types.Scene.mbcrea_preset_name_filter = bpy.props.StringProperty(
name="Name",
description="The name for the file.\nStarting with type_ is automatic",
default="",
maxlen=1024,
subtype='FILE_NAME')

bpy.types.Scene.mbcrea_special_preset = bpy.props.BoolProperty(
name="Special",
description="If the preset is special or common")

class FinalizeExpression(bpy.types.Operator):
"""
Working like FinalizeMorph
Expand Down Expand Up @@ -3650,17 +3681,35 @@ def execute(self, context):
scn = bpy.context.scene
#-------File name----------
pheno_name = algorithms.split_name(scn.mbcrea_phenotype_name_filter, '-²&=¨^$£%µ,?;!§+*/').lower()
#--expression path + name--
#---phenotype path + name--
path = os.path.join(file_ops.get_data_path(), "phenotypes", morphcreator.get_body_type() + "_ptypes", pheno_name+".json")
#--------Saving file-------
morphcreator.save_phenotype(path, mblab_humanoid)
return {'FINISHED'}

def ShowMessageBox(self, message = "", title = "Message Box", icon = 'INFO'):
class FinalizePreset(bpy.types.Operator):
"""
Working like Save character
"""
bl_label = 'Finalize the preset'
bl_idname = 'mbcrea.button_save_preset'
filename_ext = ".json"
bl_description = 'Finalize the preset'
bl_context = 'objectmode'
bl_options = {'REGISTER', 'INTERNAL'}

def execute(self, context):
scn = bpy.context.scene
#-------File name----------
preset_name = algorithms.split_name(scn.mbcrea_preset_name_filter, '-²&=¨^$£%µ,?;!§+*/').lower()
if not preset_name.startswith("type_"):
preset_name = "type_" + preset_name
#----preset path + name----
path = os.path.join(file_ops.get_data_path(), "presets", mblab_humanoid.presets_data_folder, preset_name+".json")
#--------Saving file-------
morphcreator.save_preset(path, mblab_humanoid)
return {'FINISHED'}

def draw(self, context):
self.layout.label(text=message)
bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)

class ButtonCompatToolsDir(bpy.types.Operator):
#just for quick tests
Expand Down Expand Up @@ -4003,9 +4052,9 @@ def execute(self, context):
return {'FINISHED'}

class ButtonFastCreationsON(bpy.types.Operator):
bl_label = 'Fast Creation Tools'
bl_label = 'Character Library Creation'
bl_idname = 'mbcrea.button_fastcreators_on'
bl_description = 'Quick tools to create :\n- Phenotypes\n- Presets'
bl_description = 'Quick tools to create :\n- Phenotypes\n- Presets\nfor Character Library'
bl_context = 'objectmode'
bl_options = {'REGISTER', 'INTERNAL'}

Expand All @@ -4016,9 +4065,9 @@ def execute(self, context):
return {'FINISHED'}

class ButtonFastCreationsOFF(bpy.types.Operator):
bl_label = 'Fast Creation Tools'
bl_label = 'Character Library Creation'
bl_idname = 'mbcrea.button_fastcreators_off'
bl_description = 'Quick tools to create :\n- Phenotypes\n- Presets'
bl_description = 'Quick tools to create :\n- Phenotypes\n- Presets\nfor Character Library'
bl_context = 'objectmode'
bl_options = {'REGISTER', 'INTERNAL'}

Expand Down Expand Up @@ -4410,6 +4459,7 @@ def execute(self, context):
FinalizeExpression,
FinalizeCombExpression,
FinalizePhenotype,
FinalizePreset,
ButtonUpdateCombMorphs,
FinalizeCombMorph,
Reset_expression_category,
Expand Down
7 changes: 3 additions & 4 deletions expressionscreator.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,9 @@ def save_face_expression(self, filepath):
for prop in self.humanoid.character_data.keys():
if self.humanoid.character_data[prop] != 0.5 and prop.startswith("Expressions_"):
char_data["structural"][prop] = round(self.humanoid.character_data[prop], 4)

output_file = open(filepath, 'w')
json.dump(char_data, output_file)
output_file.close()
with open(filepath, "w") as j_file:
json.dump(char_data, j_file, indent=2)
j_file.close()

# data_source can be a filepath but also the data themselves.
def load_face_expression(self, data_source, reset_unassigned=True):
Expand Down
35 changes: 35 additions & 0 deletions morphcreator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import bpy
import numpy
from . import algorithms
from . import file_ops


body_parts = [("AB", "Abdomen", ""),
Expand Down Expand Up @@ -291,5 +292,39 @@ def is_phenotype_exists(body_type, name):
return False
return False

def save_phenotype(path, humanoid):
# Save all expression morphs as a new face expression
# in its dedicated file.
# If file already exists, it's replaced.
logger.info("Exporting character to {0}".format(file_ops.simple_path(path)))
obj = humanoid.get_object()
char_data = {"structural": dict()}

if obj:
for prop in humanoid.character_data.keys():
if humanoid.character_data[prop] != 0.5 and not prop.startswith("Expressions_"):
char_data["structural"][prop] = round(humanoid.character_data[prop], 2)

with open(path, "w") as j_file:
json.dump(char_data, j_file, indent=2)
j_file.close()

# ------------------------------------------------------------------------
# All methods/classes to help creating presets
# ------------------------------------------------------------------------

def is_preset_exists(preset_folder, name):
if len(preset_folder) < 1 or len(name) < 1:
return False
try:
path = os.path.join(file_ops.get_data_path(), "presets", preset_folder)
for database_file in os.listdir(path):
the_item, extension = os.path.splitext(database_file)
if the_item == name:
return True
except:
return False
return False

def save_phenotype(path, humanoid):
return None

0 comments on commit 491285b

Please sign in to comment.