mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
Important rework of handling multiple/nested items in bmesh_to_ifc, create_entity and sverchok_to_ifc nodes. Formatting and other minor fixes.
This commit is contained in:
+39
-35
@@ -1,5 +1,5 @@
|
|||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -28,21 +28,18 @@ bl_info = {
|
|||||||
"warning": "",
|
"warning": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
import sys
|
|
||||||
import importlib
|
import importlib
|
||||||
import nodeitems_utils
|
import nodeitems_utils
|
||||||
import sverchok
|
from sverchok.core import make_node_list
|
||||||
from sverchok.core import sv_registration_utils, make_node_list
|
|
||||||
from sverchok.utils import auto_gather_node_classes, get_node_class_reference
|
from sverchok.utils import auto_gather_node_classes, get_node_class_reference
|
||||||
from sverchok.menu import SverchNodeItem, SverchNodeCategory, register_node_panels
|
from sverchok.menu import SverchNodeItem, SverchNodeCategory
|
||||||
from sverchok.utils.extra_categories import (
|
from sverchok.utils.extra_categories import (
|
||||||
register_extra_category_provider,
|
register_extra_category_provider,
|
||||||
unregister_extra_category_provider,
|
unregister_extra_category_provider,
|
||||||
)
|
)
|
||||||
from sverchok.ui.nodeview_space_menu import make_extra_category_menus
|
from sverchok.ui.nodeview_space_menu import make_extra_category_menus
|
||||||
from sverchok.utils.logging import info, debug
|
from sverchok.utils.logging import info, debug
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
|
|
||||||
def nodes_index():
|
def nodes_index():
|
||||||
return [
|
return [
|
||||||
@@ -73,8 +70,7 @@ def nodes_index():
|
|||||||
("ifc.bmesh_to_ifc", "SvIfcBMeshToIfcRepr"),
|
("ifc.bmesh_to_ifc", "SvIfcBMeshToIfcRepr"),
|
||||||
("ifc.sverchok_to_ifc", "SvIfcSverchokToIfcRepr"),
|
("ifc.sverchok_to_ifc", "SvIfcSverchokToIfcRepr"),
|
||||||
("ifc.create_project", "SvIfcCreateProject"),
|
("ifc.create_project", "SvIfcCreateProject"),
|
||||||
("ifc.quick_project_setup", "SvIfcQuickProjectSetup")
|
("ifc.quick_project_setup", "SvIfcQuickProjectSetup"),
|
||||||
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@@ -96,26 +92,23 @@ imported_modules = make_node_list()
|
|||||||
reload_event = False
|
reload_event = False
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
from os.path import splitext
|
||||||
from os.path import abspath, splitext
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
from ifcsverchok.ifcstore import SvIfcStore
|
from ifcsverchok.ifcstore import SvIfcStore
|
||||||
from sverchok.data_structure import flatten_data
|
|
||||||
|
|
||||||
class IFC_Sv_UpdateCurrent(bpy.types.Operator):
|
class IFC_Sv_UpdateCurrent(bpy.types.Operator):
|
||||||
"""Update current Sverchok node tree"""
|
"""Update current Sverchok node tree"""
|
||||||
|
|
||||||
bl_idname = "ifc.sverchok_update_current"
|
bl_idname = "ifc.sverchok_update_current"
|
||||||
bl_label = "Update current node tree"
|
bl_label = "Update current node tree"
|
||||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
|
||||||
|
|
||||||
node_group: bpy.props.StringProperty(default="")
|
node_group: bpy.props.StringProperty(default="")
|
||||||
force_mode: bpy.props.BoolProperty(default=False)
|
force_mode: bpy.props.BoolProperty(default=False)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
print("#"*10, "Update current node tree")
|
|
||||||
self.file = SvIfcStore.purge()
|
self.file = SvIfcStore.purge()
|
||||||
self.file = SvIfcStore.get_file()
|
|
||||||
self.file.write("/Users/martina/Documents/GSoC/CodeTests/IfcFileTest_7_11_purged.ifc")
|
|
||||||
node_tree = context.space_data.node_tree
|
node_tree = context.space_data.node_tree
|
||||||
if node_tree:
|
if node_tree:
|
||||||
if self.force_mode or node_tree.sv_process:
|
if self.force_mode or node_tree.sv_process:
|
||||||
@@ -125,7 +118,8 @@ class IFC_Sv_UpdateCurrent(bpy.types.Operator):
|
|||||||
finally:
|
finally:
|
||||||
bpy.context.window.cursor_set("DEFAULT")
|
bpy.context.window.cursor_set("DEFAULT")
|
||||||
self.report({"INFO"}, "Node tree updated.")
|
self.report({"INFO"}, "Node tree updated.")
|
||||||
return {'FINISHED'}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class IFC_Sv_write_file(bpy.types.Operator):
|
class IFC_Sv_write_file(bpy.types.Operator):
|
||||||
bl_idname = "ifc.write_file_panel"
|
bl_idname = "ifc.write_file_panel"
|
||||||
@@ -141,43 +135,52 @@ class IFC_Sv_write_file(bpy.types.Operator):
|
|||||||
return any("IFC" in n for n in context.space_data.edit_tree.nodes.keys())
|
return any("IFC" in n for n in context.space_data.edit_tree.nodes.keys())
|
||||||
|
|
||||||
def ensure_hirarchy(self, file):
|
def ensure_hirarchy(self, file):
|
||||||
elements_in_buildings = []
|
elements_in_buildings = set()
|
||||||
if not 0 <= 0 < len(file.by_type("IfcBuilding")):
|
if len(file.by_type("IfcBuilding")) == 0:
|
||||||
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")
|
||||||
elements = ifcopenshell.util.element.get_decomposition(my_building)
|
elements = ifcopenshell.util.element.get_decomposition(my_building)
|
||||||
else:
|
else:
|
||||||
for building in file.by_type("IfcBuilding"):
|
for building in file.by_type("IfcBuilding"):
|
||||||
elements = ifcopenshell.util.element.get_decomposition(building)
|
elements = ifcopenshell.util.element.get_decomposition(building)
|
||||||
elements_in_buildings.extend(elements)
|
elements_in_buildings.update(elements)
|
||||||
|
|
||||||
for spatial in (file.by_type("IfcSpatialElement") or file.by_type("IfcSpatialStructureElement")):
|
for spatial in file.by_type("IfcSpatialElement") or file.by_type("IfcSpatialStructureElement"):
|
||||||
if (not (spatial.is_a("IfcSite") or spatial.is_a("IfcBuilding")) and (spatial not in elements_in_buildings)):
|
if not (spatial.is_a("IfcSite") or spatial.is_a("IfcBuilding")) and (spatial not in elements_in_buildings):
|
||||||
elements = ifcopenshell.util.element.get_decomposition(spatial)
|
elements = ifcopenshell.util.element.get_decomposition(spatial)
|
||||||
ifcopenshell.api.run("aggregate.assign_object", file, product=spatial, relating_object=file.by_type("IfcBuilding")[0])
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object", file, product=spatial, relating_object=file.by_type("IfcBuilding")[0]
|
||||||
|
)
|
||||||
|
|
||||||
elements_in_buildings_after = []
|
|
||||||
for building in file.by_type("IfcBuilding"):
|
for building in file.by_type("IfcBuilding"):
|
||||||
elements = ifcopenshell.util.element.get_decomposition(building)
|
elements = ifcopenshell.util.element.get_decomposition(building)
|
||||||
elements_in_buildings_after.extend(elements)
|
elements_in_buildings.update(elements)
|
||||||
|
|
||||||
elements = file.by_type("IfcElement")
|
elements = file.by_type("IfcElement")
|
||||||
for element in elements:
|
for element in elements:
|
||||||
if element not in elements_in_buildings:
|
if element not in elements_in_buildings:
|
||||||
ifcopenshell.api.run("spatial.assign_container", file, product=element, relating_structure=file.by_type("IfcBuilding")[0])
|
ifcopenshell.api.run(
|
||||||
|
"spatial.assign_container", file, product=element, relating_structure=file.by_type("IfcBuilding")[0]
|
||||||
|
)
|
||||||
|
|
||||||
for building in file.by_type("IfcBuilding"):
|
for building in file.by_type("IfcBuilding"):
|
||||||
elements = ifcopenshell.util.element.get_decomposition(building)
|
elements = ifcopenshell.util.element.get_decomposition(building)
|
||||||
if not building.Decomposes:
|
if not building.Decomposes:
|
||||||
if not 0 <= 0 < len(file.by_type("IfcSite")):
|
if len(file.by_type("IfcSite")) == 0:
|
||||||
ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site")
|
ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site")
|
||||||
ifcopenshell.api.run("aggregate.assign_object", file, product=building, relating_object=file.by_type("IfcSite")[0])
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object", file, product=building, relating_object=file.by_type("IfcSite")[0]
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
if file.by_type("IfcSite")[0].Decomposes[0].RelatingObject.is_a("IfcProject"):
|
if file.by_type("IfcSite")[0].Decomposes[0].RelatingObject.is_a("IfcProject"):
|
||||||
continue
|
continue
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
ifcopenshell.api.run("aggregate.assign_object", file, product=file.by_type("IfcSite")[0], relating_object=file.by_type("IfcProject")[0])
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object",
|
||||||
|
file,
|
||||||
|
product=file.by_type("IfcSite")[0],
|
||||||
|
relating_object=file.by_type("IfcProject")[0],
|
||||||
|
)
|
||||||
self.file = file
|
self.file = file
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -198,6 +201,7 @@ class IFC_Sv_write_file(bpy.types.Operator):
|
|||||||
context.window_manager.fileselect_add(self)
|
context.window_manager.fileselect_add(self)
|
||||||
return {"RUNNING_MODAL"}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
|
||||||
class IFC_PT_write_file_panel(bpy.types.Panel):
|
class IFC_PT_write_file_panel(bpy.types.Panel):
|
||||||
bl_idname = "IFC_PT_write_file_panel"
|
bl_idname = "IFC_PT_write_file_panel"
|
||||||
bl_label = "Write IFC to file"
|
bl_label = "Write IFC to file"
|
||||||
@@ -217,10 +221,12 @@ class IFC_PT_write_file_panel(bpy.types.Panel):
|
|||||||
row = layout.split(factor=0.2, align=True)
|
row = layout.split(factor=0.2, align=True)
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row2 = layout.row()
|
row2 = layout.row()
|
||||||
row.operator('ifc.sverchok_update_current', text='IFC Re-run all nodes')
|
row.operator("ifc.sverchok_update_current", text="IFC Re-run all nodes")
|
||||||
row2.operator("ifc.write_file_panel")
|
row2.operator("ifc.write_file_panel")
|
||||||
|
|
||||||
CLASSES = [IFC_Sv_UpdateCurrent,IFC_Sv_write_file, IFC_PT_write_file_panel]
|
|
||||||
|
CLASSES = [IFC_Sv_UpdateCurrent, IFC_Sv_write_file, IFC_PT_write_file_panel]
|
||||||
|
|
||||||
|
|
||||||
def register_nodes():
|
def register_nodes():
|
||||||
node_modules = make_node_list()
|
node_modules = make_node_list()
|
||||||
@@ -281,9 +287,7 @@ def register():
|
|||||||
auto_gather_node_classes(extra_nodes)
|
auto_gather_node_classes(extra_nodes)
|
||||||
menu = make_menu()
|
menu = make_menu()
|
||||||
menu_category_provider = SvExCategoryProvider("IFCSVERCHOK", menu)
|
menu_category_provider = SvExCategoryProvider("IFCSVERCHOK", menu)
|
||||||
register_extra_category_provider(
|
register_extra_category_provider(menu_category_provider) # if 'IFCSVERCHOK' in nodeitems_utils._node_categories:
|
||||||
menu_category_provider
|
|
||||||
) # if 'IFCSVERCHOK' in nodeitems_utils._node_categories:
|
|
||||||
nodeitems_utils.register_node_categories("IFCSVERCHOK", menu)
|
nodeitems_utils.register_node_categories("IFCSVERCHOK", menu)
|
||||||
our_menu_classes = make_extra_category_menus()
|
our_menu_classes = make_extra_category_menus()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
+22
-25
@@ -1,13 +1,25 @@
|
|||||||
# import os
|
# IfcSverchok - IFC Sverchok extension
|
||||||
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
|
#
|
||||||
|
# This file is part of IfcSverchok.
|
||||||
|
#
|
||||||
|
# IfcSverchok is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# IfcSverchok is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
# import uuid
|
|
||||||
# import hashlib
|
|
||||||
# import zipfile
|
|
||||||
# import tempfile
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
from ifcopenshell import template
|
from ifcopenshell import template
|
||||||
# import blenderbim.bim.handler
|
|
||||||
# from pathlib import Path
|
|
||||||
|
|
||||||
class SvIfcStore:
|
class SvIfcStore:
|
||||||
path = ""
|
path = ""
|
||||||
@@ -52,7 +64,6 @@ class SvIfcStore:
|
|||||||
SvIfcStore.future = []
|
SvIfcStore.future = []
|
||||||
SvIfcStore.schema_identifiers = ["IFC4", "IFC2X3"]
|
SvIfcStore.schema_identifiers = ["IFC4", "IFC2X3"]
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_boilerplate():
|
def create_boilerplate():
|
||||||
|
|
||||||
@@ -61,11 +72,10 @@ class SvIfcStore:
|
|||||||
organization=None,
|
organization=None,
|
||||||
creator=None,
|
creator=None,
|
||||||
project_name="IfcSverchokDemoProject",
|
project_name="IfcSverchokDemoProject",
|
||||||
)
|
)
|
||||||
if bpy.context.scene.unit_settings.system == 'IMPERIAL':
|
if bpy.context.scene.unit_settings.system == "IMPERIAL":
|
||||||
#TODO change units to imperial
|
# TODO change units to imperial
|
||||||
pass
|
pass
|
||||||
# model = ifcopenshell.api.run("context.add_context", file, context_type="Model")
|
|
||||||
model = ifcopenshell.util.representation.get_context(file, context="Model")
|
model = ifcopenshell.util.representation.get_context(file, context="Model")
|
||||||
print("model: ", model)
|
print("model: ", model)
|
||||||
context = ifcopenshell.api.run(
|
context = ifcopenshell.api.run(
|
||||||
@@ -76,22 +86,9 @@ class SvIfcStore:
|
|||||||
target_view="MODEL_VIEW",
|
target_view="MODEL_VIEW",
|
||||||
parent=model,
|
parent=model,
|
||||||
)
|
)
|
||||||
# site = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site")
|
|
||||||
# building = ifcopenshell.api.run(
|
|
||||||
# "root.create_entity", file, ifc_class="IfcBuilding", name="My Building"
|
|
||||||
# )
|
|
||||||
# building_storey = ifcopenshell.api.run(
|
|
||||||
# "root.create_entity", file, ifc_class="IfcBuildingStorey", name="My Storey"
|
|
||||||
# )
|
|
||||||
|
|
||||||
# ifcopenshell.api.run("aggregate.assign_object", file, product=site, relating_object=file.by_type("IfcProject")[0])
|
|
||||||
# ifcopenshell.api.run("aggregate.assign_object", file, product=building, relating_object=site)
|
|
||||||
# ifcopenshell.api.run("aggregate.assign_object", file, product=building_storey, relating_object=building)
|
|
||||||
|
|
||||||
SvIfcStore.file = file
|
SvIfcStore.file = file
|
||||||
return SvIfcStore.file
|
return SvIfcStore.file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_file():
|
def get_file():
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -16,4 +15,3 @@
|
|||||||
#
|
#
|
||||||
# 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/>.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -16,4 +15,3 @@
|
|||||||
#
|
#
|
||||||
# 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/>.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
# IfcSverchok - IFC Sverchok extension
|
||||||
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
|
#
|
||||||
|
# This file is part of IfcSverchok.
|
||||||
|
#
|
||||||
|
# IfcSverchok is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# IfcSverchok is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
# IfcSverchok - IFC Sverchok extension
|
||||||
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
|
#
|
||||||
|
# This file is part of IfcSverchok.
|
||||||
|
#
|
||||||
|
# IfcSverchok is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# IfcSverchok is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
@@ -13,7 +31,7 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
bl_idname = "SvIfcAddSpatialElement"
|
bl_idname = "SvIfcAddSpatialElement"
|
||||||
bl_label = "IFC Add Spatial Element"
|
bl_label = "IFC Add Spatial Element"
|
||||||
node_dict = {}
|
node_dict = {}
|
||||||
|
|
||||||
Names: StringProperty(name="Name(s)", update=updateNode)
|
Names: StringProperty(name="Name(s)", update=updateNode)
|
||||||
IfcClass: StringProperty(name="IFC Class", update=updateNode, default="IfcSpace")
|
IfcClass: StringProperty(name="IFC Class", update=updateNode, default="IfcSpace")
|
||||||
Elements: StringProperty(name="Elements", update=updateNode)
|
Elements: StringProperty(name="Elements", update=updateNode)
|
||||||
@@ -24,14 +42,14 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
self.inputs.new("SvStringsSocket", "Elements").prop_name = "Elements"
|
self.inputs.new("SvStringsSocket", "Elements").prop_name = "Elements"
|
||||||
self.outputs.new("SvStringsSocket", "Entities")
|
self.outputs.new("SvStringsSocket", "Entities")
|
||||||
self.node_dict[hash(self)] = {}
|
self.node_dict[hash(self)] = {}
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
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 = "Ifc entity by type."
|
||||||
|
|
||||||
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]
|
||||||
if hash(self) not in self.node_dict:
|
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)]:
|
if not self.node_dict[hash(self)]:
|
||||||
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
||||||
|
|
||||||
@@ -40,8 +58,11 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
edit = False
|
edit = False
|
||||||
edit_elements = False
|
edit_elements = False
|
||||||
for i in range(len(self.inputs)):
|
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]:
|
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
|
edit = True
|
||||||
if self.inputs[i].name == "Elements":
|
if self.inputs[i].name == "Elements":
|
||||||
edit_elements = True
|
edit_elements = True
|
||||||
@@ -83,7 +104,9 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
if items.is_a("IfcSpatialElement") or items.is_a("IfcSpatialStructureElement"):
|
if items.is_a("IfcSpatialElement") or items.is_a("IfcSpatialStructureElement"):
|
||||||
ifcopenshell.api.run("aggregate.assign_object", self.file, product=items, relating_object=result)
|
ifcopenshell.api.run("aggregate.assign_object", self.file, product=items, relating_object=result)
|
||||||
else:
|
else:
|
||||||
ifcopenshell.api.run("spatial.assign_container", self.file, product=items, relating_structure=result)
|
ifcopenshell.api.run(
|
||||||
|
"spatial.assign_container", self.file, product=items, relating_structure=result
|
||||||
|
)
|
||||||
SvIfcStore.id_map.setdefault(self.node_id, []).append(result.id())
|
SvIfcStore.id_map.setdefault(self.node_id, []).append(result.id())
|
||||||
spatial_ids.append(result.id())
|
spatial_ids.append(result.id())
|
||||||
return spatial_ids
|
return spatial_ids
|
||||||
@@ -106,15 +129,25 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
for element in self.elements[i]:
|
for element in self.elements[i]:
|
||||||
element_set = set([element])
|
element_set = set([element])
|
||||||
for removed_element in subelements - element_set:
|
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(
|
||||||
ifcopenshell.api.run("aggregate.unassign_object", self.file, product=removed_element, relating_object=result)
|
"IfcSpatialStructureElement"
|
||||||
|
):
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.unassign_object", self.file, product=removed_element, relating_object=result
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
ifcopenshell.api.run("spatial.unassign_container", self.file, product=removed_element, relating_object=result)
|
ifcopenshell.api.run(
|
||||||
|
"spatial.unassign_container", self.file, product=removed_element, relating_object=result
|
||||||
|
)
|
||||||
for added_element in element_set - subelements:
|
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)
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object", self.file, product=added_element, relating_object=result
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
ifcopenshell.api.run("spatial.assign_container", self.file, product=added_element, relating_structure=result)
|
ifcopenshell.api.run(
|
||||||
|
"spatial.assign_container", self.file, product=added_element, relating_structure=result
|
||||||
|
)
|
||||||
spatial_ids.append(result.id())
|
spatial_ids.append(result.id())
|
||||||
SvIfcStore.id_map[self.node_id] = spatial_ids
|
SvIfcStore.id_map[self.node_id] = spatial_ids
|
||||||
return spatial_ids
|
return spatial_ids
|
||||||
@@ -129,17 +162,20 @@ class SvIfcAddSpatialElement(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
def repeat_input_unique(self, input, count):
|
def repeat_input_unique(self, input, count):
|
||||||
input = repeat_last_for_length(input, count, deepcopy=False)
|
input = repeat_last_for_length(input, count, deepcopy=False)
|
||||||
if input[0]:
|
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
|
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 input
|
||||||
|
|
||||||
def sv_free(self):
|
def sv_free(self):
|
||||||
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')
|
# print('Node was deleted')
|
||||||
except KeyError or AttributeError:
|
except KeyError or AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(SvIfcAddSpatialElement)
|
bpy.utils.register_class(SvIfcAddSpatialElement)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -105,4 +104,4 @@ def register():
|
|||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
bpy.utils.unregister_class(SvIfcApi)
|
bpy.utils.unregister_class(SvIfcApi)
|
||||||
bpy.utils.unregister_class(SvIfcTooltip)
|
bpy.utils.unregister_class(SvIfcTooltip)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -21,13 +20,12 @@ import bpy
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
import ifcsverchok.helper
|
import ifcsverchok.helper
|
||||||
from bpy.props import StringProperty, EnumProperty
|
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
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SvIfcTooltip(bpy.types.Operator):
|
class SvIfcTooltip(bpy.types.Operator):
|
||||||
bl_idname = "node.sv_ifc_tooltip"
|
bl_idname = "node.sv_ifc_tooltip"
|
||||||
bl_label = "IFC Info"
|
bl_label = "IFC Info"
|
||||||
@@ -43,12 +41,6 @@ class SvIfcTooltip(bpy.types.Operator):
|
|||||||
|
|
||||||
class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
|
|
||||||
# def update_usecase(self, context):
|
|
||||||
# # update_usecase is not getting run rn
|
|
||||||
# module_usecase = self.get_module_usecase()
|
|
||||||
# if module_usecase:
|
|
||||||
# self.generate_node(*module_usecase)
|
|
||||||
|
|
||||||
bl_idname = "SvIfcApiWIP"
|
bl_idname = "SvIfcApiWIP"
|
||||||
bl_label = "IFC API WIP"
|
bl_label = "IFC API WIP"
|
||||||
tooltip: StringProperty(name="Tooltip")
|
tooltip: StringProperty(name="Tooltip")
|
||||||
@@ -57,11 +49,13 @@ class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "usecase").prop_name = "usecase"
|
self.inputs.new("SvStringsSocket", "usecase").prop_name = "usecase"
|
||||||
#input_socket.tooltip = "ifcopenshell.api usecase, written like 'module.usecase' \n E.g.: 'project.create_file'"
|
# input_socket.tooltip = "ifcopenshell.api usecase, written like 'module.usecase' \n E.g.: 'project.create_file'"
|
||||||
self.outputs.new("SvVerticesSocket", "file")
|
self.outputs.new("SvVerticesSocket", "file")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "ifcopenshell.api usecase, written like 'module.usecase' \n E.g.: 'project.create_file"
|
op = layout.operator(
|
||||||
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
|
).tooltip = "ifcopenshell.api usecase, written like 'module.usecase' \n E.g.: 'project.create_file"
|
||||||
# op.tooltip = self.tooltip
|
# op.tooltip = self.tooltip
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
@@ -71,11 +65,9 @@ class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
try:
|
try:
|
||||||
module_usecase = self.get_module_usecase()
|
module_usecase = self.get_module_usecase()
|
||||||
except:
|
except:
|
||||||
raise Exception(
|
raise Exception(f"Couldn't run generate_node(). Module usecase: {module_usecase}")
|
||||||
f"Couldn't run generate_node(). Module usecase: {module_usecase}"
|
if ".".join(module_usecase) != self.current_usecase:
|
||||||
)
|
self.generate_node(*module_usecase)
|
||||||
if '.'.join(module_usecase) != self.current_usecase:
|
|
||||||
self.generate_node(*module_usecase)
|
|
||||||
try:
|
try:
|
||||||
for i in range(0, len(self.inputs)):
|
for i in range(0, len(self.inputs)):
|
||||||
input = self.inputs[i].sv_get()
|
input = self.inputs[i].sv_get()
|
||||||
@@ -85,8 +77,7 @@ class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
|
|
||||||
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() uses zip_long_repeat() which doesn't take objects like bmesh
|
super().process() # super().process() uses zip_long_repeat() which doesn't take objects like bmesh
|
||||||
|
|
||||||
|
|
||||||
def get_module_usecase(self):
|
def get_module_usecase(self):
|
||||||
usecase = self.inputs["usecase"].sv_get()[0][0]
|
usecase = self.inputs["usecase"].sv_get()[0][0]
|
||||||
@@ -102,10 +93,10 @@ class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
node_inputs["file"] = None
|
node_inputs["file"] = None
|
||||||
node_inputs.update(getattr(local_module.Usecase(local_module), "settings", {}))
|
node_inputs.update(getattr(local_module.Usecase(local_module), "settings", {}))
|
||||||
# print("node inputs: ", node_inputs)
|
# print("node inputs: ", node_inputs)
|
||||||
|
|
||||||
while len(self.inputs) > 1:
|
while len(self.inputs) > 1:
|
||||||
self.inputs.remove(self.inputs[-1])
|
self.inputs.remove(self.inputs[-1])
|
||||||
|
|
||||||
if node_inputs:
|
if node_inputs:
|
||||||
self.tooltip = ""
|
self.tooltip = ""
|
||||||
for name, data in node_inputs.items():
|
for name, data in node_inputs.items():
|
||||||
@@ -116,11 +107,10 @@ class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
else:
|
else:
|
||||||
self.tooltip = f"{name}: None\n"
|
self.tooltip = f"{name}: None\n"
|
||||||
self.tooltip = self.tooltip.strip()
|
self.tooltip = self.tooltip.strip()
|
||||||
self.current_usecase = '.'.join([module, usecase])
|
self.current_usecase = ".".join([module, usecase])
|
||||||
|
|
||||||
|
|
||||||
def process_ifc(self, usecase, *setting_values):
|
def process_ifc(self, usecase, *setting_values):
|
||||||
|
|
||||||
if usecase and setting_values:
|
if usecase and setting_values:
|
||||||
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 != ""}
|
||||||
@@ -133,8 +123,6 @@ class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
self.outputs["file"].sv_set([ifcopenshell.api.run(usecase, **settings)])
|
self.outputs["file"].sv_set([ifcopenshell.api.run(usecase, **settings)])
|
||||||
except:
|
except:
|
||||||
raise Exception(f"Couldn't run usecase.")
|
raise Exception(f"Couldn't run usecase.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
@@ -144,4 +132,4 @@ def register():
|
|||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
bpy.utils.unregister_class(SvIfcApiWIP)
|
bpy.utils.unregister_class(SvIfcApiWIP)
|
||||||
bpy.utils.unregister_class(SvIfcTooltip)
|
bpy.utils.unregister_class(SvIfcTooltip)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -28,18 +28,20 @@ import blenderbim.tool as tool
|
|||||||
import blenderbim.core.geometry as core
|
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.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import (updateNode, flatten_data, fixed_iter, flat_iter)
|
from sverchok.data_structure import updateNode, flatten_data, fixed_iter, flat_iter
|
||||||
from blenderbim.bim.module.root.prop import get_contexts
|
from blenderbim.bim.module.root.prop import get_contexts
|
||||||
from sverchok.data_structure import zip_long_repeat, node_id
|
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
|
||||||
|
|
||||||
|
|
||||||
class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
"""
|
"""
|
||||||
Triggers: BMesh to Ifc Repr
|
Triggers: BMesh to Ifc Repr
|
||||||
Tooltip: Blender mesh to Ifc Shape Representation
|
Tooltip: Blender mesh to Ifc Shape Representation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bl_idname = "SvIfcBMeshToIfcRepr"
|
bl_idname = "SvIfcBMeshToIfcRepr"
|
||||||
bl_label = "IFC Blender Mesh to IFC Repr"
|
bl_label = "IFC Blender Mesh to IFC Repr"
|
||||||
node_dict = {}
|
node_dict = {}
|
||||||
@@ -54,61 +56,81 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
|
|||||||
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 = [
|
context_types = [
|
||||||
('Model', 'Model', 'Context type: Model', 0),
|
("Model", "Model", "Context type: Model", 0),
|
||||||
('Plan', 'Plan', 'Context type: Plan', 1),
|
("Plan", "Plan", "Context type: Plan", 1),
|
||||||
]
|
]
|
||||||
|
|
||||||
context_identifiers = [
|
context_identifiers = [
|
||||||
('Body', 'Body', 'Context identifier: Body', 0),
|
("Body", "Body", "Context identifier: Body", 0),
|
||||||
('Annotation', 'Annotation', 'Context identifier: Annotation', 1),
|
("Annotation", "Annotation", "Context identifier: Annotation", 1),
|
||||||
('Box', 'Box', 'Context identifier: Box', 2),
|
("Box", "Box", "Context identifier: Box", 2),
|
||||||
('Axis', 'Axis', 'Context identifier: Axis', 3),
|
("Axis", "Axis", "Context identifier: Axis", 3),
|
||||||
]
|
]
|
||||||
target_views = [
|
target_views = [
|
||||||
('MODEL_VIEW', 'MODEL_VIEW', 'Target View: MODEL_VIEW', 0),
|
("MODEL_VIEW", "MODEL_VIEW", "Target View: MODEL_VIEW", 0),
|
||||||
('PLAN_VIEW', 'PLAN_VIEW', 'Target View: PLAN_VIEW', 1),
|
("PLAN_VIEW", "PLAN_VIEW", "Target View: PLAN_VIEW", 1),
|
||||||
('GRAPH_VIEW', 'GRAPH_VIEW', 'Target View: GRAPH_VIEW', 2),
|
("GRAPH_VIEW", "GRAPH_VIEW", "Target View: GRAPH_VIEW", 2),
|
||||||
('SKETCH_VIEW', 'SKETCH_VIEW', 'Target View: SKETCH_VIEW', 3),
|
("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)
|
blender_objects: PointerProperty(
|
||||||
context_type: EnumProperty(name="Context Type", description="Default: Model", default="Model",items=context_types,update=updateNode)
|
name="Blender Mesh(es)", description="Blender Mesh Object(s)", update=updateNode, type=bpy.types.Object
|
||||||
context_identifier: EnumProperty(name="Context Identifier", description="Default: Body", default="Body", items=context_identifiers, update=updateNode)
|
)
|
||||||
target_view: EnumProperty(name="Target View", description="Default: MODEL VIEW", default="MODEL_VIEW",items=target_views, update=updateNode)
|
context_type: EnumProperty(
|
||||||
|
name="Context Type", description="Default: Model", default="Model", items=context_types, update=updateNode
|
||||||
|
)
|
||||||
|
context_identifier: EnumProperty(
|
||||||
|
name="Context Identifier",
|
||||||
|
description="Default: Body",
|
||||||
|
default="Body",
|
||||||
|
items=context_identifiers,
|
||||||
|
update=updateNode,
|
||||||
|
)
|
||||||
|
target_view: EnumProperty(
|
||||||
|
name="Target View",
|
||||||
|
description="Default: MODEL VIEW",
|
||||||
|
default="MODEL_VIEW",
|
||||||
|
items=target_views,
|
||||||
|
update=updateNode,
|
||||||
|
)
|
||||||
tooltip: StringProperty(name="Tooltip")
|
tooltip: StringProperty(name="Tooltip")
|
||||||
|
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "context_type").prop_name = "context_type"
|
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("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("SvVerticesSocket", "Representations")
|
||||||
self.outputs.new("SvMatrixSocket", "Locations")
|
self.outputs.new("SvMatrixSocket", "Locations")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
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."
|
layout.operator(
|
||||||
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
|
).tooltip = "Blender mesh to Ifc Shape Representation. \nTakes one or multiple geometries."
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(self, 'is_interactive', icon='SCENE_DATA', icon_only=True)
|
row.prop(self, "is_interactive", icon="SCENE_DATA", icon_only=True)
|
||||||
row.prop(self, 'refresh_local', icon='FILE_REFRESH')
|
row.prop(self, "refresh_local", icon="FILE_REFRESH")
|
||||||
|
|
||||||
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]
|
||||||
|
|
||||||
if hash(self) not in self.node_dict:
|
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)]:
|
if not self.node_dict[hash(self)]:
|
||||||
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
||||||
|
|
||||||
if not self.inputs["blender_objects"].sv_get()[0]:
|
if not self.inputs["blender_objects"].sv_get()[0]:
|
||||||
return
|
return
|
||||||
edit = False
|
edit = False
|
||||||
for i in range(len(self.inputs)):
|
for i in range(len(self.inputs)):
|
||||||
input = self.inputs[i].sv_get(deepcopy=True)
|
input = self.inputs[i].sv_get(deepcopy=True)
|
||||||
if isinstance(self.node_dict[hash(self)][self.inputs[i].name], list) and input != self.node_dict[hash(self)][self.inputs[i].name]:
|
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
|
edit = True
|
||||||
self.node_dict[hash(self)][self.inputs[i].name] = input.copy()
|
self.node_dict[hash(self)][self.inputs[i].name] = input.copy()
|
||||||
|
|
||||||
blender_objects = self.inputs["blender_objects"].sv_get()
|
blender_objects = self.inputs["blender_objects"].sv_get()
|
||||||
self.file = SvIfcStore.get_file()
|
self.file = SvIfcStore.get_file()
|
||||||
|
|
||||||
@@ -124,8 +146,7 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
|
|||||||
representations = SvIfcStore.id_map[self.node_id]["Representations"]
|
representations = SvIfcStore.id_map[self.node_id]["Representations"]
|
||||||
locations = SvIfcStore.id_map[self.node_id]["Locations"]
|
locations = SvIfcStore.id_map[self.node_id]["Locations"]
|
||||||
|
|
||||||
print("representations: ", representations)
|
# print("representations: ", representations)
|
||||||
print("locations: ", locations)
|
|
||||||
|
|
||||||
self.outputs["Representations"].sv_set(representations)
|
self.outputs["Representations"].sv_set(representations)
|
||||||
self.outputs["Locations"].sv_set(locations)
|
self.outputs["Locations"].sv_set(locations)
|
||||||
@@ -134,41 +155,63 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
|
|||||||
representations_ids = []
|
representations_ids = []
|
||||||
locations = []
|
locations = []
|
||||||
for blender_object in blender_objects:
|
for blender_object in blender_objects:
|
||||||
if blender_object.type == 'MESH':
|
if blender_object.type == "MESH":
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
try:
|
||||||
bpy.ops.object.select_all(action='DESELECT')
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
bpy.ops.object.select_all(action="DESELECT")
|
||||||
blender_object.select_set(True)
|
blender_object.select_set(True)
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
try:
|
||||||
bpy.ops.mesh.separate(type='LOOSE')
|
bpy.ops.object.mode_set(mode="EDIT")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
bpy.ops.mesh.separate(type="LOOSE")
|
||||||
|
representations_ids_obj = []
|
||||||
|
locations_obj = []
|
||||||
for obj in bpy.context.selected_objects:
|
for obj in bpy.context.selected_objects:
|
||||||
representation = ifcopenshell.api.run("geometry.add_representation", self.file, should_run_listeners=False,blender_object = obj, geometry=obj.data, context = self.get_context())
|
representation = ifcopenshell.api.run(
|
||||||
|
"geometry.add_representation",
|
||||||
|
self.file,
|
||||||
|
should_run_listeners=False,
|
||||||
|
blender_object=obj,
|
||||||
|
geometry=obj.data,
|
||||||
|
context=self.get_context(),
|
||||||
|
)
|
||||||
if not representation:
|
if not representation:
|
||||||
raise Exception("Couldn't create representation. Possibly wrong context.")
|
raise Exception("Couldn't create representation. Possibly wrong context.")
|
||||||
representations_ids.append(representation.id())
|
|
||||||
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Representations", []).append(representation.id())
|
representations_ids_obj.append(representation.id())
|
||||||
locations.append(blender_object.matrix_world)
|
locations_obj.append(obj.matrix_world)
|
||||||
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Locations", []).append(blender_object.matrix_world)
|
representations_ids.append(representations_ids_obj)
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
locations.append(locations_obj)
|
||||||
bpy.ops.object.select_all(action='DESELECT')
|
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:
|
||||||
|
pass
|
||||||
|
bpy.ops.object.select_all(action="DESELECT")
|
||||||
return representations_ids, locations
|
return representations_ids, locations
|
||||||
|
|
||||||
def edit(self):
|
def edit(self):
|
||||||
if "Representations" not in SvIfcStore.id_map[self.node_id]:
|
if "Representations" not in SvIfcStore.id_map[self.node_id]:
|
||||||
return
|
return
|
||||||
for step_id in SvIfcStore.id_map[self.node_id]["Representations"]:
|
for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
|
||||||
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=self.file.by_id(step_id))
|
for step_id in obj:
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"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]["Representations"]
|
||||||
del SvIfcStore.id_map[self.node_id]["Locations"]
|
del SvIfcStore.id_map[self.node_id]["Locations"]
|
||||||
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))
|
|
||||||
return results
|
|
||||||
|
|
||||||
def get_context(self):
|
def get_context(self):
|
||||||
context = ifcopenshell.util.representation.get_context(self.file, self.context_type, self.context_identifier, self.target_view)
|
context = ifcopenshell.util.representation.get_context(
|
||||||
|
self.file, self.context_type, self.context_identifier, self.target_view
|
||||||
|
)
|
||||||
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:
|
||||||
@@ -184,13 +227,15 @@ 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):
|
||||||
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]:
|
||||||
for step_id in SvIfcStore.id_map[self.node_id]["Representations"]:
|
for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
|
||||||
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=self.file.by_id(step_id))
|
for step_id in obj:
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"geometry.remove_representation", self.file, representation=self.file.by_id(step_id)
|
||||||
|
)
|
||||||
|
|
||||||
if "Contexts" in SvIfcStore.id_map[self.node_id]:
|
if "Contexts" in SvIfcStore.id_map[self.node_id]:
|
||||||
for context_id in SvIfcStore.id_map[self.node_id]["Contexts"]:
|
for context_id in SvIfcStore.id_map[self.node_id]["Contexts"]:
|
||||||
@@ -202,11 +247,11 @@ class SvIfcBMeshToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.help
|
|||||||
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.run("context.remove_context", self.file, context=parent)
|
||||||
print("Removed context with step ID: ", context_id)
|
# 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')
|
# print('Node was deleted')
|
||||||
except KeyError or AttributeError:
|
except KeyError or AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -17,8 +16,8 @@
|
|||||||
# 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/>.
|
||||||
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
|
||||||
import ifcsverchok.helper
|
import ifcsverchok.helper
|
||||||
from ifcsverchok.ifcstore import SvIfcStore
|
from ifcsverchok.ifcstore import SvIfcStore
|
||||||
from bpy.props import StringProperty
|
from bpy.props import StringProperty
|
||||||
@@ -29,24 +28,29 @@ from sverchok.data_structure import updateNode, flatten_data
|
|||||||
class SvIfcById(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcById(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
bl_idname = "SvIfcById"
|
bl_idname = "SvIfcById"
|
||||||
bl_label = "IFC By Id"
|
bl_label = "IFC By Id"
|
||||||
id: StringProperty(name="Id(s)", update=updateNode, )
|
id: StringProperty(
|
||||||
|
name="Id(s)",
|
||||||
|
update=updateNode,
|
||||||
|
)
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "id").prop_name = "id"
|
self.inputs.new("SvStringsSocket", "id").prop_name = "id"
|
||||||
self.outputs.new("SvStringsSocket", "Entities")
|
self.outputs.new("SvStringsSocket", "Entities")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
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."
|
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):
|
def process(self):
|
||||||
self.ids = flatten_data(self.inputs["id"].sv_get(), target_level=1)
|
self.ids = flatten_data(self.inputs["id"].sv_get(), target_level=1)
|
||||||
print(self.ids)
|
|
||||||
if not self.ids[0]:
|
if not self.ids[0]:
|
||||||
return
|
return
|
||||||
self.file = SvIfcStore.get_file()
|
self.file = SvIfcStore.get_file()
|
||||||
self.entities = [self.file.by_id(int(step_id)) for step_id in self.ids]
|
self.entities = [self.file.by_id(int(step_id)) for step_id in self.ids]
|
||||||
self.outputs["Entities"].sv_set(self.entities)
|
self.outputs["Entities"].sv_set(self.entities)
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(SvIfcById)
|
bpy.utils.register_class(SvIfcById)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -23,8 +22,8 @@ import ifcsverchok.helper
|
|||||||
from bpy.props import StringProperty, EnumProperty
|
from bpy.props import StringProperty, EnumProperty
|
||||||
from ifcsverchok.ifcstore import SvIfcStore
|
from ifcsverchok.ifcstore import SvIfcStore
|
||||||
from sverchok.node_tree import SverchCustomTreeNode
|
from sverchok.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import updateNode, flatten_data
|
from sverchok.data_structure import updateNode
|
||||||
from sverchok.utils.handle_blender_data import keep_enum_reference
|
|
||||||
|
|
||||||
def get_ifc_products(self, context):
|
def get_ifc_products(self, context):
|
||||||
ifc_products = getattr(self, "ifc_products", [])
|
ifc_products = getattr(self, "ifc_products", [])
|
||||||
@@ -57,6 +56,7 @@ def update_ifc_products(self, context):
|
|||||||
if hasattr(self, "ifc_classes"):
|
if hasattr(self, "ifc_classes"):
|
||||||
self.ifc_classes.clear()
|
self.ifc_classes.clear()
|
||||||
|
|
||||||
|
|
||||||
def get_ifc_classes(self, context):
|
def get_ifc_classes(self, context):
|
||||||
ifc_classes = getattr(self, "ifc_classes", [])
|
ifc_classes = getattr(self, "ifc_classes", [])
|
||||||
if ifc_classes:
|
if ifc_classes:
|
||||||
@@ -83,9 +83,18 @@ def get_ifc_classes(self, context):
|
|||||||
class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
bl_idname = "SvIfcByType"
|
bl_idname = "SvIfcByType"
|
||||||
bl_label = "IFC By Type"
|
bl_label = "IFC By Type"
|
||||||
ifc_product: EnumProperty(items=get_ifc_products, name="IfcProduct", description="Pick an IfcProduct from drop-down.", update=update_ifc_products)
|
ifc_product: EnumProperty(
|
||||||
ifc_class: EnumProperty(items=get_ifc_classes, name="IfcClass", description="Pick an IfcClass from drop-down.", update=updateNode)
|
items=get_ifc_products,
|
||||||
custom_ifc_class: StringProperty(name="Custom IfcClass", description="Give the name of your custom IfcClass.", update=updateNode)
|
name="IfcProduct",
|
||||||
|
description="Pick an IfcProduct from drop-down.",
|
||||||
|
update=update_ifc_products,
|
||||||
|
)
|
||||||
|
ifc_class: EnumProperty(
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "ifc_product").prop_name = "ifc_product"
|
self.inputs.new("SvStringsSocket", "ifc_product").prop_name = "ifc_product"
|
||||||
@@ -93,9 +102,13 @@ class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc
|
|||||||
self.inputs.new("SvStringsSocket", "custom_ifc_class").prop_name = "custom_ifc_class"
|
self.inputs.new("SvStringsSocket", "custom_ifc_class").prop_name = "custom_ifc_class"
|
||||||
self.outputs.new("SvStringsSocket", "Entity")
|
self.outputs.new("SvStringsSocket", "Entity")
|
||||||
self.width = 200
|
self.width = 200
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
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."
|
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."
|
||||||
|
)
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
self.file = SvIfcStore.get_file()
|
self.file = SvIfcStore.get_file()
|
||||||
@@ -119,4 +132,4 @@ def register():
|
|||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
bpy.utils.unregister_class(SvIfcByType)
|
bpy.utils.unregister_class(SvIfcByType)
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
|
# IfcSverchok - IFC Sverchok extension
|
||||||
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
|
#
|
||||||
|
# This file is part of IfcSverchok.
|
||||||
|
#
|
||||||
|
# IfcSverchok is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# IfcSverchok is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with IfcSverchok. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from mathutils import Matrix, Vector
|
from mathutils import Matrix
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcsverchok.helper
|
import ifcsverchok.helper
|
||||||
from ifcsverchok.ifcstore import SvIfcStore
|
from ifcsverchok.ifcstore import SvIfcStore
|
||||||
|
|
||||||
# import ifcsverchok.ifc_store
|
from bpy.props import StringProperty, BoolProperty
|
||||||
# from bpy.props import StringProperty
|
|
||||||
# from sverchok.node_tree import SverchCustomTreeNode
|
|
||||||
# from sverchok.data_structure import updateNode
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import ifcopenshell
|
|
||||||
|
|
||||||
from bpy.props import StringProperty, EnumProperty, IntProperty, BoolProperty
|
|
||||||
from sverchok.node_tree import SverchCustomTreeNode
|
from sverchok.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import updateNode, flatten_data, repeat_last_for_length
|
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):
|
||||||
@@ -43,32 +53,33 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
|
|||||||
self.inputs.new("SvStringsSocket", "Descriptions").prop_name = "Descriptions"
|
self.inputs.new("SvStringsSocket", "Descriptions").prop_name = "Descriptions"
|
||||||
self.inputs.new("SvStringsSocket", "IfcClass").prop_name = "IfcClass"
|
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("SvMatrixSocket", "Locations").is_mandatory = False
|
||||||
self.inputs.new("SvStringsSocket", "Properties").prop_name = "Properties"
|
self.inputs.new("SvStringsSocket", "Properties").prop_name = "Properties"
|
||||||
self.outputs.new("SvStringsSocket", "Entities")
|
self.outputs.new("SvStringsSocket", "Entities")
|
||||||
self.node_dict[hash(self)] = {}
|
self.node_dict[hash(self)] = {}
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
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."
|
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 = layout.row(align=True)
|
||||||
row.prop(self, 'is_interactive', icon='SCENE_DATA', icon_only=True)
|
row.prop(self, "is_interactive", icon="SCENE_DATA", icon_only=True)
|
||||||
row.prop(self, 'refresh_local', icon='FILE_REFRESH')
|
row.prop(self, "refresh_local", icon="FILE_REFRESH")
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
|
|
||||||
self.names = flatten_data(self.inputs["Names"].sv_get(), target_level=1)
|
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.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.ifc_class = flatten_data(self.inputs["IfcClass"].sv_get(), target_level=1)[0]
|
||||||
self.representations = flatten_data(self.inputs["Representations"].sv_get(), target_level=1)
|
self.representations = ensure_min_nesting(self.inputs["Representations"].sv_get(), 2)
|
||||||
self.locations = flatten_data(self.inputs["Locations"].sv_get(default=[]), target_level=1)
|
self.representations = flatten_data(self.representations, target_level=2)
|
||||||
|
self.locations = ensure_min_nesting(self.inputs["Locations"].sv_get(default=[]), 2)
|
||||||
self.properties = self.inputs["Properties"].sv_get()
|
self.properties = self.inputs["Properties"].sv_get()
|
||||||
|
|
||||||
|
|
||||||
self.sv_input_names = [i.name for i in self.inputs]
|
self.sv_input_names = [i.name for i in self.inputs]
|
||||||
|
|
||||||
if hash(self) not in self.node_dict:
|
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)]:
|
if not self.node_dict[hash(self)]:
|
||||||
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
||||||
if not self.inputs["IfcClass"].sv_get()[0][0]:
|
if not self.inputs["IfcClass"].sv_get()[0][0]:
|
||||||
@@ -76,18 +87,24 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
|
|||||||
|
|
||||||
edit = False
|
edit = False
|
||||||
for i in range(len(self.inputs)):
|
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]:
|
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
|
edit = True
|
||||||
self.node_dict[hash(self)][self.inputs[i].name] = input.copy()
|
self.node_dict[hash(self)][self.inputs[i].name] = input.copy()
|
||||||
|
|
||||||
if self.refresh_local:
|
if self.refresh_local:
|
||||||
edit = True
|
edit = True
|
||||||
|
|
||||||
self.file = SvIfcStore.get_file()
|
self.file = SvIfcStore.get_file()
|
||||||
if self.representations[0]:
|
if self.representations[0][0]:
|
||||||
try:
|
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 self.representations]
|
||||||
|
self.representations = [
|
||||||
|
[self.file.by_id(step_id) for step_id in representation] for representation in self.representations
|
||||||
|
]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise
|
raise
|
||||||
self.names = self.repeat_input_unique(self.names, len(self.representations))
|
self.names = self.repeat_input_unique(self.names, len(self.representations))
|
||||||
@@ -102,9 +119,8 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
|
|||||||
entities = self.edit()
|
entities = self.edit()
|
||||||
else:
|
else:
|
||||||
entities = SvIfcStore.id_map[self.node_id]
|
entities = SvIfcStore.id_map[self.node_id]
|
||||||
|
|
||||||
print("Entities: ", entities)
|
|
||||||
|
|
||||||
|
# print("Entities: ", entities)
|
||||||
self.outputs["Entities"].sv_set(entities)
|
self.outputs["Entities"].sv_set(entities)
|
||||||
|
|
||||||
def create(self, index=None):
|
def create(self, index=None):
|
||||||
@@ -114,20 +130,32 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
|
|||||||
iterator = [index]
|
iterator = [index]
|
||||||
for i in iterator:
|
for i in iterator:
|
||||||
try:
|
try:
|
||||||
entity = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=self.ifc_class, name=self.names[i], description=self.descriptions[i])
|
entity = ifcopenshell.api.run(
|
||||||
|
"root.create_entity",
|
||||||
|
self.file,
|
||||||
|
ifc_class=self.ifc_class,
|
||||||
|
name=self.names[i],
|
||||||
|
description=self.descriptions[i],
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
if self.representations[i]:
|
for repr in self.representations[i]:
|
||||||
ifcopenshell.api.run("geometry.assign_representation", self.file, product=entity, representation=self.representations[i])
|
if self.representations[i]:
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"geometry.assign_representation", self.file, product=entity, representation=repr
|
||||||
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
if isinstance(self.locations[i], Matrix):
|
for loc in self.locations[i]:
|
||||||
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=entity, matrix=self.locations[i])
|
if isinstance(self.locations[i], Matrix):
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"geometry.edit_object_placement", self.file, product=entity, matrix=loc
|
||||||
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
entities_ids.append(entity.id())
|
entities_ids.append(entity.id())
|
||||||
SvIfcStore.id_map.setdefault(self.node_id, []).append(entity.id())
|
SvIfcStore.id_map.setdefault(self.node_id, []).append(entity.id())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception("Something went wrong. Cannot create entity.", e)
|
raise Exception("Something went wrong. Cannot create entity.", e)
|
||||||
return entities_ids
|
return entities_ids
|
||||||
|
|
||||||
@@ -146,15 +174,19 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
|
|||||||
entity.Description = self.descriptions[i]
|
entity.Description = self.descriptions[i]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.representations[i] and self.representations[i].is_a('IfcProductDefinitionShape'):
|
for repr in self.representations[i]:
|
||||||
entity.Representation = self.representations[i]
|
if repr and repr.is_a("IfcProductDefinitionShape"):
|
||||||
elif self.representations[i]:
|
entity.Representation = repr
|
||||||
ifcopenshell.api.run("geometry.assign_representation", self.file, product=entity, representation=self.representations[i])
|
elif repr:
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"geometry.assign_representation", self.file, product=entity, representation=repr
|
||||||
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
if isinstance(self.locations[i], Matrix):
|
for loc in self.locations[i]:
|
||||||
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=entity, matrix=self.locations[i])
|
if isinstance(loc, Matrix):
|
||||||
|
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=entity, matrix=loc)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
if entity.is_a() != self.ifc_class:
|
if entity.is_a() != self.ifc_class:
|
||||||
@@ -163,21 +195,23 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
|
|||||||
SvIfcStore.id_map.setdefault(self.node_id, []).append(entity.id())
|
SvIfcStore.id_map.setdefault(self.node_id, []).append(entity.id())
|
||||||
entities_ids.append(entity.id())
|
entities_ids.append(entity.id())
|
||||||
|
|
||||||
if id_map_copy>entities_ids:
|
if id_map_copy > entities_ids:
|
||||||
SvIfcStore.id_map[self.node_id] = entities_ids
|
SvIfcStore.id_map[self.node_id] = entities_ids
|
||||||
return entities_ids
|
return entities_ids
|
||||||
|
|
||||||
def repeat_input_unique(self, input, count):
|
def repeat_input_unique(self, input, count):
|
||||||
input = repeat_last_for_length(input, count, deepcopy=False)
|
input = repeat_last_for_length(input, count, deepcopy=False)
|
||||||
if input[0]:
|
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
|
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 input
|
||||||
|
|
||||||
def sv_free(self):
|
def sv_free(self):
|
||||||
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')
|
# print('Node was deleted')
|
||||||
except KeyError or AttributeError:
|
except KeyError or AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -19,10 +19,8 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcsverchok.helper
|
import ifcsverchok.helper
|
||||||
from bpy.props import StringProperty
|
|
||||||
from sverchok.node_tree import SverchCustomTreeNode
|
from sverchok.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import updateNode
|
|
||||||
# from ifcopenshell import template
|
|
||||||
|
|
||||||
class SvIfcCreateProject(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcCreateProject(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
bl_idname = "SvIfcCreateProject"
|
bl_idname = "SvIfcCreateProject"
|
||||||
@@ -36,25 +34,26 @@ class SvIfcCreateProject(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helpe
|
|||||||
self.outputs.new("SvVerticesSocket", "file")
|
self.outputs.new("SvVerticesSocket", "file")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Adds project, unit and context to IFC file"
|
op = layout.operator(
|
||||||
#op.tooltip = self.tooltip
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
|
).tooltip = "Adds project, unit and context to IFC file"
|
||||||
|
# op.tooltip = self.tooltip
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
#file
|
# file
|
||||||
file = self.inputs["file"].sv_get()[0][0]
|
file = self.inputs["file"].sv_get()[0][0]
|
||||||
if file:
|
if file:
|
||||||
schema_name = file.wrapped_data.schema
|
schema_name = file.wrapped_data.schema
|
||||||
else:
|
else:
|
||||||
schema_name = "IFC4"
|
schema_name = "IFC4"
|
||||||
|
|
||||||
#project name
|
# project name
|
||||||
project_name = self.inputs["project_name"].sv_get()[0][0]
|
project_name = self.inputs["project_name"].sv_get()[0][0]
|
||||||
self.process_ifc(file, project_name)
|
self.process_ifc(file, project_name)
|
||||||
|
|
||||||
|
|
||||||
def process_ifc(self, file, project_name):
|
def process_ifc(self, file, project_name):
|
||||||
|
|
||||||
# create project
|
# create project
|
||||||
project = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcProject", name=str(project_name))
|
project = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcProject", name=str(project_name))
|
||||||
lengthunit = ifcopenshell.api.run("unit.add_si_unit", file, unit_type="LENGTHUNIT", name="METRE")
|
lengthunit = ifcopenshell.api.run("unit.add_si_unit", file, unit_type="LENGTHUNIT", name="METRE")
|
||||||
ifcopenshell.api.run("unit.assign_unit", file, units=[lengthunit])
|
ifcopenshell.api.run("unit.assign_unit", file, units=[lengthunit])
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -28,29 +27,16 @@ from sverchok.node_tree import SverchCustomTreeNode
|
|||||||
from sverchok.data_structure import updateNode, flatten_data
|
from sverchok.data_structure import updateNode, flatten_data
|
||||||
|
|
||||||
|
|
||||||
# class SvIfcCreateShapeRefresh(bpy.types.Operator):
|
|
||||||
# bl_idname = "node.sv_ifc_create_shape_refresh"
|
|
||||||
# bl_label = "IFC Create Shape Refresh"
|
|
||||||
# bl_options = {"UNDO"}
|
|
||||||
|
|
||||||
|
|
||||||
# tree_name: StringProperty(default="")
|
|
||||||
# node_name: StringProperty(default="")
|
|
||||||
|
|
||||||
# def execute(self, context):
|
|
||||||
# node = bpy.data.node_groups[self.tree_name].nodes[self.node_name]
|
|
||||||
# node.process()
|
|
||||||
# return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
"""
|
"""
|
||||||
Triggers: Ifc create shape by entity
|
Triggers: Ifc create shape by entity
|
||||||
Tooltip: Create Blender shape by Ifc Entity
|
Tooltip: Create Blender shape by Ifc Entity
|
||||||
"""
|
"""
|
||||||
|
|
||||||
is_scene_dependent = True
|
is_scene_dependent = True
|
||||||
is_interactive = False
|
is_interactive = False
|
||||||
node_dict = {}
|
node_dict = {}
|
||||||
|
|
||||||
def refresh_node(self, context):
|
def refresh_node(self, context):
|
||||||
if self.refresh_local:
|
if self.refresh_local:
|
||||||
self.process()
|
self.process()
|
||||||
@@ -61,22 +47,23 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
|
|||||||
bl_idname = "SvIfcCreateShape"
|
bl_idname = "SvIfcCreateShape"
|
||||||
bl_label = "IFC Create Blender Shape"
|
bl_label = "IFC Create Blender Shape"
|
||||||
entity: StringProperty(name="Entities", update=updateNode)
|
entity: StringProperty(name="Entities", update=updateNode)
|
||||||
|
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "Entities").prop_name = "entity"
|
self.inputs.new("SvStringsSocket", "Entities").prop_name = "entity"
|
||||||
self.outputs.new('SvStringsSocket', "Object(s)")
|
self.outputs.new("SvStringsSocket", "Object(s)")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
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."
|
row.operator(
|
||||||
row.prop(self, 'refresh_local', icon='FILE_REFRESH')
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
|
).tooltip = "Create Blender shape from IfcEntity ID. Takes one or multiple IfcEntity IDs."
|
||||||
|
row.prop(self, "refresh_local", icon="FILE_REFRESH")
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
self.entities = flatten_data(self.inputs["Entities"].sv_get(), target_level = 1)
|
self.entities = flatten_data(self.inputs["Entities"].sv_get(), target_level=1)
|
||||||
if not self.entities[0]:
|
if not self.entities[0]:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.refresh_local or hash(self) not in self.node_dict:
|
if self.refresh_local or hash(self) not in self.node_dict:
|
||||||
self.file = SvIfcStore.get_file()
|
self.file = SvIfcStore.get_file()
|
||||||
try:
|
try:
|
||||||
@@ -87,7 +74,7 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
|
|||||||
self.node_dict[hash(self)] = blender_objects
|
self.node_dict[hash(self)] = blender_objects
|
||||||
else:
|
else:
|
||||||
blender_objects = self.node_dict[hash(self)]
|
blender_objects = self.node_dict[hash(self)]
|
||||||
|
|
||||||
self.outputs["Object(s)"].sv_set(blender_objects)
|
self.outputs["Object(s)"].sv_set(blender_objects)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
@@ -110,6 +97,7 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
|
|||||||
raise Exception("Entity could not be converted into a shape. Entity: {}".format(entity))
|
raise Exception("Entity could not be converted into a shape. Entity: {}".format(entity))
|
||||||
return blender_objects
|
return blender_objects
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
# bpy.utils.register_class(SvIfcCreateShapeRefresh)
|
# bpy.utils.register_class(SvIfcCreateShapeRefresh)
|
||||||
bpy.utils.register_class(SvIfcCreateShape)
|
bpy.utils.register_class(SvIfcCreateShape)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -20,9 +19,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcsverchok.helper
|
import ifcsverchok.helper
|
||||||
from bpy.props import StringProperty
|
|
||||||
from sverchok.node_tree import SverchCustomTreeNode
|
from sverchok.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import updateNode
|
|
||||||
|
|
||||||
|
|
||||||
class SvIfcGenerateGuid(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcGenerateGuid(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -20,11 +19,12 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcsverchok.helper
|
import ifcsverchok.helper
|
||||||
from bpy.props import StringProperty, EnumProperty
|
from bpy.props import EnumProperty
|
||||||
from ifcsverchok.ifcstore import SvIfcStore
|
from ifcsverchok.ifcstore import SvIfcStore
|
||||||
from sverchok.node_tree import SverchCustomTreeNode
|
from sverchok.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import updateNode
|
from sverchok.data_structure import updateNode
|
||||||
|
|
||||||
|
|
||||||
def get_ifc_products(self, context):
|
def get_ifc_products(self, context):
|
||||||
ifc_products = getattr(self, "ifc_products", [])
|
ifc_products = getattr(self, "ifc_products", [])
|
||||||
file = SvIfcStore.get_file()
|
file = SvIfcStore.get_file()
|
||||||
@@ -83,15 +83,22 @@ def get_ifc_classes(self, context):
|
|||||||
class SvIfcPickIfcClass(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcPickIfcClass(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
bl_idname = "SvIfcPickIfcClass"
|
bl_idname = "SvIfcPickIfcClass"
|
||||||
bl_label = "IFC Class Picker"
|
bl_label = "IFC Class Picker"
|
||||||
ifc_product: EnumProperty(items=get_ifc_products, name="IfcProduct", description="Pick an IfcProduct from drop-down.", update=update_ifc_products)
|
ifc_product: EnumProperty(
|
||||||
ifc_class: EnumProperty(items=get_ifc_classes, name="IfcClass", description="Pick an IfcClass from drop-down.", update=updateNode)
|
items=get_ifc_products,
|
||||||
|
name="IfcProduct",
|
||||||
|
description="Pick an IfcProduct from drop-down.",
|
||||||
|
update=update_ifc_products,
|
||||||
|
)
|
||||||
|
ifc_class: EnumProperty(
|
||||||
|
items=get_ifc_classes, name="IfcClass", description="Pick an IfcClass from drop-down.", update=updateNode
|
||||||
|
)
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "ifc_product").prop_name = "ifc_product"
|
self.inputs.new("SvStringsSocket", "ifc_product").prop_name = "ifc_product"
|
||||||
self.inputs.new("SvStringsSocket", "ifc_class").prop_name = "ifc_class"
|
self.inputs.new("SvStringsSocket", "ifc_class").prop_name = "ifc_class"
|
||||||
self.outputs.new("SvStringsSocket", "IfcClass")
|
self.outputs.new("SvStringsSocket", "IfcClass")
|
||||||
self.width = 200
|
self.width = 200
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Ifc Class Picker"
|
layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Ifc Class Picker"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# 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 email.mime import application
|
from email.mime import application
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
@@ -25,6 +26,7 @@ from sverchok.node_tree import SverchCustomTreeNode
|
|||||||
from sverchok.data_structure import updateNode
|
from sverchok.data_structure import updateNode
|
||||||
from ifcopenshell import template
|
from ifcopenshell import template
|
||||||
|
|
||||||
|
|
||||||
class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||||
bl_idname = "SvIfcQuickProjectSetup"
|
bl_idname = "SvIfcQuickProjectSetup"
|
||||||
bl_label = "IFC Quick Project Setup"
|
bl_label = "IFC Quick Project Setup"
|
||||||
@@ -33,7 +35,6 @@ class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
application: StringProperty(name="application", update=updateNode)
|
application: StringProperty(name="application", update=updateNode)
|
||||||
application_version: StringProperty(name="application_version", update=updateNode)
|
application_version: StringProperty(name="application_version", update=updateNode)
|
||||||
timestamp: StringProperty(name="timestamp", update=updateNode)
|
timestamp: StringProperty(name="timestamp", update=updateNode)
|
||||||
|
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
input_socket = self.inputs.new("SvStringsSocket", "filename")
|
input_socket = self.inputs.new("SvStringsSocket", "filename")
|
||||||
@@ -59,8 +60,10 @@ class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
self.outputs.new("SvVerticesSocket", "file")
|
self.outputs.new("SvVerticesSocket", "file")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
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"
|
op = layout.operator(
|
||||||
#op.tooltip = self.tooltip
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
|
).tooltip = "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]
|
||||||
@@ -70,17 +73,17 @@ class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
settings = dict(zip(self.sv_input_names, setting_values))
|
settings = dict(zip(self.sv_input_names, setting_values))
|
||||||
settings = {k: v for k, v in settings.items() if v != ""}
|
settings = {k: v for k, v in settings.items() if v != ""}
|
||||||
file = template.create(
|
file = template.create(
|
||||||
filename=settings['filename'],
|
filename=settings["filename"],
|
||||||
timestring=settings['timestring'],
|
timestring=settings["timestring"],
|
||||||
organization=settings['organization'],
|
organization=settings["organization"],
|
||||||
creator=settings['creator'],
|
creator=settings["creator"],
|
||||||
schema_identifier=settings['schema_identifier'],
|
schema_identifier=settings["schema_identifier"],
|
||||||
application_version=settings['application_version'],
|
application_version=settings["application_version"],
|
||||||
timestamp=settings['timestamp'],
|
timestamp=settings["timestamp"],
|
||||||
application=settings['application'],
|
application=settings["application"],
|
||||||
project_globalid=settings['project_globalid'],
|
project_globalid=settings["project_globalid"],
|
||||||
project_name=settings['project_name'],
|
project_name=settings["project_name"],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.outputs["file"].sv_set([[file]])
|
self.outputs["file"].sv_set([[file]])
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -63,7 +62,7 @@ class SvIfcReadEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.S
|
|||||||
self.outputs.new("SvStringsSocket", name).prop_name = name
|
self.outputs.new("SvStringsSocket", name).prop_name = name
|
||||||
self.current_ifc_class = ifc_class
|
self.current_ifc_class = ifc_class
|
||||||
|
|
||||||
def process_ifc(self, file, entity):
|
def process_ifc(self, entity):
|
||||||
self.outputs["id"].sv_set([[entity.id()]])
|
self.outputs["id"].sv_set([[entity.id()]])
|
||||||
self.outputs["is_a"].sv_set([[entity.is_a()]])
|
self.outputs["is_a"].sv_set([[entity.is_a()]])
|
||||||
for i in range(0, self.entity_schema.attribute_count()):
|
for i in range(0, self.entity_schema.attribute_count()):
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#
|
#
|
||||||
# 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
|
from copy import deepcopy
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
@@ -26,124 +26,146 @@ import blenderbim.tool as tool
|
|||||||
import blenderbim.core.geometry as core
|
import blenderbim.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
|
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
|
Triggers: Sv to Ifc Repr
|
||||||
Tooltip: Sverchok geometry to Ifc Shape Representation
|
Tooltip: Sverchok geometry to Ifc Shape Representation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bl_idname = "SvIfcSverchokToIfcRepr"
|
bl_idname = "SvIfcSverchokToIfcRepr"
|
||||||
bl_label = "IFC Sverchok to IFC Repr"
|
bl_label = "IFC Sverchok to IFC Repr"
|
||||||
node_dict = {}
|
node_dict = {}
|
||||||
|
|
||||||
n_id: StringProperty()
|
n_id: StringProperty()
|
||||||
context_types = [
|
context_types = [
|
||||||
('Model', 'Model', 'Context type: Model', 0),
|
("Model", "Model", "Context type: Model", 0),
|
||||||
('Plan', 'Plan', 'Context type: Plan', 1),
|
("Plan", "Plan", "Context type: Plan", 1),
|
||||||
]
|
]
|
||||||
|
|
||||||
context_identifiers = [
|
context_identifiers = [
|
||||||
('Body', 'Body', 'Context identifier: Body', 0),
|
("Body", "Body", "Context identifier: Body", 0),
|
||||||
('Annotation', 'Annotation', 'Context identifier: Annotation', 1),
|
("Annotation", "Annotation", "Context identifier: Annotation", 1),
|
||||||
('Box', 'Box', 'Context identifier: Box', 2),
|
("Box", "Box", "Context identifier: Box", 2),
|
||||||
('Axis', 'Axis', 'Context identifier: Axis', 3),
|
("Axis", "Axis", "Context identifier: Axis", 3),
|
||||||
]
|
]
|
||||||
target_views = [
|
target_views = [
|
||||||
('MODEL_VIEW', 'MODEL_VIEW', 'Target View: MODEL_VIEW', 0),
|
("MODEL_VIEW", "MODEL_VIEW", "Target View: MODEL_VIEW", 0),
|
||||||
('PLAN_VIEW', 'PLAN_VIEW', 'Target View: PLAN_VIEW', 1),
|
("PLAN_VIEW", "PLAN_VIEW", "Target View: PLAN_VIEW", 1),
|
||||||
('GRAPH_VIEW', 'GRAPH_VIEW', 'Target View: GRAPH_VIEW', 2),
|
("GRAPH_VIEW", "GRAPH_VIEW", "Target View: GRAPH_VIEW", 2),
|
||||||
('SKETCH_VIEW', 'SKETCH_VIEW', 'Target View: SKETCH_VIEW', 3),
|
("SKETCH_VIEW", "SKETCH_VIEW", "Target View: SKETCH_VIEW", 3),
|
||||||
]
|
]
|
||||||
|
|
||||||
context_type: EnumProperty(name="Context Type", description="Default: Model", default="Model",items=context_types,update=updateNode)
|
context_type: EnumProperty(
|
||||||
context_identifier: EnumProperty(name="Context Identifier", description="Default: Body", default="Body", items=context_identifiers, update=updateNode)
|
name="Context Type", description="Default: Model", default="Model", items=context_types, update=updateNode
|
||||||
target_view: EnumProperty(name="Target View", description="Default: MODEL VIEW", default="MODEL_VIEW",items=target_views, update=updateNode)
|
)
|
||||||
|
context_identifier: EnumProperty(
|
||||||
|
name="Context Identifier",
|
||||||
|
description="Default: Body",
|
||||||
|
default="Body",
|
||||||
|
items=context_identifiers,
|
||||||
|
update=updateNode,
|
||||||
|
)
|
||||||
|
target_view: EnumProperty(
|
||||||
|
name="Target View",
|
||||||
|
description="Default: MODEL VIEW",
|
||||||
|
default="MODEL_VIEW",
|
||||||
|
items=target_views,
|
||||||
|
update=updateNode,
|
||||||
|
)
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "context_type").prop_name = "context_type"
|
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("SvStringsSocket", "target_view").prop_name = "target_view"
|
||||||
self.inputs.new("SvVerticesSocket", "Vertices")
|
self.inputs.new("SvVerticesSocket", "Vertices")
|
||||||
self.inputs.new("SvStringsSocket", "Edges")
|
self.inputs.new("SvStringsSocket", "Edges")
|
||||||
self.inputs.new("SvStringsSocket", "Faces")
|
self.inputs.new("SvStringsSocket", "Faces")
|
||||||
self.outputs.new("SvVerticesSocket", "Representation(s)")
|
self.outputs.new("SvVerticesSocket", "Representation(s)")
|
||||||
self.width = 210
|
self.width = 210
|
||||||
self.node_dict[hash(self)] = {}
|
self.node_dict[hash(self)] = {}
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
op = layout.operator(
|
op = layout.operator(
|
||||||
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
).tooltip = "Sverchok geometry to Ifc Shape Representation. \nTakes one or multiple geometries."
|
).tooltip = "Sverchok geometry to Ifc Shape Representation. \nTakes one or multiple geometries."
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
if not any(socket.is_linked for socket in self.inputs):
|
if not any(socket.is_linked for socket in self.inputs):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.file = SvIfcStore.get_file()
|
self.file = SvIfcStore.get_file()
|
||||||
self.sv_input_names = [i.name for i in self.inputs]
|
self.sv_input_names = [i.name for i in self.inputs]
|
||||||
|
|
||||||
if hash(self) not in self.node_dict:
|
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)]:
|
if not self.node_dict[hash(self)]:
|
||||||
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
self.node_dict[hash(self)].update(dict.fromkeys(self.sv_input_names, 0))
|
||||||
|
|
||||||
edit = False
|
edit = False
|
||||||
for i in range(len(self.inputs)):
|
for i in range(len(self.inputs)):
|
||||||
input = self.inputs[i].sv_get(deepcopy=False)
|
input = self.inputs[i].sv_get(deepcopy=False)
|
||||||
if isinstance(self.node_dict[hash(self)][self.inputs[i].name], list) and input != self.node_dict[hash(self)][self.inputs[i].name]:
|
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
|
edit = True
|
||||||
self.node_dict[hash(self)][self.inputs[i].name] = input
|
self.node_dict[hash(self)][self.inputs[i].name] = input
|
||||||
|
|
||||||
self.vertices = self.inputs["Vertices"].sv_get(deepcopy=False)
|
self.vertices = ensure_min_nesting(self.inputs["Vertices"].sv_get(deepcopy=False), 4)
|
||||||
self.edges = self.inputs["Edges"].sv_get(deepcopy=False)
|
self.edges = ensure_min_nesting(self.inputs["Edges"].sv_get(deepcopy=False), 4)
|
||||||
self.faces = self.inputs["Faces"].sv_get(deepcopy=False)
|
self.faces = ensure_min_nesting(self.inputs["Faces"].sv_get(deepcopy=False), 4)
|
||||||
geo_data = list(zip(self.vertices, self.edges, self.faces))
|
data = list(zip(self.vertices, self.edges, self.faces))
|
||||||
|
objects = []
|
||||||
|
for object in data:
|
||||||
|
objects.append(list(zip(object[0], object[1], object[2])))
|
||||||
|
|
||||||
if self.node_id not in SvIfcStore.id_map:
|
if self.node_id not in SvIfcStore.id_map:
|
||||||
|
representations = self.create(objects)
|
||||||
representations = self.create(geo_data)
|
|
||||||
else:
|
else:
|
||||||
if edit is True:
|
if edit is True:
|
||||||
self.edit()
|
self.edit()
|
||||||
representations = self.create(geo_data)
|
representations = self.create(objects)
|
||||||
else:
|
else:
|
||||||
# representations = self.get_existing_element()
|
|
||||||
representations = SvIfcStore.id_map[self.node_id]["Representations"]
|
representations = SvIfcStore.id_map[self.node_id]["Representations"]
|
||||||
|
|
||||||
self.outputs["Representation(s)"].sv_set(representations)
|
self.outputs["Representation(s)"].sv_set(representations)
|
||||||
|
|
||||||
def create(self, geo_data):
|
def create(self, geo_data):
|
||||||
representations_ids = []
|
representations_ids = []
|
||||||
self.context = self.get_context()
|
self.context = self.get_context()
|
||||||
for item in geo_data:
|
for obj in geo_data:
|
||||||
representation = ifcopenshell.api.run(
|
representations_ids_obj = []
|
||||||
"geometry.add_sverchok_representation",
|
for item in obj:
|
||||||
self.file,
|
representation = ifcopenshell.api.run(
|
||||||
should_run_listeners=False,
|
"geometry.add_sverchok_representation",
|
||||||
context=self.context,
|
self.file,
|
||||||
vertices=[item[0]],
|
should_run_listeners=False,
|
||||||
edges=[item[1]],
|
context=self.context,
|
||||||
faces=[item[2]],
|
vertices=[list(map(tuple, item[0]))],
|
||||||
|
edges=[list(map(tuple, item[1]))],
|
||||||
|
faces=[list(map(tuple, item[2]))],
|
||||||
|
)
|
||||||
|
if not representation:
|
||||||
|
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
|
||||||
)
|
)
|
||||||
if not representation:
|
|
||||||
raise Exception("Couldn't create representation. Possibly wrong context.")
|
|
||||||
representations_ids.append(representation.id())
|
|
||||||
SvIfcStore.id_map.setdefault(self.node_id, {}).setdefault("Representations", []).append(representation.id())
|
|
||||||
return representations_ids
|
return representations_ids
|
||||||
|
|
||||||
def edit(self):
|
def edit(self):
|
||||||
# results = self.get_existing_element()
|
|
||||||
if "Representations" not in SvIfcStore.id_map[self.node_id]:
|
if "Representations" not in SvIfcStore.id_map[self.node_id]:
|
||||||
return
|
return
|
||||||
for step_id in SvIfcStore.id_map[self.node_id]["Representations"]:
|
for obj in SvIfcStore.id_map[self.node_id]["Representations"]:
|
||||||
ifcopenshell.api.run(
|
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]["Representations"]
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_context(self):
|
def get_context(self):
|
||||||
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
|
||||||
@@ -162,13 +184,15 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
)
|
)
|
||||||
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):
|
||||||
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]:
|
||||||
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("geometry.remove_representation", self.file, representation=self.file.by_id(step_id))
|
ifcopenshell.api.run(
|
||||||
|
"geometry.remove_representation", self.file, representation=self.file.by_id(step_id)
|
||||||
|
)
|
||||||
|
|
||||||
if "Contexts" in SvIfcStore.id_map[self.node_id]:
|
if "Contexts" in SvIfcStore.id_map[self.node_id]:
|
||||||
for context_id in SvIfcStore.id_map[self.node_id]["Contexts"]:
|
for context_id in SvIfcStore.id_map[self.node_id]["Contexts"]:
|
||||||
@@ -180,18 +204,18 @@ class SvIfcSverchokToIfcRepr(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.h
|
|||||||
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.run("context.remove_context", self.file, context=parent)
|
||||||
print("Removed context with step ID: ", context_id)
|
# 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')
|
# print('Node was deleted')
|
||||||
except KeyError or AttributeError:
|
except KeyError or AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(SvIfcSverchokToIfcRepr)
|
bpy.utils.register_class(SvIfcSverchokToIfcRepr)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
bpy.utils.unregister_class(SvIfcSverchokToIfcRepr)
|
bpy.utils.unregister_class(SvIfcSverchokToIfcRepr)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# IfcSverchok - IFC Sverchok extension
|
# IfcSverchok - IFC Sverchok extension
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2022 Martina Jakubowska <martina@jakubowska.dk>
|
||||||
#
|
#
|
||||||
# This file is part of IfcSverchok.
|
# This file is part of IfcSverchok.
|
||||||
#
|
#
|
||||||
@@ -32,29 +31,31 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv
|
|||||||
Triggers: Ifc write to file
|
Triggers: Ifc write to file
|
||||||
Tooltip: Write active Sverchok Ifc file to path
|
Tooltip: Write active Sverchok Ifc file to path
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def refresh_node_local(self, context):
|
def refresh_node_local(self, context):
|
||||||
if self.refresh_local:
|
if self.refresh_local:
|
||||||
self.process()
|
self.process()
|
||||||
self.refresh_local = False
|
self.refresh_local = False
|
||||||
|
|
||||||
# out = ""
|
|
||||||
refresh_local: BoolProperty(name="Write", description="Write to file", update=refresh_node_local)
|
refresh_local: BoolProperty(name="Write", description="Write to file", update=refresh_node_local)
|
||||||
|
|
||||||
bl_idname = "SvIfcWriteFile"
|
bl_idname = "SvIfcWriteFile"
|
||||||
bl_label = "IFC Write File"
|
bl_label = "IFC Write File"
|
||||||
path: StringProperty(name="path", description="File path to write to. Can be relative.", update=updateNode)
|
path: StringProperty(name="path", description="File path to write to. Can be relative.", update=updateNode)
|
||||||
|
|
||||||
def sv_init(self, context):
|
def sv_init(self, context):
|
||||||
self.inputs.new("SvStringsSocket", "path").prop_name = "path"
|
self.inputs.new("SvStringsSocket", "path").prop_name = "path"
|
||||||
self.outputs.new("SvStringsSocket", "output")
|
self.outputs.new("SvStringsSocket", "output")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Writes active Ifc file to path.\n It will overwrite an existing file.\n N.B.! It's recommended to create a fresh IFC File using the 're-run all nodes' button in IfcSverchok panel before saving."
|
row.operator(
|
||||||
row.prop(self, 'refresh_local', icon='FILE_REFRESH')
|
"node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False
|
||||||
|
).tooltip = "Writes active Ifc file to path.\n It will overwrite an existing file.\n N.B.! It's recommended to create a fresh IFC File using the 're-run all nodes' button in IfcSverchok panel before saving."
|
||||||
|
row.prop(self, "refresh_local", icon="FILE_REFRESH")
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
path = flatten_data(self.inputs["path"].sv_get(), target_level = 1)[0]
|
path = flatten_data(self.inputs["path"].sv_get(), target_level=1)[0]
|
||||||
if not path:
|
if not path:
|
||||||
return
|
return
|
||||||
path = abspath(path)
|
path = abspath(path)
|
||||||
@@ -66,7 +67,7 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv
|
|||||||
self.ensure_hirarchy(file)
|
self.ensure_hirarchy(file)
|
||||||
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):
|
||||||
elements_in_buildings = []
|
elements_in_buildings = []
|
||||||
if not 0 <= 0 < len(file.by_type("IfcBuilding")):
|
if not 0 <= 0 < len(file.by_type("IfcBuilding")):
|
||||||
@@ -77,10 +78,12 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv
|
|||||||
elements = ifcopenshell.util.element.get_decomposition(building)
|
elements = ifcopenshell.util.element.get_decomposition(building)
|
||||||
elements_in_buildings.extend(elements)
|
elements_in_buildings.extend(elements)
|
||||||
|
|
||||||
for spatial in (file.by_type("IfcSpatialElement") or file.by_type("IfcSpatialStructureElement")):
|
for spatial in file.by_type("IfcSpatialElement") or file.by_type("IfcSpatialStructureElement"):
|
||||||
if (not (spatial.is_a("IfcSite") or spatial.is_a("IfcBuilding")) and (spatial not in elements_in_buildings)):
|
if not (spatial.is_a("IfcSite") or spatial.is_a("IfcBuilding")) and (spatial not in elements_in_buildings):
|
||||||
elements = ifcopenshell.util.element.get_decomposition(spatial)
|
elements = ifcopenshell.util.element.get_decomposition(spatial)
|
||||||
ifcopenshell.api.run("aggregate.assign_object", file, product=spatial, relating_object=file.by_type("IfcBuilding")[0])
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object", file, product=spatial, relating_object=file.by_type("IfcBuilding")[0]
|
||||||
|
)
|
||||||
|
|
||||||
elements_in_buildings_after = []
|
elements_in_buildings_after = []
|
||||||
for building in file.by_type("IfcBuilding"):
|
for building in file.by_type("IfcBuilding"):
|
||||||
@@ -90,24 +93,31 @@ class SvIfcWriteFile(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.Sv
|
|||||||
elements = file.by_type("IfcElement")
|
elements = file.by_type("IfcElement")
|
||||||
for element in elements:
|
for element in elements:
|
||||||
if element not in elements_in_buildings:
|
if element not in elements_in_buildings:
|
||||||
ifcopenshell.api.run("spatial.assign_container", file, product=element, relating_structure=file.by_type("IfcBuilding")[0])
|
ifcopenshell.api.run(
|
||||||
|
"spatial.assign_container", file, product=element, relating_structure=file.by_type("IfcBuilding")[0]
|
||||||
|
)
|
||||||
|
|
||||||
for building in file.by_type("IfcBuilding"):
|
for building in file.by_type("IfcBuilding"):
|
||||||
elements = ifcopenshell.util.element.get_decomposition(building)
|
elements = ifcopenshell.util.element.get_decomposition(building)
|
||||||
if not building.Decomposes:
|
if not building.Decomposes:
|
||||||
if not 0 <= 0 < len(file.by_type("IfcSite")):
|
if not 0 <= 0 < len(file.by_type("IfcSite")):
|
||||||
ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site")
|
ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcSite", name="My Site")
|
||||||
ifcopenshell.api.run("aggregate.assign_object", file, product=building, relating_object=file.by_type("IfcSite")[0])
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object", file, product=building, relating_object=file.by_type("IfcSite")[0]
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
if file.by_type("IfcSite")[0].Decomposes[0].RelatingObject.is_a("IfcProject"):
|
if file.by_type("IfcSite")[0].Decomposes[0].RelatingObject.is_a("IfcProject"):
|
||||||
continue
|
continue
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
ifcopenshell.api.run("aggregate.assign_object", file, product=file.by_type("IfcSite")[0], relating_object=file.by_type("IfcProject")[0])
|
ifcopenshell.api.run(
|
||||||
|
"aggregate.assign_object",
|
||||||
|
file,
|
||||||
|
product=file.by_type("IfcSite")[0],
|
||||||
|
relating_object=file.by_type("IfcProject")[0],
|
||||||
|
)
|
||||||
self.file = file
|
self.file = file
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|||||||
Reference in New Issue
Block a user