From c8c690afc27f834e58d048e7bcf8759e2d6c7c75 Mon Sep 17 00:00:00 2001 From: martinaCodes Date: Fri, 21 Oct 2022 00:11:45 +0200 Subject: [PATCH] changes 1) pasing ID references 2) bugs in create_entities, where number of representations couldn't be updated 3) by_id node updated to current workflow ... other small fixes --- src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py | 23 ++-- src/ifcsverchok/nodes/ifc/by_id.py | 21 ++-- src/ifcsverchok/nodes/ifc/create_entity.py | 119 +++++++++++++-------- 3 files changed, 97 insertions(+), 66 deletions(-) diff --git a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py index 76736ad2f7..c0fae2e35b 100644 --- a/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py +++ b/src/ifcsverchok/nodes/ifc/bmesh_to_ifc.py @@ -88,7 +88,6 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help self.inputs.new("SvStringsSocket", "target_view").prop_name = "target_view" self.inputs.new("SvStringsSocket", "paradigm").prop_name = "paradigm" self.inputs.new("SvObjectSocket", "blender_objects").prop_name = "blender_objects" #no prop for now - self.outputs.new("SvVerticesSocket", "file") self.outputs.new("SvVerticesSocket", "Representations") self.width = 210 self.node_dict[hash(self)] = {} @@ -102,8 +101,8 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help row.prop(self, 'refresh_local', icon='FILE_REFRESH') def process(self): - print("#"*20, "\n running bmesh_to_ifc3 PROCESS()... \n", "#"*20,) - print("#"*20, "\n hash(self):", hash(self), "\n", "#"*20,) + # print("#"*20, "\n running bmesh_to_ifc3 PROCESS()... \n", "#"*20,) + # print("#"*20, "\n hash(self):", hash(self), "\n", "#"*20,) self.sv_input_names = [i.name for i in self.inputs] @@ -112,7 +111,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help if not self.node_dict[hash(self)]: self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0)) - print("node_dict: ", self.node_dict) + # print("node_dict: ", self.node_dict) if not self.inputs["blender_objects"].sv_get()[0]: return edit = False @@ -138,6 +137,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help # print("blender_objects: ", blender_objects) self.file = SvIfcStore.get_file() + print(self.file) self.context = self.get_context() if self.node_id not in SvIfcStore.id_map: @@ -147,23 +147,23 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help self.edit() representations = self.create(blender_objects) else: - representations = self.get_existing_element() + # representations = self.get_existing_element() + representations = SvIfcStore.id_map[self.node_id]["Representations"] print("representations: ", representations) print("SvIfcStore.id_map: ", SvIfcStore.id_map) self.outputs["Representations"].sv_set(representations) - self.outputs["file"].sv_set([[self.file]]) def create(self, blender_objects): - results = [] + representations_ids = [] for blender_object in blender_objects: representation = ifcopenshell.api.run("geometry.add_representation", self.file, should_run_listeners=False,blender_object = blender_object, geometry=blender_object.data, context = self.context) if not representation: raise Exception("Couldn't create representation. Possibly wrong context.") - results.append([representation]) + representations_ids.append(representation.id()) SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Representations", []).append(representation.id()) - return results + return representations_ids def edit(self): # results = self.get_existing_element() @@ -171,15 +171,14 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help return for step_id in SvIfcStore.id_map[self.node_id]["Representations"]: #if self.file.by_id(step_id).is_a('IfcShapeRepresentation'): - print("step_id: ", step_id) ifcopenshell.api.run("geometry.remove_representation", self.file, representation=self.file.by_id(step_id)) del SvIfcStore.id_map[self.node_id]["Representations"] - return + return def get_existing_element(self): results = [] for step_id in SvIfcStore.id_map[self.node_id]["Representations"]: - results.append([self.file.by_id(step_id)]) + results.append(self.file.by_id(step_id)) return results def get_context(self): diff --git a/src/ifcsverchok/nodes/ifc/by_id.py b/src/ifcsverchok/nodes/ifc/by_id.py index a2888e8475..1866f9dfac 100644 --- a/src/ifcsverchok/nodes/ifc/by_id.py +++ b/src/ifcsverchok/nodes/ifc/by_id.py @@ -20,6 +20,7 @@ import bpy import ifcopenshell import ifcsverchok.helper +from ifcsverchok.ifcstore import SvIfcStore from bpy.props import StringProperty from sverchok.node_tree import SverchCustomTreeNode from sverchok.data_structure import updateNode @@ -28,21 +29,21 @@ from sverchok.data_structure import updateNode class SvIfcById(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): bl_idname = "SvIfcById" bl_label = "IFC By Id" - file: StringProperty(name="file", update=updateNode) - id: StringProperty(name="id", update=updateNode) + id: StringProperty(name="Id(s)", update=updateNode) def sv_init(self, context): - self.inputs.new("SvStringsSocket", "file").prop_name = "file" self.inputs.new("SvStringsSocket", "id").prop_name = "id" - self.outputs.new("SvStringsSocket", "entity") + self.outputs.new("SvStringsSocket", "Entities") + + def draw_buttons(self, context, layout): + layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Get IFC element by step id. Takes one or multiple step ids." def process(self): - self.sv_input_names = ["file", "id"] - super().process() - - def process_ifc(self, file, id): - self.outputs["entity"].sv_set([[file.by_id(int(id))]]) - + self.ids = self.inputs["id"].sv_get() + print(self.ids) + self.file = SvIfcStore.get_file() + self.entities = [self.file.by_id(step_id) for step_id in self.ids] + self.outputs["Entities"].sv_set(self.entities) def register(): bpy.utils.register_class(SvIfcById) diff --git a/src/ifcsverchok/nodes/ifc/create_entity.py b/src/ifcsverchok/nodes/ifc/create_entity.py index 795503bc81..81ae8cc1b7 100644 --- a/src/ifcsverchok/nodes/ifc/create_entity.py +++ b/src/ifcsverchok/nodes/ifc/create_entity.py @@ -50,14 +50,24 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper self.outputs.new("SvStringsSocket", "file") # only for testing self.node_dict[hash(self)] = {} + def draw_buttons(self, context, layout): + layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Create IFC Entity. Takes one or multiple inputs. \nIf 'Representation(s)' is given, that determines number of output entities. Otherwise, 'Names' is used." + + row = layout.row(align=True) + row.prop(self, 'is_interactive', icon='SCENE_DATA', icon_only=True) + row.prop(self, 'refresh_local', icon='FILE_REFRESH') + + + + def process(self): print("#"*20, "\n running create_entity3 PROCESS()... \n", "#"*20,) print("#"*20, "\n hash(self):", hash(self), "\n", "#"*20,) - self.names = self.inputs["Names"].sv_get() - self.descriptions = self.inputs["Descriptions"].sv_get() + self.names = flatten_data(self.inputs["Names"].sv_get(), target_level=1) + self.descriptions = flatten_data(self.inputs["Descriptions"].sv_get(), target_level=1) self.ifc_class = self.inputs["IfcClass"].sv_get()[0][0] - self.representations = self.inputs["Representations"].sv_get() + self.representations = flatten_data(self.inputs["Representations"].sv_get(), target_level=1) self.properties = self.inputs["Properties"].sv_get() @@ -84,78 +94,99 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper if self.refresh_local: edit = True + print("\nrepresentations before convert: ", self.representations) + + self.file = SvIfcStore.get_file() + if self.representations[0]: + self.representations = [self.file.by_id(step_id) for step_id in self.representations] + self.names = self.repeat_input_unique(self.names, len(self.representations)) + self.descriptions = self.repeat_input_unique(self.descriptions, len(self.representations)) + elif not self.representations[0]: + self.descriptions = self.repeat_input_unique(self.descriptions, len(self.names)) - self.names = repeat_last_for_length(self.names, len(self.representations), deepcopy=False) - self.descriptions = repeat_last_for_length(self.descriptions, len(self.representations), deepcopy=False) # print("REPRESENTATION: ", self.representations) # print("IfcClass: ",self.ifc_class) print("Names: ",self.names) print("Descriptions: ",self.descriptions) - - - - self.file = SvIfcStore.get_file() + # print("\nrepresentations after convert: ", self.representations) if self.node_id not in SvIfcStore.id_map: - enities = self.create() + entities = self.create() else: if edit is True: - enities = self.edit() + entities = self.edit() else: - enities = self.get_existing_element() + # entities = self.get_existing_element() + entities = SvIfcStore.id_map[self.node_id] - print("Entities: ", enities) + print("Entities: ", entities) print("SvIfcStore.id_map: ", SvIfcStore.id_map) - self.outputs["Entities"].sv_set(enities) + self.outputs["Entities"].sv_set(entities) self.outputs["file"].sv_set([[self.file]]) - def create(self): - # print("#"*20, "\n running create entity CREATE()... \n") - results = [] - for i, name in enumerate(self.names): - print(type(self.names[i][0])) + def create(self, index=None): + entities_ids = [] + iterator = range(len(self.names)) + if index is not None: + iterator = [index] + for i in iterator: try: - self.entity = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=self.ifc_class, name=self.names[i][0], description=self.descriptions[i][0]) + entity = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=self.ifc_class, name=self.names[i], description=self.descriptions[i]) try: - ifcopenshell.api.run("geometry.assign_representation", self.file, product=self.entity, representation=self.representations[i][0]) + ifcopenshell.api.run("geometry.assign_representation", self.file, product=entity, representation=self.representations[i]) except IndexError: pass - results.append([self.entity]) - SvIfcStore.id_map.setdefault(self.node_id, []).append(self.entity.id()) - except: - raise Exception("Something went wrong. Cannot create entity.") - return results + entities_ids.append(entity.id()) + SvIfcStore.id_map.setdefault(self.node_id, []).append(entity.id()) + except Exception as e: + raise Exception("Something went wrong. Cannot create entity.", e) + return entities_ids def edit(self): - results = [] + entities_ids = [] id_map_copy = SvIfcStore.id_map[self.node_id].copy() - for i, step_id in enumerate(id_map_copy): - self.entity = self.file.by_id(step_id) - self.entity.Name = self.names[i][0] - self.entity.Description = self.descriptions[i][0] + for i, _ in enumerate(self.names): + try: + step_id = id_map_copy[i] + except IndexError: + id = self.create(index=i) + entities_ids.append(id[0]) + continue + entity = self.file.by_id(step_id) + entity.Name = self.names[i] + entity.Description = self.descriptions[i] - if self.representations[i][0] and not self.file.by_type("IFCPRODUCTDEFINITIONSHAPE"): - ifcopenshell.api.run("geometry.assign_representation", self.file, product=self.entity, representation=self.representations[i][0]) - elif self.representations[i][0]: - self.entity.Representation = self.representations[i][0] - else: + try: + if self.representations[i] and not self.file.by_type("IFCPRODUCTDEFINITIONSHAPE"): + ifcopenshell.api.run("geometry.assign_representation", self.file, product=entity, representation=self.representations[i]) + elif self.representations[i]: + entity.Representation = self.representations[i] + except IndexError: pass - if self.entity.is_a() != self.ifc_class: + if entity.is_a() != self.ifc_class: SvIfcStore.id_map[self.node_id].remove(step_id) - self.entity = ifcopenshell.util.schema.reassign_class(self.file, self.entity, self.ifc_class) - SvIfcStore.id_map.setdefault(self.node_id, []).append(self.entity.id()) - results.append([self.entity]) + entity = ifcopenshell.util.schema.reassign_class(self.file, entity, self.ifc_class) + SvIfcStore.id_map.setdefault(self.node_id, []).append(entity.id()) + entities_ids.append(entity.id()) + + if id_map_copy>entities_ids: + SvIfcStore.id_map[self.node_id] = entities_ids + return entities_ids + + def repeat_input_unique(self, input, count): + input = repeat_last_for_length(input, count, deepcopy=False) + if input[0]: + input = [a if not (s:=sum(j == a for j in input[:i])) else f'{a}-{s+1}' for i, a in enumerate(input)] # add number to duplicates + return input - return results def get_existing_element(self): - # print("#"*20, "\n running create entity get_existing_element()... \n", "#"*20,) results = [] for i, step_id in enumerate(SvIfcStore.id_map[self.node_id]): - self.entity = self.file.by_id(step_id) - results.append([self.entity]) + entity = self.file.by_id(step_id) + results.append([entity]) return results