Added new nodes: api_WIP, bmesh_to_ifc, create_project and quick_project_setup

Modified nodes: api, create_entity
This commit is contained in:
martinaCodes
2022-08-25 22:01:35 +02:00
committed by Dion Moult
parent f818446e7e
commit ba4130d395
9 changed files with 445 additions and 15 deletions
+21 -10
View File
@@ -26,10 +26,7 @@ from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
def update_usecase(self, context):
module_usecase = self.get_module_usecase()
if module_usecase:
self.generate_node(*module_usecase)
class SvIfcTooltip(bpy.types.Operator):
@@ -46,13 +43,25 @@ class SvIfcTooltip(bpy.types.Operator):
class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
def update_usecase(self, context):
try:
module_usecase = self.get_module_usecase()
if module_usecase:
self.generate_node(*module_usecase)
except:
raise Exception(
f"Couldn't run generate_node(). Module usecase: {module_usecase}"
)
bl_idname = "SvIfcApi"
bl_label = "IFC API"
tooltip: StringProperty(name="Tooltip")
usecase: StringProperty(name="Usecase", update=update_usecase)
usecase: StringProperty(update=updateNode)
def sv_init(self, context):
self.inputs.new("SvStringsSocket", "usecase").prop_name = "usecase"
input_socket = self.inputs.new("SvStringsSocket", "usecase").use_prop = True
input_socket.tooltip = "ifcopenshell.api usecase, written like 'module.usecase' \n E.g.: 'project.create_file'"
self.outputs.new("SvVerticesSocket", "file")
def draw_buttons(self, context, layout):
@@ -63,8 +72,9 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
print("process")
module_usecase = self.get_module_usecase()
if module_usecase:
self.generate_node(*module_usecase)
self.sv_input_names = [i.name for i in self.inputs]
super().process()
super().process() # super().process() uses zip_long_repeat() which doesn't take objects like bmesh
def get_module_usecase(self):
usecase = self.inputs["usecase"].sv_get()[0][0]
@@ -75,7 +85,7 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
try:
node_data = ifcopenshell.api.extract_docs(module, usecase)
except:
print("Node not yet implemented:", module, usecase)
raise Exception("Node not yet implemented:", module, usecase)
return
while len(self.inputs) > 1:
self.inputs.remove(self.inputs[-1])
@@ -83,7 +93,7 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
self.tooltip = ""
for name, data in node_data["inputs"].items():
setattr(SvIfcApi, name, StringProperty(name=name, update=updateNode))
self.inputs.new("SvStringsSocket", name).prop_name = name
self.inputs.new("SvStringsSocket", name).use_prop = True
if "default" in data:
self.tooltip = f"{name} ({data['default']}): {data['description']}\n"
else:
@@ -97,6 +107,7 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
self.outputs["file"].sv_set([ifcopenshell.api.run(usecase, **settings)])
def register():
bpy.utils.register_class(SvIfcTooltip)
bpy.utils.register_class(SvIfcApi)
@@ -104,4 +115,4 @@ def register():
def unregister():
bpy.utils.unregister_class(SvIfcApi)
bpy.utils.unregister_class(SvIfcTooltip)
bpy.utils.unregister_class(SvIfcTooltip)
+118
View File
@@ -0,0 +1,118 @@
# IfcSverchok - IFC Sverchok extension
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
# 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 ifcopenshell
import ifcopenshell.api
import ifcsverchok.helper
from bpy.props import StringProperty, EnumProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
import importlib
class SvIfcTooltip(bpy.types.Operator):
bl_idname = "node.sv_ifc_tooltip"
bl_label = "IFC Info"
tooltip: bpy.props.StringProperty()
@classmethod
def description(cls, context, properties):
return properties.tooltip
def execute(self, context):
return {"FINISHED"}
class SvIfcApiWIP(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
def update_usecase(self, context):
# update is not getting run rn
try:
module_usecase = self.get_module_usecase()
#if module_usecase:
self.generate_node(*module_usecase)
except:
raise Exception(
f"Couldn't run generate_node(). Module usecase: {module_usecase}"
)
bl_idname = "SvIfcApiWIP"
bl_label = "IFC API WIP"
tooltip: StringProperty(name="Tooltip")
usecase: StringProperty(update=updateNode)
def sv_init(self, context):
input_socket = self.inputs.new("SvStringsSocket", "usecase").use_prop = True
# input_socket.tooltip = "ifcopenshell.api usecase, written like 'module.usecase' \n E.g.: 'project.create_file'"
self.outputs.new("SvVerticesSocket", "file")
def draw_buttons(self, context, layout):
op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False)
op.tooltip = self.tooltip
def process(self):
print("process")
module_usecase = self.get_module_usecase()
if module_usecase:
self.generate_node(*module_usecase) # does this actually add to 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
self.process()
def get_module_usecase(self):
usecase = self.inputs["usecase"].sv_get()[0][0]
if usecase:
return usecase.split(".")
def generate_node(self, module, usecase):
importlib.import_module(f"ifcopenshell.api.{module}.{usecase}")
init_func = getattr(getattr(ifcopenshell.api, module), usecase).Usecase.__init__
if "settings" in init_func.__code__.co_varnames:
args = list(init_func.__code__.co_consts[3])
args.insert(0, 'file')
else:
args = ['file']
while len(self.inputs) > 1:
self.inputs.remove(self.inputs[-1])
for name in args:
print("name type", type(name))
setattr(SvIfcApiWIP, str(name), StringProperty(name=str(name), update=updateNode))
self.inputs.new("SvStringsSocket", str(name)).use_prop = True
def process_ifc(self, usecase, *setting_values):
if usecase:
settings = dict(zip(self.sv_input_names[1:], setting_values))
settings = {k: v for k, v in settings.items() if v != ""}
self.outputs["file"].sv_set([ifcopenshell.api.run(usecase, **settings)])
def register():
bpy.utils.register_class(SvIfcTooltip)
bpy.utils.register_class(SvIfcApiWIP)
def unregister():
bpy.utils.unregister_class(SvIfcApiWIP)
bpy.utils.unregister_class(SvIfcTooltip)
+104
View File
@@ -0,0 +1,104 @@
# IfcSverchok - IFC Sverchok extension
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
# 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 ifcopenshell
import ifcsverchok.helper
import ifcopenshell.api
import blenderbim.tool as tool
import blenderbim.core.geometry as core
from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
from blenderbim.bim.module.root.prop import get_contexts
class SvIfcBMeshToIfcGeo(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
"""
Triggers: BMesh to Ifc Geo
Tooltip: Blender mesh to Ifc Geometric Representation
"""
bl_idname = "SvIfcBMeshToIfcGeo"
bl_label = "IFC Blender Mesh to IFC Geo"
tooltip: StringProperty(name="Tooltip")
context_id: bpy.props.IntProperty()
def sv_init(self, context):
input_socket = self.inputs.new("SvStringsSocket", "file")
input_socket.tooltip = "ifc file to add the geometry to"
input_socket = self.inputs.new("SvObjectSocket", "blender_object")
input_socket.tooltip = "Pick or pass Blender Mesh object"
input_socket = self.inputs.new("SvStringsSocket", "ifc_representation_class")
input_socket.tooltip = "Whether to cast a mesh into a particular class"
self.outputs.new("SvVerticesSocket", "file")
self.outputs.new("SvVerticesSocket", "representation")
def draw_buttons(self, context, layout):
op = layout.operator("node.sv_ifc_tooltip", text="", icon="QUESTION", emboss=False).tooltip = "Description?"
#op.tooltip = self.tooltip
def process(self):
print("Running process...")
# file
file = self.inputs["file"].sv_get()[0][0]
# blender mesh
blender_object = self.inputs["blender_object"].sv_get()[0]
print("blender object: ", blender_object)
#geometry
geometry = blender_object.data
print("geometry: ", geometry)
#run process_ifc
self.process_ifc(file, blender_object, geometry)
def process_ifc(self, file, blender_object, geometry):
#get context
try:
for context in file.by_type("IFCGEOMETRICREPRESENTATIONCONTEXT", include_subtypes=True):
if context.get_info()["ContextType"] == "Model" and context.get_info()["ContextIdentifier"] == "Body":
repr_context= context
print("pop", context)
elif context.get_info()["ContextType"] == "Model":
repr_context= context
except:
raise Exception(
"Ifc Geometric Representation Context is missing."
)
representation = [ifcopenshell.api.run("geometry.add_representation", file, should_run_listeners=False,blender_object = blender_object, geometry=geometry, context = repr_context)]
print("representation: ", representation)
try:
self.outputs["file"].sv_set([[file]])
self.outputs["representation"].sv_set([representation])
except:
raise Exception(
"Couldn't write to file. Representation: {}".format(
representation
)
)
def register():
bpy.utils.register_class(SvIfcBMeshToIfcGeo)
def unregister():
bpy.utils.unregister_class(SvIfcBMeshToIfcGeo)
+1 -1
View File
@@ -115,4 +115,4 @@ def register():
def unregister():
bpy.utils.unregister_class(SvIfcByType)
bpy.utils.unregister_class(SvIfcByType)
+9 -3
View File
@@ -54,16 +54,17 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
self.generate_inputs(ifc_class)
try:
for i in range(0, len(self.inputs)):
self.inputs[i].sv_get()
input = self.inputs[i].sv_get()
except:
# This occurs when a blender save file is reloaded
self.generate_inputs(ifc_class)
for i in range(0, self.entity_schema.attribute_count()):
self.sv_input_names.append(self.entity_schema.attribute_by_index(i).name())
super().process()
self.process()
def generate_inputs(self, ifc_class):
# print("generate_inputs...")
while len(self.inputs) > 2:
self.inputs.remove(self.inputs[-1])
for i in range(0, self.entity_schema.attribute_count()):
@@ -77,12 +78,16 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
for i in range(0, len(entity)):
try:
value = attributes[i]
# print("value (attribute[i]): ", value, "|value type: ", type(value))
if isinstance(value, str) and value == "":
value = None
except:
value = None
if value is None and entity.is_a("IfcRoot") and i == 0:
value = ifcopenshell.guid.new()
if value is not None and entity.attribute_name(i) == "Representation":
value = file.createIfcProductDefinitionShape(None, None, Representations = [value])
#product_shape = ifcopenshell.api.run("geometry.assign_representation", file, product = , representation = value)
if value is not None:
value = self.cast_value(self.entity_schema.attribute_by_index(i), value)
try:
@@ -93,6 +98,7 @@ class SvIfcCreateEntity(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper
ifc_class, entity.attribute_name(i), value
)
)
self.outputs["file"].sv_set([[file]])
self.outputs["entity"].sv_set([[entity]])
-1
View File
@@ -1,4 +1,3 @@
# IfcSverchok - IFC Sverchok extension
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
@@ -0,0 +1,80 @@
# IfcSverchok - IFC Sverchok extension
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
# 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 ifcopenshell
import ifcsverchok.helper
from bpy.props import StringProperty
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):
bl_idname = "SvIfcCreateProject"
bl_label = "IFC Create Project"
def sv_init(self, context):
input_socket = self.inputs.new("SvStringsSocket", "file")
input_socket.tooltip = "ifc file to add the project to"
input_socket = self.inputs.new("SvStringsSocket", "project_name")
input_socket.tooltip = "Project name"
self.outputs.new("SvVerticesSocket", "file")
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.tooltip = self.tooltip
def process(self):
#file
file = self.inputs["file"].sv_get()[0][0]
if file:
schema_name = file.wrapped_data.schema
else:
schema_name = "IFC4"
#project name
project_name = self.inputs["project_name"].sv_get()[0][0]
print("project name:", project_name)
self.process_ifc(file, project_name)
def process_ifc(self, file, project_name):
# create project
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")
ifcopenshell.api.run("unit.assign_unit", file, units=[lengthunit])
model = ifcopenshell.api.run("context.add_context", file, context_type="Model")
context = ifcopenshell.api.run(
"context.add_context",
file,
context_type="Model",
context_identifier="Body",
target_view="MODEL_VIEW",
parent=model,
)
self.outputs["file"].sv_set([[file]])
def register():
bpy.utils.register_class(SvIfcCreateProject)
def unregister():
bpy.utils.unregister_class(SvIfcCreateProject)
+16
View File
@@ -26,6 +26,8 @@ from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
from sverchok.data_structure import zip_long_repeat
class SvIfcCreateShapeRefresh(bpy.types.Operator):
bl_idname = "node.sv_ifc_create_shape_refresh"
@@ -57,8 +59,22 @@ class SvIfcCreateShape(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.
def process(self):
self.sv_input_names = ["file", "entity"]
super().process()
def process_helper(self):
print("Hello from helper")
sv_inputs_nested = []
for name in self.sv_input_names:
sv_inputs_nested.append(self.inputs[name].sv_get())
print(24*"#","\n", "sv_input: ", self.inputs[name].sv_get(), "input type: ", type(self.inputs[name].sv_get()), "\n", "#"*24)
for sv_input_nested in zip_long_repeat(*sv_inputs_nested):
for sv_input in zip_long_repeat(*sv_input_nested):
sv_input = list(sv_input)
print(24*"#","\n", "sv_input post zip_long_repeat: ", sv_input, "input type: ", type(sv_input), "\n", "#"*24)
self.process_ifc(*sv_input)
def process_ifc(self, file, entity):
print("process ifc...")
print("entity: ", entity)
try:
if not entity.is_a("IfcProduct"):
return
@@ -0,0 +1,96 @@
# IfcSverchok - IFC Sverchok extension
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
# 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/>.
from email.mime import application
import bpy
import ifcopenshell
import ifcsverchok.helper
from bpy.props import StringProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
from ifcopenshell import template
class SvIfcQuickProjectSetup(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
bl_idname = "SvIfcQuickProjectSetup"
bl_label = "IFC Quick Project Setup"
schema_identifier: StringProperty(name="schema_identifier", update=updateNode, default="IFC4")
timestring: StringProperty(name="timestring", update=updateNode)
application: StringProperty(name="application", update=updateNode)
application_version: StringProperty(name="application_version", update=updateNode)
timestamp: StringProperty(name="timestamp", update=updateNode)
def sv_init(self, context):
input_socket = self.inputs.new("SvStringsSocket", "filename")
input_socket.tooltip = "Ifc file name"
input_socket = self.inputs.new("SvStringsSocket", "timestring")
input_socket.tooltip = "Timestring, default = current time"
input_socket = self.inputs.new("SvStringsSocket", "organization")
input_socket.tooltip = "Organization"
input_socket = self.inputs.new("SvStringsSocket", "creator")
input_socket.tooltip = "creator"
input_socket = self.inputs.new("SvStringsSocket", "schema_identifier")
input_socket.tooltip = "Schema, default = 'IFC4'"
input_socket = self.inputs.new("SvStringsSocket", "application_version")
input_socket.tooltip = "Application version"
input_socket = self.inputs.new("SvStringsSocket", "timestamp")
input_socket.tooltip = "Timestamp, default = current time"
input_socket = self.inputs.new("SvStringsSocket", "application")
input_socket.tooltip = "Application, default = 'IfcOpenShell'"
input_socket = self.inputs.new("SvStringsSocket", "project_globalid")
input_socket.tooltip = "Project GlobalId"
input_socket = self.inputs.new("SvStringsSocket", "project_name")
input_socket.tooltip = "Project name"
self.outputs.new("SvVerticesSocket", "file")
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.tooltip = self.tooltip
def process(self):
self.sv_input_names = [i.name for i in self.inputs]
print("inputnames: ", self.sv_input_names)
super().process()
def process_ifc(self, *setting_values):
print("setting values: ", setting_values)
settings = dict(zip(self.sv_input_names, setting_values))
print("settings: ", settings)
settings = {k: v for k, v in settings.items() if v != ""}
file = template.create(
filename=settings['filename'],
timestring=settings['timestring'],
organization=settings['organization'],
creator=settings['creator'],
schema_identifier=settings['schema_identifier'],
application_version=settings['application_version'],
timestamp=settings['timestamp'],
application=settings['application'],
project_globalid=settings['project_globalid'],
project_name=settings['project_name'],
)
self.outputs["file"].sv_set([[file]])
def register():
bpy.utils.register_class(SvIfcQuickProjectSetup)
def unregister():
bpy.utils.unregister_class(SvIfcQuickProjectSetup)