Skip to content

Commit

Permalink
save and load JSON node methods get empty dictionary node, add new st…
Browse files Browse the repository at this point in the history
…ructures, fix some load_from_json methods according to new importer
  • Loading branch information
Durman committed Jun 3, 2021
1 parent 9c4b7e7 commit 5bf433d
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 32 deletions.
4 changes: 2 additions & 2 deletions nodes/scene/objects_in_lite.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,13 @@ def load_from_json(self, node_data: dict, import_version: float):

# rename if obj existed
if not obj.name == name:
node_data['params']["obj_name"] = obj.name
self.obj_name = obj.name
if import_version < 1.0:
node_data['params']["obj_name"] = obj.name # I guess the name was used for further importing

def save_to_json(self, node_data: dict):
# generate flat data, and inject into incoming storage variable
obj = self.node_dict.get(hash(self))
print(obj)
if not obj:
self.error('failed to obtain local geometry, can not add to json')
return
Expand Down
10 changes: 4 additions & 6 deletions nodes/scene/objects_mk3.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def modifiers_handle(self, context):
description='sorting inserted objects by names',
default=True, update=updateNode)

object_names: bpy.props.CollectionProperty(type=SvOB3BDataCollection, options={'SKIP_SAVE'})
object_names: bpy.props.CollectionProperty(type=SvOB3BDataCollection)

active_obj_index: bpy.props.IntProperty()

Expand Down Expand Up @@ -324,12 +324,10 @@ def process(self):
outputs['Matrixes'].sv_set(mtrx_out)
outputs['Object'].sv_set([data_objects.get(o.name) for o in self.object_names])

def save_to_json(self, node_data: dict):
node_data['object_names'] = [o.name for o in self.object_names]

def load_from_json(self, node_data: dict, import_version: float):
for named_object in node_data.get('object_names', []):
self.object_names.add().name = named_object
if import_version < 1.0:
for named_object in node_data.get('object_names', []):
self.object_names.add().name = named_object


classes = [SvOB3BItemOperator, SvOB3BDataCollection, SVOB3B_UL_NamesList, SvOB3Callback, SvObjectsNodeMK3]
Expand Down
9 changes: 4 additions & 5 deletions nodes/script/script1_lite.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,14 +553,13 @@ def load_from_json(self, node_data: dict, import_version: float):
'''
if import_version < 1.0:
params = node_data.get('params')
else:
# really not good thing to do, the import should not relay on structure of the importer module
params = node_data.get('properties')
if params:

script_name = params.get('script_name')
script_content = params.get('script_str')
else:
script_name = self.script_name
script_content = self.script_str

if script_name:
with self.sv_throttle_tree_update():
texts = bpy.data.texts
if script_name and not (script_name in texts):
Expand Down
30 changes: 15 additions & 15 deletions nodes/text/text_in_mk2.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,8 @@ def reload(self):


def process(self): # dispatch based on mode
print(self.textmode, self.current_text, 5)
if not self.current_text:
return
print(self.textmode)
if self.textmode == 'CSV':
self.update_csv()
elif self.textmode == 'SV':
Expand Down Expand Up @@ -605,7 +603,6 @@ def update_text(self):
return

# load data into selected socket
print(self.list_data[n_id])
self.outputs[0].sv_set(self.list_data[n_id])

def set_pointer_from_filename(self):
Expand Down Expand Up @@ -636,19 +633,22 @@ def load_from_json(self, node_data: dict, import_version: float):
as it's a beta service, old IO json may not be compatible - in this interest
of neat code we assume it finds everything.
'''
texts = bpy.data.texts
params = node_data.get('params')

# original textin used 'current_text', textin+ uses 'text'
current_text = params.get('current_text', params.get('text'))

# it's not clear from the exporter code why textmode parameter isn't stored
# in params.. for now this lets us look in both places. ugly but whatever.
textmode = params.get('textmode')
if not textmode:
textmode = node_data.get('textmode')
self.textmode = textmode
if import_version < 1.0:
params = node_data.get('params')

# original textin used 'current_text', textin+ uses 'text'
current_text = params.get('current_text', params.get('text'))

# it's not clear from the exporter code why textmode parameter isn't stored
# in params.. for now this lets us look in both places. ugly but whatever.
textmode = params.get('textmode')
if not textmode:
textmode = node_data.get('textmode')
self.textmode = textmode
else:
current_text = self.current_text

texts = bpy.data.texts
if not current_text:
self.info("`%s' doesn't store a current_text in params", self.name)

Expand Down
7 changes: 6 additions & 1 deletion old_nodes/profile_mk2.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,8 +942,13 @@ def process(self):
outputs[3].sv_set([])

def load_from_json(self, node_data: dict, import_version: float):
if import_version < 1.0:
file_name = node_data['params']['filename']
else:
file_name = self.filename

texts = bpy.data.texts
new_text = texts.new(node_data['params']['filename'])
new_text = texts.new(file_name)
new_text.from_string(node_data['path_file'])
self.update()

Expand Down
61 changes: 58 additions & 3 deletions utils/sv_json_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ def __init__(self, factories: List[Type[Struct]]):
StrTypes.LINK: 'link',
StrTypes.PROP: 'prop',
StrTypes.MATERIAL: 'material',
StrTypes.COLLECTION: 'collection'
StrTypes.COLLECTION: 'collection',
StrTypes.IMAGE: 'image',
StrTypes.TEXTURE: 'texture',
}

