Files
IfcOpenShell/src/ifcsverchok/nodes/ifc/create_entity.py
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

191 lines
8.4 KiB
Python
Raw Normal View History

import bpy
from mathutils import Matrix, Vector
import ifcopenshell
import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore
# import ifcsverchok.ifc_store
# from bpy.props import StringProperty
# from sverchok.node_tree import SverchCustomTreeNode
# from sverchok.data_structure import updateNode
2021-08-17 08:39:38 +10:00
2020-10-01 14:47:42 +10:00
import bpy
import ifcopenshell
2022-10-24 00:08:59 +02:00
from bpy.props import StringProperty, EnumProperty, IntProperty, BoolProperty
2020-10-01 14:47:42 +10:00
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, flatten_data, repeat_last_for_length
2020-10-01 14:47:42 +10:00
class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcCreateEntity"
bl_label = "IFC Create Entity"
node_dict = {}
is_scene_dependent = True # if True and is_interactive then the node will be updated upon scene changes
def refresh_node(self, context):
if self.refresh_local:
self.process()
self.refresh_local = False
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)
IfcClass: StringProperty(name="IfcClass", update=updateNode)
Representations: StringProperty(name="Representations", default="", update=updateNode)
2022-10-24 00:08:59 +02:00
# Locations: FloatVectorProperty(name="Locations", default="", update=updateNode)
Properties: StringProperty(name="properties", update=updateNode)
2020-10-01 14:47:42 +10:00
def sv_init(self, context):
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"
2022-10-24 00:08:59 +02:00
self.inputs.new("SvMatrixSocket", "Locations").is_mandatory=False
self.inputs.new("SvStringsSocket", "Properties").prop_name = "Properties"
self.outputs.new("SvStringsSocket", "Entities")
self.node_dict[hash(self)] = {}
2020-10-01 14:47:42 +10:00
2022-10-21 00:11:45 +02:00
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')
2020-10-01 14:47:42 +10:00
def process(self):
2022-10-21 00:11:45 +02:00
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]
2022-10-21 00:11:45 +02:00
self.representations = flatten_data(self.inputs["Representations"].sv_get(), target_level=1)
2022-10-24 00:08:59 +02:00
self.locations = flatten_data(self.inputs["Locations"].sv_get(default=[]), target_level=1)
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
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]:
raise Exception('Mandatory input "IfcClass" is missing.')
edit = False
for i in range(len(self.inputs)):
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]:
edit = True
self.node_dict[hash(self)][self.inputs[i].name] = input.copy()
if self.refresh_local:
edit = True
2022-10-21 00:11:45 +02:00
self.file = SvIfcStore.get_file()
if self.representations[0]:
try:
self.representations = [self.file.by_id(step_id) for step_id in self.representations]
except Exception as e:
raise
2022-10-21 00:11:45 +02:00
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))
if self.node_id not in SvIfcStore.id_map:
2022-10-21 00:11:45 +02:00
entities = self.create()
else:
if edit is True:
2022-10-21 00:11:45 +02:00
entities = self.edit()
else:
2022-10-21 00:11:45 +02:00
entities = SvIfcStore.id_map[self.node_id]
2022-10-21 00:11:45 +02:00
print("Entities: ", entities)
2022-10-21 00:11:45 +02:00
self.outputs["Entities"].sv_set(entities)
2022-10-21 00:11:45 +02:00
def create(self, index=None):
entities_ids = []
iterator = range(len(self.names))
if index is not None:
iterator = [index]
for i in iterator:
2020-10-01 14:47:42 +10:00
try:
2022-10-21 00:11:45 +02:00
entity = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=self.ifc_class, name=self.names[i], description=self.descriptions[i])
try:
if self.representations[i]:
ifcopenshell.api.run("geometry.assign_representation", self.file, product=entity, representation=self.representations[i])
except IndexError:
pass
2022-10-24 00:08:59 +02:00
try:
if isinstance(self.locations[i], Matrix):
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=entity, matrix=self.locations[i])
2022-10-24 00:08:59 +02:00
except IndexError:
pass
2022-10-21 00:11:45 +02:00
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):
2022-10-21 00:11:45 +02:00
entities_ids = []
id_map_copy = SvIfcStore.id_map[self.node_id].copy()
2022-10-21 00:11:45 +02:00
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]
try:
if self.representations[i] and self.representations[i].is_a('IfcProductDefinitionShape'):
2022-10-21 00:11:45 +02:00
entity.Representation = self.representations[i]
elif self.representations[i]:
ifcopenshell.api.run("geometry.assign_representation", self.file, product=entity, representation=self.representations[i])
2022-10-21 00:11:45 +02:00
except IndexError:
pass
2022-10-24 00:08:59 +02:00
try:
if isinstance(self.locations[i], Matrix):
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=entity, matrix=self.locations[i])
2022-10-24 00:08:59 +02:00
except IndexError:
pass
2022-10-21 00:11:45 +02:00
if entity.is_a() != self.ifc_class:
SvIfcStore.id_map[self.node_id].remove(step_id)
2022-10-21 00:11:45 +02:00
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
def sv_free(self):
try:
del SvIfcStore.id_map[self.node_id]
del self.node_dict[hash(self)]
print('Node was deleted')
except KeyError or AttributeError:
pass
2020-10-01 14:47:42 +10:00
2020-11-01 19:24:01 +07:00
2020-10-01 14:47:42 +10:00
def register():
bpy.utils.register_class(SvIfcCreateEntity)
2020-11-01 19:24:01 +07:00
2020-10-01 14:47:42 +10:00
def unregister():
bpy.utils.unregister_class(SvIfcCreateEntity)