Updated following nodes to work with the current workflow: add_pset, by_guid, get_attribute, get_property, read_entity. Added tooltips and other minor fixes

This commit is contained in:
martinaCodes
2022-11-11 02:50:30 +01:00
committed by Dion Moult
parent 41ae350f33
commit 05633cd657
11 changed files with 508 additions and 169 deletions
+58 -22
View File
@@ -28,22 +28,36 @@ import ifcopenshell
from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
from sverchok.data_structure import updateNode, flatten_data
class SvIfcAddPset(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcAddPset"
bl_label = "IFC Add Pset"
Name: StringProperty(name="Name", update=updateNode, default="My_Pset")
Properties: StringProperty(name="Properties", update=updateNode, default="{\"Foo\":\"Bar\"}")
Elements: StringProperty(name="Elements", update=updateNode)
Name: StringProperty(
name="Name",
description="Name of the property set. Eg. Pset_WallCommon.",
update=updateNode,
default="My_Pset",
)
Properties: StringProperty(
name="Properties",
description='Propertied in a JSON key:value format.Eg. {"IsExternal":"True"}',
update=updateNode,
default='{"Foo":"Bar"}',
)
Elements: StringProperty(name="Element Ids", update=updateNode)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "Name").prop_name = "Name"
self.inputs.new("SvTextSocket", "Properties").prop_name = "Properties"
self.inputs.new("SvStringsSocket", "Elements").prop_name = "Elements"
self.outputs.new("SvStringsSocket", "entity")
self.outputs.new("SvStringsSocket", "file")
self.outputs.new("SvStringsSocket", "Entity")
def draw_buttons(self, context, layout):
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = "Add a property set and corresponding properties to IfcElements."
def process(self):
if not any(socket.is_linked for socket in self.outputs):
@@ -51,37 +65,59 @@ class SvIfcAddPset(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIf
name = self.inputs["Name"].sv_get()[0][0]
properties = self.inputs["Properties"].sv_get()[0][0]
elements = self.inputs["Elements"].sv_get()[0]
element_ids = flatten_data(self.inputs["Elements"].sv_get(), target_level=1)
if SvIfcStore.file is None:
SvIfcStore.file = SvIfcStore.create_boilerplate()
self.file = SvIfcStore.get_file()
try:
elements = [self.file.by_id(int(step_id)) for step_id in element_ids]
print(elements[0])
except Exception as e:
raise Exception("Instance ID not found", e)
if self.node_id not in SvIfcStore.id_map.values():
if self.node_id not in SvIfcStore.id_map:
element = self.create(name, properties, elements)
else:
element = self.edit(name, properties, elements)
self.outputs["entity"].sv_set([[element]])
self.outputs["file"].sv_set([[self.file]])
self.outputs["Entity"].sv_set([element])
def create(self, name, properties, elements):
results = []
for element in elements:
result = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name=name)
ifcopenshell.api.run("pset.edit_pset", self.file, pset=result, properties=json.loads(properties))
SvIfcStore.id_map[result.id()] = self.node_id
print("element: ", element)
result = ifcopenshell.api.run(
"pset.add_pset", self.file, product=element, name=name
)
ifcopenshell.api.run(
"pset.edit_pset",
self.file,
pset=result,
properties=json.loads(properties),
)
print("result: ", result)
SvIfcStore.id_map.setdefault(self.node_id, []).append(result.id())
results.append(result)
return result
return results
def edit(self, name, properties, elements):
result = self.get_existing_element()
ifcopenshell.api.run("pset.edit_pset", self.file, pset=result, name=name, properties=json.loads(properties))
return result
result_ids = SvIfcStore.id_map[self.node_id]
results = []
for result_id in result_ids:
result = self.file.by_id(result_id)
ifcopenshell.api.run(
"pset.edit_pset",
self.file,
pset=result,
name=name,
properties=json.loads(properties),
)
results.append(result)
return results
def get_existing_element(self):
entity_id = list(SvIfcStore.id_map.keys())[list(SvIfcStore.id_map.values()).index(self.node_id)]
return self.file.by_id(entity_id)
# def get_existing_element(self):
# entity_id = list(SvIfcStore.id_map.keys())[list(SvIfcStore.id_map.values()).index(self.node_id)]
# return self.file.by_id(entity_id)
def register():
@@ -24,17 +24,37 @@ from ifcsverchok.ifcstore import SvIfcStore
from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, flatten_data, repeat_last_for_length, ensure_min_nesting
from sverchok.data_structure import (
updateNode,
flatten_data,
repeat_last_for_length,
ensure_min_nesting,
)
class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcAddSpatialElement(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
bl_idname = "SvIfcAddSpatialElement"
bl_label = "IFC Add Spatial Element"
node_dict = {}
Names: StringProperty(name="Name(s)", update=updateNode)
IfcClass: StringProperty(name="IFC Class", update=updateNode, default="IfcSpace")
Elements: StringProperty(name="Elements", update=updateNode)
Names: StringProperty(
name="Name(s)",
description="Name or list of names of the spacial element.",
update=updateNode,
)
IfcClass: StringProperty(
name="IFC Class",
description='IfcClass of the spacial element. Eg. "IfcSpace".\nYou can use the "IFC Class Picker" node to find a relevant class.',
update=updateNode,
default="IfcSpace",
)
Elements: StringProperty(
name="Elements",
description="The IfcElements you want to add to the spacial element.\nThis can also be a (list of) spacial elements. Eg. IfcSpaces aggregated to an IfcBuildingStorey.",
update=updateNode,
)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "Names").prop_name = "Names"
@@ -44,12 +64,16 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
self.node_dict[hash(self)] = {}
def draw_buttons(self, context, layout):
layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Ifc entity by type."
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = "Add IfcElements to an IfcSpatialElement."
def process(self):
self.sv_input_names = [i.name for i in self.inputs]
if hash(self) not in self.node_dict:
self.node_dict[hash(self)] = {} # happens if node is already on canvas when blender loads
self.node_dict[
hash(self)
] = {} # happens if node is already on canvas when blender loads
if not self.node_dict[hash(self)]:
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
@@ -58,7 +82,9 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
edit = False
edit_elements = False
for i in range(len(self.inputs)):
input = self.inputs[self.sv_input_names[i]].sv_get(deepcopy=True, default=[])
input = self.inputs[self.sv_input_names[i]].sv_get(
deepcopy=True, default=[]
)
if (
isinstance(self.node_dict[hash(self)][self.inputs[i].name], list)
and input != self.node_dict[hash(self)][self.inputs[i].name]
@@ -69,20 +95,27 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
self.node_dict[hash(self)][self.inputs[i].name] = input.copy()
self.names = flatten_data(self.inputs["Names"].sv_get(), target_level=1)
self.ifc_class = flatten_data(self.inputs["IfcClass"].sv_get(), target_level=1)[0]
self.ifc_class = flatten_data(self.inputs["IfcClass"].sv_get(), target_level=1)[
0
]
self.elements = ensure_min_nesting(self.inputs["Elements"].sv_get(), 2)
self.elements = flatten_data(self.elements, target_level=2)
if not self.elements[0][0]:
raise Exception('Mandatory input "Element(s)" is missing.')
return
self.file = SvIfcStore.get_file()
self.elements = [[self.file.by_id(step_id) for step_id in element] for element in self.elements]
self.elements = [
[self.file.by_id(step_id) for step_id in element]
for element in self.elements
]
if "len" not in self.node_dict[hash(self)]:
self.node_dict[hash(self)]["len"] = 0
self.names = self.repeat_input_unique(self.names, len(self.elements))
if (self.node_id not in SvIfcStore.id_map) or (len(self.elements) != self.node_dict[hash(self)]["len"]):
if (self.node_id not in SvIfcStore.id_map) or (
len(self.elements) != self.node_dict[hash(self)]["len"]
):
self.remove()
elements = self.create()
self.node_dict[hash(self)]["len"] = len(self.elements)
@@ -99,13 +132,28 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
if index is not None:
iterator = [index]
for i in iterator:
result = ifcopenshell.api.run("root.create_entity", self.file, name=self.names[i], ifc_class=self.ifc_class)
result = ifcopenshell.api.run(
"root.create_entity",
self.file,
name=self.names[i],
ifc_class=self.ifc_class,
)
for items in self.elements[i]:
if items.is_a("IfcSpatialElement") or items.is_a("IfcSpatialStructureElement"):
ifcopenshell.api.run("aggregate.assign_object", self.file, product=items, relating_object=result)
if items.is_a("IfcSpatialElement") or items.is_a(
"IfcSpatialStructureElement"
):
ifcopenshell.api.run(
"aggregate.assign_object",
self.file,
product=items,
relating_object=result,
)
else:
ifcopenshell.api.run(
"spatial.assign_container", self.file, product=items, relating_structure=result
"spatial.assign_container",
self.file,
product=items,
relating_structure=result,
)
SvIfcStore.id_map.setdefault(self.node_id, []).append(result.id())
spatial_ids.append(result.id())
@@ -129,24 +177,38 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
for element in self.elements[i]:
element_set = set([element])
for removed_element in subelements - element_set:
if removed_element.is_a("IfcSpatialElement") or removed_element.is_a(
"IfcSpatialStructureElement"
):
if removed_element.is_a(
"IfcSpatialElement"
) or removed_element.is_a("IfcSpatialStructureElement"):
ifcopenshell.api.run(
"aggregate.unassign_object", self.file, product=removed_element, relating_object=result
"aggregate.unassign_object",
self.file,
product=removed_element,
relating_object=result,
)
else:
ifcopenshell.api.run(
"spatial.unassign_container", self.file, product=removed_element, relating_object=result
"spatial.unassign_container",
self.file,
product=removed_element,
relating_object=result,
)
for added_element in element_set - subelements:
if added_element.is_a("IfcSpatialElement") or added_element.is_a("IfcSpatialStructureElement"):
if added_element.is_a(
"IfcSpatialElement"
) or added_element.is_a("IfcSpatialStructureElement"):
ifcopenshell.api.run(
"aggregate.assign_object", self.file, product=added_element, relating_object=result
"aggregate.assign_object",
self.file,
product=added_element,
relating_object=result,
)
else:
ifcopenshell.api.run(
"spatial.assign_container", self.file, product=added_element, relating_structure=result
"spatial.assign_container",
self.file,
product=added_element,
relating_structure=result,
)
spatial_ids.append(result.id())
SvIfcStore.id_map[self.node_id] = spatial_ids
@@ -163,7 +225,8 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
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)
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
+62 -21
View File
@@ -26,7 +26,13 @@ import ifcopenshell.api
from ifcsverchok.ifcstore import SvIfcStore
import blenderbim.tool as tool
import blenderbim.core.geometry as core
from bpy.props import StringProperty, EnumProperty, IntProperty, BoolProperty, PointerProperty
from bpy.props import (
StringProperty,
EnumProperty,
IntProperty,
BoolProperty,
PointerProperty,
)
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, flatten_data, fixed_iter, flat_iter
from blenderbim.bim.module.root.prop import get_contexts
@@ -36,7 +42,9 @@ from sverchok.core.socket_data import sv_get_socket
from itertools import chain, cycle
class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcBMeshToIfcRepr(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
"""
Triggers: BMesh to Ifc Repr
Tooltip: Blender mesh to Ifc Shape Representation
@@ -53,7 +61,9 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
updateNode(self, context)
self.refresh_local = False
refresh_local: BoolProperty(name="Update Node", description="Update Node", update=refresh_node)
refresh_local: BoolProperty(
name="Update Node", description="Update Node", update=refresh_node
)
context_types = [
("Model", "Model", "Context type: Model", 0),
@@ -73,10 +83,17 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
("SKETCH_VIEW", "SKETCH_VIEW", "Target View: SKETCH_VIEW", 3),
]
blender_objects: PointerProperty(
name="Blender Mesh(es)", description="Blender Mesh Object(s)", update=updateNode, type=bpy.types.Object
name="Blender Mesh(es)",
description="Blender Mesh Object(s)",
update=updateNode,
type=bpy.types.Object,
)
context_type: EnumProperty(
name="Context Type", description="Default: Model", default="Model", items=context_types, update=updateNode
name="Context Type",
description="Default: Model",
default="Model",
items=context_types,
update=updateNode,
)
context_identifier: EnumProperty(
name="Context Identifier",
@@ -96,16 +113,20 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "context_type").prop_name = "context_type"
self.inputs.new("SvStringsSocket", "context_identifier").prop_name = "context_identifier"
self.inputs.new(
"SvStringsSocket", "context_identifier"
).prop_name = "context_identifier"
self.inputs.new("SvStringsSocket", "target_view").prop_name = "target_view"
self.inputs.new("SvObjectSocket", "blender_objects").prop_name = "blender_objects" # no prop for now
self.inputs.new(
"SvObjectSocket", "blender_objects"
).prop_name = "blender_objects" # no prop for now
self.outputs.new("SvVerticesSocket", "Representations")
self.outputs.new("SvMatrixSocket", "Locations")
def draw_buttons(self, context, layout):
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = "Blender mesh to Ifc Shape Representation. \nTakes one or multiple geometries."
).tooltip = "Blender mesh to Ifc Shape Representation. \nTakes one or multiple geometries.\nDeconstructs joined geometries and creates a separate representation for each."
row = layout.row(align=True)
row.prop(self, "is_interactive", icon="SCENE_DATA", icon_only=True)
@@ -115,7 +136,9 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
self.sv_input_names = [i.name for i in self.inputs]
if hash(self) not in self.node_dict:
self.node_dict[hash(self)] = {} # happens if node is already on canvas when blender loads
self.node_dict[
hash(self)
] = {} # happens if node is already on canvas when blender loads
if not self.node_dict[hash(self)]:
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
@@ -179,16 +202,20 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
context=self.get_context(),
)
if not representation:
raise Exception("Couldn't create representation. Possibly wrong context.")
raise Exception(
"Couldn't create representation. Possibly wrong context."
)
representations_ids_obj.append(representation.id())
locations_obj.append(obj.matrix_world)
representations_ids.append(representations_ids_obj)
locations.append(locations_obj)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Representations", []).append(
representations_ids_obj
)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Locations", []).append(locations_obj)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault(
"Representations", []
).append(representations_ids_obj)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault(
"Locations", []
).append(locations_obj)
try:
bpy.ops.object.mode_set(mode="OBJECT")
except:
@@ -202,7 +229,9 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
for step_id in obj:
ifcopenshell.api.run(
"geometry.remove_representation", self.file, representation=self.file.by_id(step_id)
"geometry.remove_representation",
self.file,
representation=self.file.by_id(step_id),
)
del SvIfcStore.id_map[self.node_id]["Representations"]
del SvIfcStore.id_map[self.node_id]["Locations"]
@@ -213,9 +242,13 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
self.file, self.context_type, self.context_identifier, self.target_view
)
if not context:
parent = ifcopenshell.util.representation.get_context(self.file, self.context_type)
parent = ifcopenshell.util.representation.get_context(
self.file, self.context_type
)
if not parent:
parent = ifcopenshell.api.run("context.add_context", self.file, context_type=self.context_type)
parent = ifcopenshell.api.run(
"context.add_context", self.file, context_type=self.context_type
)
context = ifcopenshell.api.run(
"context.add_context",
self.file,
@@ -224,7 +257,9 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
target_view=self.target_view,
parent=parent,
)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Contexts", []).append(context.id())
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault(
"Contexts", []
).append(context.id())
return context
def sv_free(self):
@@ -234,7 +269,9 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
for step_id in obj:
ifcopenshell.api.run(
"geometry.remove_representation", self.file, representation=self.file.by_id(step_id)
"geometry.remove_representation",
self.file,
representation=self.file.by_id(step_id),
)
if "Contexts" in SvIfcStore.id_map[self.node_id]:
@@ -243,10 +280,14 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
if not self.file.get_inverse(context):
if self.file.by_id(context_id).ParentContext:
parent = self.file.by_id(context_id).ParentContext
ifcopenshell.api.run("context.remove_context", self.file, context=context)
ifcopenshell.api.run(
"context.remove_context", self.file, context=context
)
if parent:
if not self.file.get_inverse(parent):
ifcopenshell.api.run("context.remove_context", self.file, context=parent)
ifcopenshell.api.run(
"context.remove_context", self.file, context=parent
)
# print("Removed context with step ID: ", context_id)
SvIfcStore.id_map[self.node_id]["Contexts"].remove(context_id)
del SvIfcStore.id_map[self.node_id]
+26 -9
View File
@@ -16,31 +16,48 @@
# You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>.
import itertools
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
from sverchok.data_structure import updateNode, flatten_data
class SvIfcByGuid(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcByGuid"
bl_label = "IFC By Guid"
file: StringProperty(name="file", update=updateNode)
guid: StringProperty(name="guid", update=updateNode)
n_id: StringProperty(default="")
guid: StringProperty(name="Guid(s)", update=updateNode)
id_iter = itertools.count()
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "file").prop_name = "file"
self.inputs.new("SvStringsSocket", "guid").prop_name = "guid"
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 guid. Takes one or multiple guids."
def process(self):
self.sv_input_names = ["file", "guid"]
super().process()
print("\n\n", "#" * 30, "Running SvIfcByGuid node", "#" * 30)
print("self: ", self)
print("id(self): ", id(self))
print("hash(self): ", hash(self))
print("node_id: ", self.node_id)
self.id = next(self.id_iter)
print("self.id (itertool counter): ", self.id)
def process_ifc(self, file, guid):
self.outputs["entity"].sv_set([[file.by_guid(guid)]])
self.guids = flatten_data(self.inputs["guid"].sv_get(), target_level=1)
if not self.guids[0]:
return
self.file = SvIfcStore.get_file()
self.entities = [self.file.by_guid(guid) for guid in self.guids]
self.outputs["Entities"].sv_set(self.entities)
def register():
+26 -11
View File
@@ -48,7 +48,11 @@ def get_ifc_products(self, context):
]
)
if file.schema == "IFC2X3":
ifc_products[2] = ("IfcSpatialStructureElement", "IfcSpatialStructureElement", "")
ifc_products[2] = (
"IfcSpatialStructureElement",
"IfcSpatialStructureElement",
"",
)
return ifc_products
@@ -90,25 +94,31 @@ class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
update=update_ifc_products,
)
ifc_class: EnumProperty(
items=get_ifc_classes, name="IfcClass", description="Pick an IfcClass from drop-down.", update=updateNode
items=get_ifc_classes,
name="IfcClass",
description="Pick an IfcClass from drop-down.",
update=updateNode,
)
custom_ifc_class: StringProperty(
name="Custom IfcClass", description="Give the name of your custom IfcClass.", update=updateNode
name="Custom IfcClass",
description="Give the name of your custom IfcClass.",
update=updateNode,
)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "ifc_product").prop_name = "ifc_product"
self.inputs.new("SvStringsSocket", "ifc_class").prop_name = "ifc_class"
self.inputs.new("SvStringsSocket", "custom_ifc_class").prop_name = "custom_ifc_class"
self.outputs.new("SvStringsSocket", "Entity")
self.inputs.new(
"SvStringsSocket", "custom_ifc_class"
).prop_name = "custom_ifc_class"
self.outputs.new("SvStringsSocket", "Entities")
self.outputs.new("SvStringsSocket", "Entity Ids")
self.width = 200
def draw_buttons(self, context, layout):
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = (
"Get IFC element(s) in file by type. \nPick an IfcProduct and an IfcClass or give a custom IfcClass."
)
).tooltip = "Get IFC element(s) in file by type. \nPick an IfcProduct and an IfcClass or give a custom IfcClass."
def process(self):
self.file = SvIfcStore.get_file()
@@ -120,11 +130,16 @@ class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
def process_ifc(self, ifc_product, ifc_class, custom_ifc_class):
if custom_ifc_class:
self.outputs["Entity"].sv_set([self.file.by_type(custom_ifc_class)])
entities = self.file.by_type(custom_ifc_class)
self.outputs["Entities"].sv_set(entities)
self.outputs["Entity Ids"].sv_set([e.id() for e in entities])
elif ifc_class:
self.outputs["Entity"].sv_set([self.file.by_type(ifc_class)])
entities = self.file.by_type(ifc_class)
self.outputs["Entities"].sv_set(self.file.by_type(ifc_class))
self.outputs["Entity Ids"].sv_set([e.id() for e in entities])
else:
self.outputs["Entity"].sv_set([])
self.outputs["Entities"].sv_set([])
self.outputs["Entity Ids"].sv_set([])
def register():
+89 -25
View File
@@ -24,10 +24,17 @@ from ifcsverchok.ifcstore import SvIfcStore
from bpy.props import StringProperty, BoolProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, flatten_data, repeat_last_for_length, ensure_min_nesting
from sverchok.data_structure import (
updateNode,
flatten_data,
repeat_last_for_length,
ensure_min_nesting,
)
class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcCreateEntity(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
bl_idname = "SvIfcCreateEntity"
bl_label = "IFC Create Entity"
node_dict = {}
@@ -39,12 +46,29 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
self.process()
self.refresh_local = False
refresh_local: BoolProperty(name="Update Node", description="Update Node", update=refresh_node)
refresh_local: BoolProperty(
name="Update Node", description="Update Node", update=refresh_node
)
Names: StringProperty(name="Names", default="", update=updateNode)
Descriptions: StringProperty(name="Descriptions", default="", update=updateNode)
Names: StringProperty(
name="Names",
default="",
description="Entity name or list of names.",
update=updateNode,
)
Descriptions: StringProperty(
name="Descriptions",
default="",
description="Entity description or list of descriptions.",
update=updateNode,
)
IfcClass: StringProperty(name="IfcClass", update=updateNode)
Representations: StringProperty(name="Representations", default="", update=updateNode)
Representations: StringProperty(
name="Representations",
description='IfcRepresentation(s). Use eg. "IFC BMesh to IFC" or "IFC Sverchok to IFC" nodes to create representations.',
default="",
update=updateNode,
)
# Locations: FloatVectorProperty(name="Locations", default="", update=updateNode)
Properties: StringProperty(name="properties", update=updateNode)
@@ -52,7 +76,9 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
self.inputs.new("SvStringsSocket", "Names").prop_name = "Names"
self.inputs.new("SvStringsSocket", "Descriptions").prop_name = "Descriptions"
self.inputs.new("SvStringsSocket", "IfcClass").prop_name = "IfcClass"
self.inputs.new("SvStringsSocket", "Representations").prop_name = "Representations"
self.inputs.new(
"SvStringsSocket", "Representations"
).prop_name = "Representations"
self.inputs.new("SvMatrixSocket", "Locations").is_mandatory = False
self.inputs.new("SvStringsSocket", "Properties").prop_name = "Properties"
self.outputs.new("SvStringsSocket", "Entities")
@@ -69,17 +95,27 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
def process(self):
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 = flatten_data(self.inputs["IfcClass"].sv_get(), target_level=1)[0]
self.representations = ensure_min_nesting(self.inputs["Representations"].sv_get(), 2)
self.descriptions = flatten_data(
self.inputs["Descriptions"].sv_get(), target_level=1
)
self.ifc_class = flatten_data(self.inputs["IfcClass"].sv_get(), target_level=1)[
0
]
self.representations = ensure_min_nesting(
self.inputs["Representations"].sv_get(), 2
)
self.representations = flatten_data(self.representations, target_level=2)
self.locations = ensure_min_nesting(self.inputs["Locations"].sv_get(default=[]), 2)
self.locations = ensure_min_nesting(
self.inputs["Locations"].sv_get(default=[]), 2
)
self.properties = self.inputs["Properties"].sv_get()
self.sv_input_names = [i.name for i in self.inputs]
if hash(self) not in self.node_dict:
self.node_dict[hash(self)] = {} # happens if node is already on canvas when blender loads
self.node_dict[
hash(self)
] = {} # happens if node is already on canvas when blender loads
if not self.node_dict[hash(self)]:
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
if not self.inputs["IfcClass"].sv_get()[0][0]:
@@ -87,7 +123,9 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
edit = False
for i in range(len(self.inputs)):
input = self.inputs[self.sv_input_names[i]].sv_get(deepcopy=True, default=[])
input = self.inputs[self.sv_input_names[i]].sv_get(
deepcopy=True, default=[]
)
if (
isinstance(self.node_dict[hash(self)][self.inputs[i].name], list)
and input != self.node_dict[hash(self)][self.inputs[i].name]
@@ -103,14 +141,19 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
try:
# self.representations = [self.file.by_id(step_id) for step_id in self.representations]
self.representations = [
[self.file.by_id(step_id) for step_id in representation] for representation in self.representations
[self.file.by_id(step_id) for step_id in representation]
for representation in self.representations
]
except Exception as e:
raise
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.descriptions = self.repeat_input_unique(
self.descriptions, len(self.representations)
)
elif not self.representations[0][0]:
self.descriptions = self.repeat_input_unique(
self.descriptions, len(self.names)
)
if self.node_id not in SvIfcStore.id_map:
entities = self.create()
@@ -137,19 +180,29 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
name=self.names[i],
description=self.descriptions[i],
)
print("Entity: ", entity)
try:
print("Representations: ", self.representations[i])
for repr in self.representations[i]:
if self.representations[i]:
print("Representation: ", repr)
if repr:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=entity, representation=repr
"geometry.assign_representation",
self.file,
product=entity,
representation=repr,
)
except IndexError:
pass
try:
for loc in self.locations[i]:
if isinstance(self.locations[i], Matrix):
print("Location: ", loc)
if isinstance(loc, Matrix):
ifcopenshell.api.run(
"geometry.edit_object_placement", self.file, product=entity, matrix=loc
"geometry.edit_object_placement",
self.file,
product=entity,
matrix=loc,
)
except IndexError:
pass
@@ -179,19 +232,29 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
entity.Representation = repr
elif repr:
ifcopenshell.api.run(
"geometry.assign_representation", self.file, product=entity, representation=repr
"geometry.assign_representation",
self.file,
product=entity,
representation=repr,
)
except IndexError:
pass
try:
for loc in self.locations[i]:
if isinstance(loc, Matrix):
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=entity, matrix=loc)
ifcopenshell.api.run(
"geometry.edit_object_placement",
self.file,
product=entity,
matrix=loc,
)
except IndexError:
pass
if entity.is_a() != self.ifc_class:
SvIfcStore.id_map[self.node_id].remove(step_id)
entity = ifcopenshell.util.schema.reassign_class(self.file, entity, self.ifc_class)
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())
@@ -203,7 +266,8 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
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)
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
+2 -2
View File
@@ -46,7 +46,7 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
bl_idname = "SvIfcCreateShape"
bl_label = "IFC Create Blender Shape"
entity: StringProperty(name="Entities", update=updateNode)
entity: StringProperty(name="Entity Id(s)", update=updateNode)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "Entities").prop_name = "entity"
@@ -56,7 +56,7 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
row = layout.row(align=True)
row.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = "Create Blender shape from IfcEntity ID. Takes one or multiple IfcEntity IDs."
).tooltip = "Create Blender shape from IfcEntity Id. Takes one or multiple IfcEntity IDs."
row.prop(self, "refresh_local", icon="FILE_REFRESH")
def process(self):
+34 -6
View File
@@ -20,25 +20,53 @@ import bpy
import ifcopenshell
import ifcopenshell.util.element
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
from sverchok.data_structure import updateNode, flatten_data
class SvIfcGetAttribute(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcGetAttribute(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
bl_idname = "SvIfcGetAttribute"
bl_label = "IFC Get Attribute"
entity: StringProperty(name="entity", update=updateNode)
attribute_name: StringProperty(name="attribute_name", update=updateNode)
entity: StringProperty(name="Entity Ids", update=updateNode)
attribute_name: StringProperty(
name="Attribute name",
description='Name of attribute, eg. "Name".',
update=updateNode,
)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "entity").prop_name = "entity"
self.inputs.new("SvStringsSocket", "attribute_name").prop_name = "attribute_name"
self.inputs.new(
"SvStringsSocket", "attribute_name"
).prop_name = "attribute_name"
self.outputs.new("SvStringsSocket", "value")
def draw_buttons(self, context, layout):
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = (
"Get the value of an attribute of an IfcEntity. Can take multiple entities."
)
def process(self):
self.value_out = []
entity_nested_inputs = self.inputs["entity"].sv_get()
entity_nested_input_ids = flatten_data(
self.inputs["entity"].sv_get(), target_level=1
)
if not entity_nested_input_ids[0]:
return
self.file = SvIfcStore.get_file()
try:
entity_nested_inputs = [
self.file.by_id(int(step_id)) for step_id in entity_nested_input_ids
]
print(entity_nested_inputs)
except Exception as e:
raise Exception("Instance ID not found", e)
attribute_name = self.inputs["attribute_name"].sv_get()[0][0]
for entities in entity_nested_inputs:
if hasattr(entities, "__iter__"):
+44 -15
View File
@@ -20,35 +20,64 @@ import bpy
import ifcopenshell
import ifcopenshell.util.element
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
from sverchok.data_structure import updateNode, flatten_data
class SvIfcGetProperty(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcGetProperty(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
bl_idname = "SvIfcGetProperty"
bl_label = "IFC Get Property"
entity: StringProperty(name="entity", update=updateNode)
pset_name: StringProperty(name="pset_name", update=updateNode)
prop_name: StringProperty(name="prop_name", update=updateNode)
entity: StringProperty(name="Entity Ids", update=updateNode)
pset_name: StringProperty(
name="Pset Name",
description='Name of the property set, eg. "Pset_WallCommon".',
update=updateNode,
)
prop_name: StringProperty(
name="Prop Name",
description='Name of the property, eg. "IsExternal".',
update=updateNode,
)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "entity").prop_name = "entity"
self.inputs.new("SvStringsSocket", "entity_ids").prop_name = "entity"
self.inputs.new("SvStringsSocket", "pset_name").prop_name = "pset_name"
self.inputs.new("SvStringsSocket", "prop_name").prop_name = "prop_name"
self.outputs.new("SvStringsSocket", "value")
def process(self):
self.sv_input_names = ["entity", "pset_name", "prop_name"]
self.value_out = []
super().process()
self.outputs["value"].sv_set(self.value_out)
def draw_buttons(self, context, layout):
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = (
"Get the value of a property of an IfcEntity. Can take multiple entity ids."
)
def process_ifc(self, entity, pset_name, prop_name):
def process(self):
self.sv_input_names = ["entity_ids", "pset_name", "prop_name"]
entities_ids = flatten_data(self.inputs["entity_ids"].sv_get(), target_level=1)
pset_name = flatten_data(self.inputs["pset_name"].sv_get(), target_level=1)[0]
prop_name = flatten_data(self.inputs["prop_name"].sv_get(), target_level=1)[0]
if not entities_ids[0]:
return
self.file = SvIfcStore.get_file()
try:
self.value_out.append(ifcopenshell.util.element.get_psets(entity)[pset_name][prop_name])
except:
pass
self.entities = [self.file.by_id(int(step_id)) for step_id in entities_ids]
except Exception as e:
raise Exception(f"Invalid entity id: {e}")
self.value_out = []
for entity in self.entities:
try:
self.value_out.append(
ifcopenshell.util.element.get_psets(entity)[pset_name][prop_name]
)
except:
pass
self.outputs["value"].sv_set(self.value_out)
def register():
+36 -18
View File
@@ -19,30 +19,50 @@
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
from sverchok.data_structure import updateNode, ensure_min_nesting, flatten_data
class SvIfcReadEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcReadEntity(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
bl_idname = "SvIfcReadEntity"
bl_label = "IFC Read Entity"
file: StringProperty(name="file", update=updateNode)
entity: StringProperty(name="entity", update=updateNode)
entity: StringProperty(name="Entity Id", update=updateNode)
current_ifc_class: StringProperty(name="current_ifc_class")
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "file").prop_name = "file"
self.inputs.new("SvStringsSocket", "entity").prop_name = "entity"
self.outputs.new("SvStringsSocket", "id")
self.outputs.new("SvStringsSocket", "is_a")
def draw_buttons(self, context, layout):
layout.operator(
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
).tooltip = (
"Decompose an IfcEntity into its attributes. Takes one entity id as input"
)
def process(self):
self.sv_input_names = ["file", "entity"]
ifc_class = self.inputs["entity"].sv_get()[0][0]
if ifc_class:
ifc_class = ifc_class.is_a()
file = self.inputs["file"].sv_get()[0][0]
self.sv_input_names = ["entity"]
# ifc_class = ensure_min_nesting(self.inputs["entity"].sv_get(), 1)
entity_id = flatten_data(self.inputs["entity"].sv_get(), target_level=1)
print("entity_id", entity_id)
if not entity_id[0]:
return
if len(entity_id) > 1:
raise Exception("Only one entity can be read at a time")
self.file = SvIfcStore.get_file()
try:
entity = self.file.by_id(entity_id[0])
except Exception as e:
raise Exception("Instance with id {} not found".format(entity_id), e)
if entity:
ifc_class = entity.is_a()
file = SvIfcStore.get_file()
if file:
schema_name = file.wrapped_data.schema
else:
@@ -52,7 +72,12 @@ class SvIfcReadEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.S
if ifc_class != self.current_ifc_class:
self.generate_outputs(ifc_class)
super().process()
self.outputs["id"].sv_set([entity.id()])
self.outputs["is_a"].sv_set([entity.is_a()])
for i in range(0, self.entity_schema.attribute_count()):
name = self.entity_schema.attribute_by_index(i).name()
self.outputs[name].sv_set([entity[i]])
def generate_outputs(self, ifc_class):
while len(self.outputs) > 2:
@@ -62,13 +87,6 @@ class SvIfcReadEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.S
self.outputs.new("SvStringsSocket", name).prop_name = name
self.current_ifc_class = ifc_class
def process_ifc(self, entity):
self.outputs["id"].sv_set([[entity.id()]])
self.outputs["is_a"].sv_set([[entity.is_a()]])
for i in range(0, self.entity_schema.attribute_count()):
name = self.entity_schema.attribute_by_index(i).name()
self.outputs[name].sv_set([[entity[i]]])
def register():
bpy.utils.register_class(SvIfcReadEntity)
+44 -16
View File
@@ -29,7 +29,9 @@ from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, ensure_min_nesting
class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
class SvIfcSverchokToIfcRepr(
bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore
):
"""
Triggers: Sv to Ifc Repr
Tooltip: Sverchok geometry to Ifc Shape Representation
@@ -59,7 +61,11 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
]
context_type: EnumProperty(
name="Context Type", description="Default: Model", default="Model", items=context_types, update=updateNode
name="Context Type",
description="Default: Model",
default="Model",
items=context_types,
update=updateNode,
)
context_identifier: EnumProperty(
name="Context Identifier",
@@ -78,7 +84,9 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "context_type").prop_name = "context_type"
self.inputs.new("SvStringsSocket", "context_identifier").prop_name = "context_identifier"
self.inputs.new(
"SvStringsSocket", "context_identifier"
).prop_name = "context_identifier"
self.inputs.new("SvStringsSocket", "target_view").prop_name = "target_view"
self.inputs.new("SvVerticesSocket", "Vertices")
self.inputs.new("SvStringsSocket", "Edges")
@@ -99,7 +107,9 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
self.sv_input_names = [i.name for i in self.inputs]
if hash(self) not in self.node_dict:
self.node_dict[hash(self)] = {} # happens if node is already on canvas when blender loads
self.node_dict[
hash(self)
] = {} # happens if node is already on canvas when blender loads
if not self.node_dict[hash(self)]:
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
@@ -113,7 +123,9 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
edit = True
self.node_dict[hash(self)][self.inputs[i].name] = input
self.vertices = ensure_min_nesting(self.inputs["Vertices"].sv_get(deepcopy=False), 4)
self.vertices = ensure_min_nesting(
self.inputs["Vertices"].sv_get(deepcopy=False), 4
)
self.edges = ensure_min_nesting(self.inputs["Edges"].sv_get(deepcopy=False), 4)
self.faces = ensure_min_nesting(self.inputs["Faces"].sv_get(deepcopy=False), 4)
data = list(zip(self.vertices, self.edges, self.faces))
@@ -147,12 +159,14 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
faces=[list(map(tuple, item[2]))],
)
if not representation:
raise Exception("Couldn't create representation. Possibly wrong context.")
raise Exception(
"Couldn't create representation. Possibly wrong context."
)
representations_ids_obj.append(representation.id())
representations_ids.append(representations_ids_obj)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Representations", []).append(
representations_ids_obj
)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault(
"Representations", []
).append(representations_ids_obj)
return representations_ids
def edit(self):
@@ -161,7 +175,9 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
for step_id in obj:
ifcopenshell.api.run(
"geometry.remove_representation", self.file, representation=self.file.by_id(step_id)
"geometry.remove_representation",
self.file,
representation=self.file.by_id(step_id),
)
del SvIfcStore.id_map[self.node_id]["Representations"]
return
@@ -171,9 +187,13 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
self.file, self.context_type, self.context_identifier, self.target_view
)
if not context:
parent = ifcopenshell.util.representation.get_context(self.file, self.context_type)
parent = ifcopenshell.util.representation.get_context(
self.file, self.context_type
)
if not parent:
parent = ifcopenshell.api.run("context.add_context", self.file, context_type=self.context_type)
parent = ifcopenshell.api.run(
"context.add_context", self.file, context_type=self.context_type
)
context = ifcopenshell.api.run(
"context.add_context",
self.file,
@@ -182,7 +202,9 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
target_view=self.target_view,
parent=parent,
)
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Contexts", []).append(context.id())
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault(
"Contexts", []
).append(context.id())
return context
def sv_free(self):
@@ -191,7 +213,9 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
if "Representations" in SvIfcStore.id_map[self.node_id]:
for step_id in SvIfcStore.id_map[self.node_id]["Representations"]:
ifcopenshell.api.run(
"geometry.remove_representation", self.file, representation=self.file.by_id(step_id)
"geometry.remove_representation",
self.file,
representation=self.file.by_id(step_id),
)
if "Contexts" in SvIfcStore.id_map[self.node_id]:
@@ -200,10 +224,14 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
if not self.file.get_inverse(context):
if self.file.by_id(context_id).ParentContext:
parent = self.file.by_id(context_id).ParentContext
ifcopenshell.api.run("context.remove_context", self.file, context=context)
ifcopenshell.api.run(
"context.remove_context", self.file, context=context
)
if parent:
if not self.file.get_inverse(parent):
ifcopenshell.api.run("context.remove_context", self.file, context=parent)
ifcopenshell.api.run(
"context.remove_context", self.file, context=parent
)
# print("Removed context with step ID: ", context_id)
SvIfcStore.id_map[self.node_id]["Contexts"].remove(context_id)
del SvIfcStore.id_map[self.node_id]