This commit is contained in:
Andrej730
2025-03-21 12:53:13 +05:00
parent a567af370b
commit e075c32a5a
19 changed files with 90 additions and 77 deletions
@@ -163,7 +163,7 @@ def remove_all_listeners():
post_listeners.clear() post_listeners.clear()
def extract_docs(module, usecase): def extract_docs(module: str, usecase: str) -> dict[str, Any]:
import typing import typing
import collections import collections
+3
View File
@@ -161,9 +161,12 @@ class IFC_Sv_UpdateCurrent(bpy.types.Operator):
# infra-related spatial structure elements, such as IfcBridge. # infra-related spatial structure elements, such as IfcBridge.
# https://github.com/IfcOpenShell/IfcOpenShell/pull/2576#discussion_r1016261407 # https://github.com/IfcOpenShell/IfcOpenShell/pull/2576#discussion_r1016261407
def execute(self, context): def execute(self, context):
import sverchok.node_tree
self.file = SvIfcStore.purge() self.file = SvIfcStore.purge()
node_tree = context.space_data.node_tree node_tree = context.space_data.node_tree
if node_tree: if node_tree:
assert isinstance(node_tree, sverchok.node_tree.SverchCustomTree)
if self.force_mode or node_tree.sv_process: if self.force_mode or node_tree.sv_process:
try: try:
bpy.context.window.cursor_set("WAIT") bpy.context.window.cursor_set("WAIT")
+3 -2
View File
@@ -21,7 +21,7 @@ import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.representation import ifcopenshell.util.representation
from ifcopenshell import template from ifcopenshell import template
from typing import Union from typing import Union, Any
class SvIfcStore: class SvIfcStore:
@@ -30,7 +30,8 @@ class SvIfcStore:
schema = None schema = None
cache = None cache = None
cache_path = None cache_path = None
id_map = {} id_map: dict[str, Any] = {}
"""Mapping `{node_id: Any}`"""
guid_map = {} guid_map = {}
deleted_ids = set() deleted_ids = set()
edited_objs = set() edited_objs = set()
+3 -3
View File
@@ -38,13 +38,13 @@ class SvIfcAdd(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
def process(self): def process(self):
self.sv_input_names = ["file", "entity"] self.sv_input_names = ["file", "entity"]
self.file_out = [] self.file_out: list[ifcopenshell.file] = []
self.entity_out = [] self.entity_out: list[ifcopenshell.entity_instance] = []
super().process() super().process()
self.outputs["file"].sv_set([self.file_out]) self.outputs["file"].sv_set([self.file_out])
self.outputs["entity"].sv_set([self.entity_out]) self.outputs["entity"].sv_set([self.entity_out])
def process_ifc(self, file, entity): def process_ifc(self, file: ifcopenshell.file, entity: ifcopenshell.entity_instance) -> None:
self.entity_out.append(file.add(entity)) self.entity_out.append(file.add(entity))
self.file_out.append(file) self.file_out.append(file)
+12 -8
View File
@@ -25,6 +25,8 @@ from ifcsverchok.ifcstore import SvIfcStore
import bpy import bpy
import json import json
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.pset
from bpy.props import StringProperty from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode from sverchok.node_tree import SverchCustomTreeNode
@@ -80,12 +82,13 @@ class SvIfcAddPset(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIf
self.outputs["Entity"].sv_set([element]) self.outputs["Entity"].sv_set([element])
def create(self, name, properties, elements): def create(
self, name: str, properties: str, elements: list[ifcopenshell.entity_instance]
) -> list[ifcopenshell.entity_instance]:
results = [] results = []
for element in elements: for element in elements:
result = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name=name) result = ifcopenshell.api.pset.add_pset(self.file, product=element, name=name)
ifcopenshell.api.run( ifcopenshell.api.pset.edit_pset(
"pset.edit_pset",
self.file, self.file,
pset=result, pset=result,
properties=json.loads(properties), properties=json.loads(properties),
@@ -94,13 +97,14 @@ class SvIfcAddPset(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIf
results.append(result) results.append(result)
return results return results
def edit(self, name, properties, elements): def edit(
self, name: str, properties: str, elements: list[ifcopenshell.entity_instance]
) -> list[ifcopenshell.entity_instance]:
result_ids = SvIfcStore.id_map[self.node_id] result_ids = SvIfcStore.id_map[self.node_id]
results = [] results: list[ifcopenshell.entity_instance] = []
for result_id in result_ids: for result_id in result_ids:
result = self.file.by_id(result_id) result = self.file.by_id(result_id)
ifcopenshell.api.run( ifcopenshell.api.pset.edit_pset(
"pset.edit_pset",
self.file, self.file,
pset=result, pset=result,
name=name, name=name,
@@ -221,7 +221,6 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
try: try:
del SvIfcStore.id_map[self.node_id] del SvIfcStore.id_map[self.node_id]
del self.node_dict[hash(self)] del self.node_dict[hash(self)]
# print('Node was deleted')
except KeyError or AttributeError: except KeyError or AttributeError:
pass pass
+5 -4
View File
@@ -24,11 +24,12 @@ from bpy.props import StringProperty, EnumProperty
from sverchok.node_tree import SverchCustomTreeNode from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode from sverchok.data_structure import updateNode
import logging import logging
from typing import Union, Any
logger = logging.getLogger("sverchok.ifc") logger = logging.getLogger("sverchok.ifc")
def update_usecase(self, context): def update_usecase(self: "SvIfcApi", context: bpy.types.Context) -> None:
module_usecase = self.get_module_usecase() module_usecase = self.get_module_usecase()
if module_usecase: if module_usecase:
self.generate_node(*module_usecase) self.generate_node(*module_usecase)
@@ -68,12 +69,12 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
self.sv_input_names = [i.name for i in self.inputs] self.sv_input_names = [i.name for i in self.inputs]
super().process() super().process()
def get_module_usecase(self): def get_module_usecase(self) -> Union[list[str], None]:
usecase = self.inputs["usecase"].sv_get()[0][0] usecase = self.inputs["usecase"].sv_get()[0][0]
if usecase: if usecase:
return usecase.split(".") return usecase.split(".")
def generate_node(self, module, usecase): def generate_node(self, module: str, usecase: str) -> None:
try: try:
node_data = ifcopenshell.api.extract_docs(module, usecase) node_data = ifcopenshell.api.extract_docs(module, usecase)
except: except:
@@ -92,7 +93,7 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
self.tooltip = f"{name}: {data['description']}\n" self.tooltip = f"{name}: {data['description']}\n"
self.tooltip = self.tooltip.strip() self.tooltip = self.tooltip.strip()
def process_ifc(self, usecase, *setting_values): def process_ifc(self, usecase: Union[str, None], *setting_values: Any) -> None:
if usecase: if usecase:
settings = dict(zip(self.sv_input_names[1:], setting_values)) settings = dict(zip(self.sv_input_names[1:], setting_values))
settings = {k: v for k, v in settings.items() if v != ""} settings = {k: v for k, v in settings.items() if v != ""}
+14 -12
View File
@@ -23,6 +23,8 @@ import bpy
import ifcopenshell import ifcopenshell
import ifcsverchok.helper import ifcsverchok.helper
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.util.representation
from ifcsverchok.ifcstore import SvIfcStore from ifcsverchok.ifcstore import SvIfcStore
import bonsai.tool as tool import bonsai.tool as tool
import bonsai.core.geometry as core import bonsai.core.geometry as core
@@ -40,6 +42,7 @@ from sverchok.data_structure import zip_long_repeat, node_id
from sverchok.core.socket_data import sv_get_socket from sverchok.core.socket_data import sv_get_socket
from itertools import chain, cycle from itertools import chain, cycle
from mathutils import Matrix
class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
@@ -162,9 +165,9 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
self.outputs["Representations"].sv_set(representations) self.outputs["Representations"].sv_set(representations)
self.outputs["Locations"].sv_set(locations) self.outputs["Locations"].sv_set(locations)
def create(self, blender_objects): def create(self, blender_objects: list[bpy.types.Object]) -> tuple[list[list[list[int]]], list[list[list[Matrix]]]]:
representations_ids = [] representations_ids: list[list[list[int]]] = []
locations = [] locations: list[list[list[Matrix]]] = []
context = self.get_context() context = self.get_context()
for blender_object in blender_objects: for blender_object in blender_objects:
bpy.context.view_layer.objects.active = blender_object bpy.context.view_layer.objects.active = blender_object
@@ -183,8 +186,8 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
bpy.ops.mesh.separate( bpy.ops.mesh.separate(
type="LOOSE" type="LOOSE"
) # This isn't a great solution bc it creates new objects in the scene, thus changing the users model ) # This isn't a great solution bc it creates new objects in the scene, thus changing the users model
representations_ids_obj = [] representations_ids_obj: list[list[int]] = []
locations_obj = [] locations_obj: list[list[Matrix]] = []
try: try:
bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="OBJECT")
except Exception as e: except Exception as e:
@@ -192,16 +195,16 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
pass pass
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
if blender_object.type == "MESH": if blender_object.type == "MESH":
representation = ifcopenshell.api.run( representation = ifcopenshell.api.geometry.add_representation(
"geometry.add_representation",
self.file, self.file,
should_run_listeners=False,
blender_object=obj, blender_object=obj,
geometry=obj.data, geometry=obj.data,
context=context, context=context,
should_run_listeners=False,
) )
if not representation: if not representation:
raise Exception("Couldn't create representation. Possibly wrong context.") raise Exception("Couldn't create representation. Possibly wrong context.")
assert isinstance(representation, ifcopenshell.entity_instance)
representations_ids_obj.append([representation.id()]) representations_ids_obj.append([representation.id()])
locations_obj.append([obj.matrix_world]) locations_obj.append([obj.matrix_world])
@@ -215,7 +218,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
bpy.ops.object.select_all(action="DESELECT") bpy.ops.object.select_all(action="DESELECT")
return representations_ids, locations return representations_ids, locations
def edit(self): def edit(self) -> None:
if "Representations" not in SvIfcStore.id_map[self.node_id]: if "Representations" not in SvIfcStore.id_map[self.node_id]:
return return
for obj in SvIfcStore.id_map[self.node_id]["Representations"]: for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
@@ -229,7 +232,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
del SvIfcStore.id_map[self.node_id]["Locations"] del SvIfcStore.id_map[self.node_id]["Locations"]
return return
def get_context(self): def get_context(self) -> ifcopenshell.entity_instance:
context = ifcopenshell.util.representation.get_context( context = ifcopenshell.util.representation.get_context(
self.file, self.context_type, self.context_identifier, self.target_view self.file, self.context_type, self.context_identifier, self.target_view
) )
@@ -248,7 +251,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
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 return context
def sv_free(self): def sv_free(self) -> None:
try: try:
self.file = SvIfcStore.get_file() self.file = SvIfcStore.get_file()
if "Representations" in SvIfcStore.id_map[self.node_id]: if "Representations" in SvIfcStore.id_map[self.node_id]:
@@ -273,7 +276,6 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
SvIfcStore.id_map[self.node_id]["Contexts"].remove(context_id) SvIfcStore.id_map[self.node_id]["Contexts"].remove(context_id)
del SvIfcStore.id_map[self.node_id] del SvIfcStore.id_map[self.node_id]
del self.node_dict[hash(self)] del self.node_dict[hash(self)]
# print('Node was deleted')
except KeyError or AttributeError: except KeyError or AttributeError:
pass pass
+1
View File
@@ -33,6 +33,7 @@ class SvIfcByGuid(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
n_id: StringProperty(default="") n_id: StringProperty(default="")
guid: StringProperty(name="Guid(s)", update=updateNode) guid: StringProperty(name="Guid(s)", update=updateNode)
id_iter = itertools.count() id_iter = itertools.count()
guids: list[str]
def sv_init(self, context): def sv_init(self, context):
self.inputs.new("SvStringsSocket", "guid").prop_name = "guid" self.inputs.new("SvStringsSocket", "guid").prop_name = "guid"
+1 -1
View File
@@ -42,7 +42,7 @@ class SvIfcByQuery(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIf
self.sv_input_names = ["query"] self.sv_input_names = ["query"]
super().process() super().process()
def process_ifc(self, query): def process_ifc(self, query: str) -> None:
selector = ifcopenshell.util.selector.Selector() selector = ifcopenshell.util.selector.Selector()
self.outputs["Entity"].sv_set([selector.parse(self.file, query)]) self.outputs["Entity"].sv_set([selector.parse(self.file, query)])
+14 -17
View File
@@ -20,6 +20,9 @@ import bpy
from mathutils import Matrix from mathutils import Matrix
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.util.schema
import ifcsverchok.helper import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore from ifcsverchok.ifcstore import SvIfcStore
@@ -149,21 +152,20 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
self.outputs["Entities"].sv_set(entities) self.outputs["Entities"].sv_set(entities)
def create(self, index=None): def create(self, index=None) -> list[list[int]]:
entities_ids = [] entities_ids: list[list[int]] = []
iterator1 = range(len(self.names)) iterator1 = range(len(self.names))
if index is not None: if index is not None:
iterator1 = [index[0]] iterator1 = [index[0]]
for i in iterator1: for i in iterator1:
group = self.names[i] group = self.names[i]
group_entities_ids = [] group_entities_ids: list[int] = []
iterator2 = range(len(group)) iterator2 = range(len(group))
if index is not None: if index is not None:
iterator2 = [index[1]] iterator2 = [index[1]]
for j in iterator2: for j in iterator2:
try: try:
entity = ifcopenshell.api.run( entity = ifcopenshell.api.root.create_entity(
"root.create_entity",
self.file, self.file,
ifc_class=self.ifc_class, ifc_class=self.ifc_class,
name=self.names[i][j], name=self.names[i][j],
@@ -172,8 +174,7 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
try: try:
for repr in self.representations[i][j]: for repr in self.representations[i][j]:
if repr: if repr:
ifcopenshell.api.run( ifcopenshell.api.geometry.assign_representation(
"geometry.assign_representation",
self.file, self.file,
product=entity, product=entity,
representation=repr, representation=repr,
@@ -183,8 +184,7 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
try: try:
for loc in self.locations[i][j]: for loc in self.locations[i][j]:
if isinstance(loc, Matrix): if isinstance(loc, Matrix):
ifcopenshell.api.run( ifcopenshell.api.geometry.edit_object_placement(
"geometry.edit_object_placement",
self.file, self.file,
product=entity, product=entity,
matrix=loc, matrix=loc,
@@ -198,11 +198,11 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
entities_ids.append(group_entities_ids) entities_ids.append(group_entities_ids)
return entities_ids return entities_ids
def edit(self): def edit(self) -> list[list[int]]:
entities_ids = [] entities_ids: list[list[int]] = []
id_map_copy = SvIfcStore.id_map[self.node_id].copy() id_map_copy = SvIfcStore.id_map[self.node_id].copy()
for i, group in enumerate(self.names): for i, group in enumerate(self.names):
group_entities_ids = [] group_entities_ids: list[int] = []
for j, _ in enumerate(group): for j, _ in enumerate(group):
try: try:
step_id = id_map_copy[i][j] step_id = id_map_copy[i][j]
@@ -219,8 +219,7 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
if repr and repr.is_a("IfcProductDefinitionShape"): if repr and repr.is_a("IfcProductDefinitionShape"):
entity.Representation = repr entity.Representation = repr
elif repr: elif repr:
ifcopenshell.api.run( ifcopenshell.api.geometry.assign_representation(
"geometry.assign_representation",
self.file, self.file,
product=entity, product=entity,
representation=repr, representation=repr,
@@ -230,8 +229,7 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
try: try:
for loc in self.locations[i][j]: for loc in self.locations[i][j]:
if isinstance(loc, Matrix): if isinstance(loc, Matrix):
ifcopenshell.api.run( ifcopenshell.api.geometry.edit_object_placement(
"geometry.edit_object_placement",
self.file, self.file,
product=entity, product=entity,
matrix=loc, matrix=loc,
@@ -263,7 +261,6 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
try: try:
del SvIfcStore.id_map[self.node_id] del SvIfcStore.id_map[self.node_id]
del self.node_dict[hash(self)] del self.node_dict[hash(self)]
# print('Node was deleted')
except KeyError or AttributeError: except KeyError or AttributeError:
pass pass
@@ -38,7 +38,6 @@ class SvIfcCreateProject(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helpe
op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = ( op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = (
"Adds project, unit and context to IFC file" "Adds project, unit and context to IFC file"
) )
# op.tooltip = self.tooltip
def process(self): def process(self):
# file # file
@@ -19,6 +19,7 @@
import bpy import bpy
import logging import logging
import ifcopenshell import ifcopenshell
import ifcopenshell.geom
import ifcsverchok.helper import ifcsverchok.helper
from ifcsverchok.ifcstore import SvIfcStore from ifcsverchok.ifcstore import SvIfcStore
import bonsai.bim.import_ifc import bonsai.bim.import_ifc
@@ -63,7 +63,6 @@ class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = ( op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = (
"Quick Project Setup: creates Ifc file and sets up a basic project" "Quick Project Setup: creates Ifc file and sets up a basic project"
) )
# op.tooltip = self.tooltip
def process(self): def process(self):
self.sv_input_names = [i.name for i in self.inputs] self.sv_input_names = [i.name for i in self.inputs]
+1 -1
View File
@@ -38,7 +38,7 @@ class SvIfcReadFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvI
self.sv_input_names = ["path"] self.sv_input_names = ["path"]
super().process() super().process()
def process_ifc(self, path): def process_ifc(self, path: str) -> None:
guid = ifcopenshell.guid.new() guid = ifcopenshell.guid.new()
ifcsverchok.helper.ifc_files[guid] = ifcopenshell.open(path) ifcsverchok.helper.ifc_files[guid] = ifcopenshell.open(path)
self.outputs["file"].sv_set([[ifcsverchok.helper.ifc_files[guid]]]) self.outputs["file"].sv_set([[ifcsverchok.helper.ifc_files[guid]]])
+10 -1
View File
@@ -22,6 +22,7 @@ import ifcsverchok.helper
from bpy.props import StringProperty from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode from sverchok.data_structure import updateNode
from typing import Union
class SvIfcRemove(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): class SvIfcRemove(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
@@ -36,12 +37,20 @@ class SvIfcRemove(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
self.outputs.new("SvStringsSocket", "file") self.outputs.new("SvStringsSocket", "file")
def process(self): def process(self):
file: ifcopenshell.file
file = self.inputs["file"].sv_get()[0][0] file = self.inputs["file"].sv_get()[0][0]
self.new_file = ifcopenshell.file.from_string(file.wrapped_data.to_string()) self.new_file = ifcopenshell.file.from_string(file.wrapped_data.to_string())
self.remove_entity(self.inputs["entity"].sv_get()) self.remove_entity(self.inputs["entity"].sv_get())
self.outputs["file"].sv_set([[self.new_file]]) self.outputs["file"].sv_set([[self.new_file]])
def remove_entity(self, entity): def remove_entity(
self,
entity: Union[
list[list[ifcopenshell.entity_instance]],
list[ifcopenshell.entity_instance],
ifcopenshell.entity_instance,
],
) -> None:
if isinstance(entity, (tuple, list)): if isinstance(entity, (tuple, list)):
for e in entity: for e in entity:
self.remove_entity(e) self.remove_entity(e)
@@ -19,11 +19,11 @@
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.util.selector import ifcopenshell.util.selector
import bonsai.tool as tool
import ifcsverchok.helper import ifcsverchok.helper
from bpy.props import StringProperty from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode from sverchok.data_structure import updateNode
from bonsai.bim.ifc import IfcStore
class SvIfcSelectBlenderObjectsRefresh(bpy.types.Operator): class SvIfcSelectBlenderObjectsRefresh(bpy.types.Operator):
@@ -35,6 +35,7 @@ class SvIfcSelectBlenderObjectsRefresh(bpy.types.Operator):
node_name: StringProperty(default="") node_name: StringProperty(default="")
def execute(self, context): def execute(self, context):
node: SvIfcSelectBlenderObjects
node = bpy.data.node_groups[self.tree_name].nodes[self.node_name] node = bpy.data.node_groups[self.tree_name].nodes[self.node_name]
node.process() node.process()
return {"FINISHED"} return {"FINISHED"}
@@ -43,7 +44,9 @@ class SvIfcSelectBlenderObjectsRefresh(bpy.types.Operator):
class SvIfcSelectBlenderObjects(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore): class SvIfcSelectBlenderObjects(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcSelectBlenderObjects" bl_idname = "SvIfcSelectBlenderObjects"
bl_label = "IFC Select Blender Objects" bl_label = "IFC Select Blender Objects"
bl_description = "Select Blender objects based on IFC entities."
file: StringProperty(name="file", update=updateNode) file: StringProperty(name="file", update=updateNode)
# TODO: never used.
query: StringProperty(name="query", update=updateNode) query: StringProperty(name="query", update=updateNode)
def sv_init(self, context): def sv_init(self, context):
@@ -54,18 +57,18 @@ class SvIfcSelectBlenderObjects(bpy.types.Node, SverchCustomTreeNode, ifcsvercho
layout, "node.sv_ifc_select_blender_objects_refresh", icon="FILE_REFRESH", text="Refresh" layout, "node.sv_ifc_select_blender_objects_refresh", icon="FILE_REFRESH", text="Refresh"
) )
def process(self): def process(self) -> None:
self.file = IfcStore.get_file()
self.sv_input_names = ["entities"] self.sv_input_names = ["entities"]
self.guids = [] self.guids: list[str] = []
super().process() super().process()
for obj in bpy.context.visible_objects: for obj in bpy.context.visible_objects:
if not obj.BIMObjectProperties.ifc_definition_id: element = tool.Ifc.get_entity(obj)
if not element:
continue continue
if self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId in self.guids: if getattr(element, "GlobalId", None) in self.guids:
obj.select_set(True) obj.select_set(True)
def process_ifc(self, entities): def process_ifc(self, entities: ifcopenshell.entity_instance) -> None:
self.guids.append(entities.GlobalId) self.guids.append(entities.GlobalId)
+9 -16
View File
@@ -16,15 +16,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>. # along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>.
from copy import deepcopy
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcsverchok.helper import ifcsverchok.helper
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.context
import ifcopenshell.api.geometry
import ifcopenshell.util.representation import ifcopenshell.util.representation
from ifcsverchok.ifcstore import SvIfcStore from ifcsverchok.ifcstore import SvIfcStore
import bonsai.tool as tool
import bonsai.core.geometry as core
from bpy.props import StringProperty, EnumProperty, IntProperty, FloatVectorProperty from bpy.props import StringProperty, EnumProperty, IntProperty, FloatVectorProperty
from sverchok.node_tree import SverchCustomTreeNode from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, ensure_min_nesting from sverchok.data_structure import updateNode, ensure_min_nesting
@@ -142,8 +141,7 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
for obj in geo_data: for obj in geo_data:
representations_ids_obj = [] representations_ids_obj = []
for item in obj: for item in obj:
representation = ifcopenshell.api.run( representation = ifcopenshell.api.geometry.add_mesh_representation(
"geometry.add_mesh_representation",
self.file, self.file,
should_run_listeners=False, should_run_listeners=False,
context=self.context, context=self.context,
@@ -165,8 +163,7 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
return return
for obj in SvIfcStore.id_map[self.node_id]["Representations"]: for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
for step_id in obj: for step_id in obj:
ifcopenshell.api.run( ifcopenshell.api.geometry.remove_representation(
"geometry.remove_representation",
self.file, self.file,
representation=self.file.by_id(step_id[0]), representation=self.file.by_id(step_id[0]),
) )
@@ -180,9 +177,8 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
if not context: 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: if not parent:
parent = ifcopenshell.api.run("context.add_context", self.file, context_type=self.context_type) parent = ifcopenshell.api.context.add_context(self.file, context_type=self.context_type)
context = ifcopenshell.api.run( context = ifcopenshell.api.context.add_context(
"context.add_context",
self.file, self.file,
context_type=self.context_type, context_type=self.context_type,
context_identifier=self.context_identifier, context_identifier=self.context_identifier,
@@ -197,8 +193,7 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
self.file = SvIfcStore.get_file() self.file = SvIfcStore.get_file()
if "Representations" in SvIfcStore.id_map[self.node_id]: if "Representations" in SvIfcStore.id_map[self.node_id]:
for step_id in SvIfcStore.id_map[self.node_id]["Representations"]: for step_id in SvIfcStore.id_map[self.node_id]["Representations"]:
ifcopenshell.api.run( ifcopenshell.api.geometry.remove_representation(
"geometry.remove_representation",
self.file, self.file,
representation=self.file.by_id(step_id[0]), representation=self.file.by_id(step_id[0]),
) )
@@ -209,15 +204,13 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
if not self.file.get_inverse(context): if not self.file.get_inverse(context):
if self.file.by_id(context_id).ParentContext: if self.file.by_id(context_id).ParentContext:
parent = 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.context.remove_context(self.file, context=context)
if parent: if parent:
if not self.file.get_inverse(parent): if not self.file.get_inverse(parent):
ifcopenshell.api.run("context.remove_context", self.file, context=parent) ifcopenshell.api.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) SvIfcStore.id_map[self.node_id]["Contexts"].remove(context_id)
del SvIfcStore.id_map[self.node_id] del SvIfcStore.id_map[self.node_id]
del self.node_dict[hash(self)] del self.node_dict[hash(self)]
# print('Node was deleted')
except KeyError or AttributeError: except KeyError or AttributeError:
pass pass
+2 -1
View File
@@ -77,7 +77,8 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv
file.write(path) file.write(path)
self.outputs["output"].sv_set(f"File written successfully to: {path}.") self.outputs["output"].sv_set(f"File written successfully to: {path}.")
def ensure_hirarchy(self, file): def ensure_hirarchy(self, file: ifcopenshell.file) -> None:
# TODO: same code as ifc.write_file_panel?
elements_in_buildings = [] elements_in_buildings = []
if not 0 <= 0 < len(file.by_type("IfcBuilding")): if not 0 <= 0 < len(file.by_type("IfcBuilding")):
my_building = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcBuilding", name="My Building") my_building = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcBuilding", name="My Building")