self.tree: Optional[Type[Struct]] = None
Expand All @@ -46,6 +48,8 @@ def __init__(self, factories: List[Type[Struct]]):
self.prop: Optional[Type[Struct]] = None
self.material: Optional[Type[Struct]] = None
self.collection: Optional[Type[Struct]] = None
self.image: Optional[Type[Struct]] = None
self.texture: Optional[Type[Struct]] = None

for factory in factories:
if factory.type in self._factory_names:
Expand Down Expand Up @@ -83,13 +87,17 @@ class StrTypes(Enum):
PROP = auto()
MATERIAL = auto()
COLLECTION = auto()
IMAGE = auto()
TEXTURE = auto()

def get_bpy_pointer(self) -> BPYPointers:
mapping = {
StrTypes.TREE: BPYPointers.NODE_TREE,
StrTypes.NODE: BPYPointers.NODE,
StrTypes.MATERIAL: BPYPointers.MATERIAL,
StrTypes.COLLECTION: BPYPointers.COLLECTION,
StrTypes.IMAGE: BPYPointers.IMAGE,
StrTypes.TEXTURE: BPYPointers.TEXTURE,
}
if self not in mapping:
raise TypeError(f'Given StrType: {self} is not a data block')
Expand All @@ -102,6 +110,8 @@ def get_type(cls, block_type: BPYPointers) -> StrTypes:
BPYPointers.NODE: StrTypes.NODE,
BPYPointers.MATERIAL: StrTypes.MATERIAL,
BPYPointers.COLLECTION: StrTypes.COLLECTION,
BPYPointers.IMAGE: StrTypes.IMAGE,
BPYPointers.TEXTURE: StrTypes.TEXTURE,
}
if block_type not in mapping:
raise TypeError(f'Given block type: {block_type} is not among supported: {mapping.keys()}')
Expand Down Expand Up @@ -487,6 +497,7 @@ def __init__(self, name: str, logger: FailsLog, structure: dict = None):
"parent": None,
},
"properties": dict(),
"advance_properties": dict(),
"inputs": dict(),
"outputs": dict(),
"bl_idname": ""
Expand Down Expand Up @@ -540,7 +551,9 @@ def export(self, node, factories: StructFactory, dependencies) -> dict:
_set_optional(self._struct, "outputs", self._struct["outputs"])

if hasattr(node, 'save_to_json'): # todo pass empty dictionary?
node.save_to_json(self._struct)
node.save_to_json(self._struct["advance_properties"])

_set_optional(self._struct, "advance_properties", self._struct["advance_properties"])

return self._struct

Expand Down Expand Up @@ -578,7 +591,7 @@ def build(self, node, factories: StructFactory, imported_data: OldNewNames):
if hasattr(node, 'load_from_json'):
with self.logger.add_fail("Setting advance node properties",
f'Tree: {node.id_data.name}, Node: {node.name}'):
node.load_from_json(self._struct, self.version)
node.load_from_json(self._struct.get("advance_properties", dict()), self.version)

def read_bl_type(self):
return self._struct['bl_idname']
Expand Down Expand Up @@ -859,6 +872,9 @@ def _export_collection_values(self, col_prop, dependencies):
def _set_collection_values(self, obj, factories, imported_structs):
"""Assign Python data to collection property"""
collection = getattr(obj, self.name)
# it is possible that collection is not empty in case a node added something into it during initialization
# but the property always consider the collection property to be empty
collection.clear()
for item_index, item_values in enumerate(self._struct):
# Some collections can be empty, in this case they should be expanded to be able to get new values
if item_index == len(collection):
Expand Down Expand Up @@ -911,6 +927,45 @@ def build(self, factories, imported_structs):
imported_structs[(StrTypes.COLLECTION, '', self.name)] = collection.name


class ImageStruct(Struct):
type = StrTypes.IMAGE

def __init__(self, name, logger=None, struct=None):
default_struct = {}
self.name = name
self.logger = logger
self._struct = struct or default_struct

def export(self, image, factories, dependencies):
return self._struct

def build(self, factories, imported_structs):
# the file should have the image already
# it could be convenient if importer could generate empty images if necessary
image = bpy.data.images.get(self.name)
if image is not None:
imported_structs[(StrTypes.IMAGE, '', self.name)] = image.name


class TextureStruct(Struct):
type = StrTypes.TEXTURE

def __init__(self, name, logger=None, struct=None):
default_struct = {}
self.name = name
self.logger = logger
self._struct = struct or default_struct

def export(self, texture, factories, dependencies):
return self._struct

def build(self, factories, imported_structs):
# it could be convenient if importer could generate empty textures if necessary
texture = bpy.data.textures.get(self.name)
if texture is not None:
imported_structs[(StrTypes.TEXTURE, '', self.name)] = texture.name


class OldNewNames: # todo can't this be regular dictionary?
"""This class should solve problem of old new names, when created object with one name get another one"""
Old, New, Owner = str, str, str
Expand Down

0 comments on commit 5bf433d

Please sign in to comment.