mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 14:22:33 +00:00
Merge branch 'v0.7.0' into linked_aggregate_operator_from_panel
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import bpy
|
||||
import json
|
||||
@@ -36,6 +37,7 @@ import blenderbim.core.style
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from mathutils import Vector
|
||||
from typing import Union
|
||||
from logging import Logger
|
||||
|
||||
|
||||
class IfcExporter:
|
||||
@@ -163,10 +165,10 @@ class IfcExporter:
|
||||
bpy.ops.bim.update_representation(obj=obj.name)
|
||||
tool.Geometry.record_object_position(obj)
|
||||
|
||||
def get_application_name(self):
|
||||
def get_application_name(self) -> str:
|
||||
return "BlenderBIM"
|
||||
|
||||
def get_application_version(self):
|
||||
def get_application_version(self) -> str:
|
||||
version = ".".join(
|
||||
[
|
||||
str(x)
|
||||
@@ -184,11 +186,13 @@ class IfcExporter:
|
||||
|
||||
class IfcExportSettings:
|
||||
def __init__(self):
|
||||
self.logger = None
|
||||
self.output_file = None
|
||||
self.logger: Logger = None
|
||||
self.output_file: str = None
|
||||
self.json_version: str = None
|
||||
self.json_compact: bool = None
|
||||
|
||||
@staticmethod
|
||||
def factory(context, output_file, logger):
|
||||
def factory(context: bpy.types.Context, output_file: str, logger: Logger) -> IfcExportSettings:
|
||||
settings = IfcExportSettings()
|
||||
settings.output_file = output_file
|
||||
settings.logger = logger
|
||||
|
||||
@@ -299,6 +299,7 @@ class IfcImporter:
|
||||
if self.ifc_import_settings.should_setup_viewport_camera:
|
||||
self.setup_viewport_camera()
|
||||
self.setup_arrays()
|
||||
self.profile_code("Setup arrays")
|
||||
self.update_progress(100)
|
||||
bpy.context.window_manager.progress_end()
|
||||
|
||||
@@ -602,6 +603,9 @@ class IfcImporter:
|
||||
return products
|
||||
|
||||
def predict_dense_mesh(self):
|
||||
if self.ifc_import_settings.should_use_native_meshes:
|
||||
return
|
||||
|
||||
threshold = 10000 # Just from experience.
|
||||
|
||||
faces = [len(e.CfsFaces) for e in self.file.by_type("IfcClosedShell")]
|
||||
@@ -1494,7 +1498,11 @@ class IfcImporter:
|
||||
# Occurs when reloading a project
|
||||
pass
|
||||
project_collection = bpy.context.view_layer.layer_collection.children[self.project["blender"].name]
|
||||
project_collection.children[self.type_collection.name].hide_viewport = True
|
||||
types_collection = project_collection.children[self.type_collection.name]
|
||||
types_collection.hide_viewport = False
|
||||
for obj in types_collection.collection.objects: #turn off all objects inside Types collection.
|
||||
obj.hide_set(True)
|
||||
|
||||
|
||||
def clean_mesh(self):
|
||||
obj = None
|
||||
@@ -2041,7 +2049,7 @@ class IfcImporter:
|
||||
|
||||
class IfcImportSettings:
|
||||
def __init__(self):
|
||||
self.logger = None
|
||||
self.logger: logging.Logger = None
|
||||
self.input_file = None
|
||||
self.diff_file = None
|
||||
self.should_use_cpu_multiprocessing = True
|
||||
|
||||
@@ -209,6 +209,10 @@ class DisableEditingClassification(bpy.types.Operator):
|
||||
class RemoveClassification(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.remove_classification"
|
||||
bl_label = "Remove Classification"
|
||||
bl_description = (
|
||||
"The classification and all of its relationships, children references, "
|
||||
"and relationships between objects and child references will be completely removed from a project"
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
classification: bpy.props.IntProperty()
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@ class AddContext(bpy.types.Operator, Operator):
|
||||
class RemoveContext(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.remove_context"
|
||||
bl_label = "Remove Context"
|
||||
bl_description = (
|
||||
"Remove representation context. Any representation geometry that is assigned to the context is also removed. "
|
||||
"If a context is removed, then any subcontexts are also removed"
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
context: bpy.props.IntProperty()
|
||||
|
||||
|
||||
@@ -246,6 +246,7 @@ class ExportIfcCsv(bpy.types.Operator):
|
||||
if props.format != "csv" and props.should_generate_svg:
|
||||
schedule_creator = scheduler.Scheduler()
|
||||
schedule_creator.schedule(self.filepath, tool.Drawing.get_path_with_ext(self.filepath, "svg"))
|
||||
self.report({"INFO"}, f"Data is exported to {props.format.upper()}.")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -285,6 +286,7 @@ class ImportIfcCsv(bpy.types.Operator):
|
||||
if not props.should_load_from_memory:
|
||||
ifc_file.write(props.csv_ifc_file)
|
||||
refresh_ui_data()
|
||||
self.report({"INFO"}, "Data is imported to IFC.")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ classes = (
|
||||
operator.PrintUnusedElementStats,
|
||||
operator.ProfileImportIFC,
|
||||
operator.PurgeHdf5Cache,
|
||||
operator.PurgeIfcLinks,
|
||||
operator.PurgeUnusedElementsByClass,
|
||||
operator.RewindInspector,
|
||||
operator.SelectExpressFile,
|
||||
|
||||
@@ -104,10 +104,11 @@ class PrintIfcFile(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PurgeIfcLinks(bpy.types.Operator):
|
||||
bl_idname = "bim.purge_ifc_links"
|
||||
bl_label = "Purge IFC Links"
|
||||
bl_description = "Purge all definitions and references from the file.\nWarning : Cannot be undone."
|
||||
class ConvertToBlender(bpy.types.Operator):
|
||||
bl_idname = "bim.convert_to_blender"
|
||||
bl_label = "Convert To Blender File"
|
||||
bl_description = "Removes all IFC data and revert to basic Blender objects.\nWarning : Cannot be undone."
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
for obj in bpy.data.objects:
|
||||
@@ -124,26 +125,6 @@ class PurgeIfcLinks(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ConvertToBlender(bpy.types.Operator):
|
||||
bl_idname = "bim.convert_to_blender"
|
||||
bl_label = "Convert To Blender File"
|
||||
bl_description = "Removes all IFC data, and converts the file to a simple Blender file."
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
for o in bpy.data.objects:
|
||||
if o.type in {"MESH", "EMPTY"}:
|
||||
o.BIMObjectProperties.ifc_definition_id = 0
|
||||
if o.data:
|
||||
o.data.BIMMeshProperties.ifc_definition_id = 0
|
||||
for m in bpy.data.materials:
|
||||
m.BIMMaterialProperties.ifc_style_id = False
|
||||
bpy.context.scene.BIMProperties.ifc_file = ""
|
||||
IfcStore.purge()
|
||||
blenderbim.bim.handler.refresh_ui_data()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ValidateIfcFile(bpy.types.Operator):
|
||||
bl_idname = "bim.validate_ifc_file"
|
||||
bl_label = "Validate IFC File"
|
||||
|
||||
@@ -60,9 +60,6 @@ class BIM_PT_debug(Panel):
|
||||
row = layout.row()
|
||||
row.operator("bim.purge_hdf5_cache")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("bim.purge_ifc_links")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("bim.update_representation", text="Manually Save Representation")
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import subprocess
|
||||
import numpy as np
|
||||
import multiprocessing
|
||||
import ifcopenshell
|
||||
import ifcopenshell.ifcopenshell_wrapper
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.util.selector
|
||||
import ifcopenshell.util.representation
|
||||
@@ -219,11 +220,12 @@ class CreateDrawing(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
self.props = context.scene.DocProperties
|
||||
|
||||
active_drawing_id = context.scene.camera.BIMObjectProperties.ifc_definition_id
|
||||
if self.print_all:
|
||||
original_drawing_id = self.props.active_drawing_id
|
||||
original_drawing_id = active_drawing_id
|
||||
drawings_to_print = [d.ifc_definition_id for d in self.props.drawings if d.is_selected and d.is_drawing]
|
||||
else:
|
||||
drawings_to_print = [self.props.active_drawing_id]
|
||||
drawings_to_print = [active_drawing_id]
|
||||
|
||||
for drawing_i, drawing_id in enumerate(drawings_to_print):
|
||||
self.drawing_index = drawing_i
|
||||
@@ -1451,13 +1453,19 @@ class ActivateModel(bpy.types.Operator):
|
||||
|
||||
CutDecorator.uninstall()
|
||||
|
||||
# save current visibility statuses for Views and Types collections
|
||||
visibility_status: dict[bpy.types.Object, bool] = {}
|
||||
for col in bpy.data.collections["Views"].children:
|
||||
for obj in col.objects:
|
||||
visibility_status[obj] = obj.hide_get()
|
||||
for obj in bpy.data.collections["Types"].objects:
|
||||
visibility_status[obj] = obj.hide_get()
|
||||
|
||||
if not bpy.app.background:
|
||||
with context.temp_override(**tool.Blender.get_viewport_context()):
|
||||
bpy.ops.object.hide_view_clear()
|
||||
bpy.ops.bim.activate_status_filters()
|
||||
|
||||
subcontext = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
||||
|
||||
for obj in context.visible_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
@@ -1475,6 +1483,11 @@ class ActivateModel(bpy.types.Operator):
|
||||
is_global=True,
|
||||
should_sync_changes_first=True,
|
||||
)
|
||||
|
||||
# restore visibility after hide_view_clear()
|
||||
for obj, hide_status in visibility_status.items():
|
||||
obj.hide_set(hide_status)
|
||||
|
||||
tool.Blender.update_viewport()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -719,7 +719,7 @@ class SvgWriter:
|
||||
self.svg.text(sheet_id, insert=(text_position[0], text_position[1] + 2.5), class_="ELEVATION", **text_style)
|
||||
)
|
||||
|
||||
def get_reference_and_sheet_id_from_annotation(self, element):
|
||||
def get_reference_and_sheet_id_from_annotation(self, element: ifcopenshell.entity_instance) -> tuple[str, str]:
|
||||
reference_id = "-"
|
||||
sheet_id = "-"
|
||||
drawing = tool.Drawing.get_annotation_element(element)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.element
|
||||
import blenderbim.tool as tool
|
||||
import ifcopenshell.util.placement
|
||||
from mathutils import Vector
|
||||
@@ -222,7 +223,7 @@ class ConnectionsData:
|
||||
@classmethod
|
||||
def is_connection_realization(cls):
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
connections = element.IsConnectionRealization
|
||||
connections = getattr(element, "IsConnectionRealization", None)
|
||||
if not connections:
|
||||
return
|
||||
|
||||
|
||||
@@ -215,6 +215,13 @@ class SwitchRepresentation(bpy.types.Operator, Operator):
|
||||
disable_opening_subtractions: bpy.props.BoolProperty()
|
||||
should_switch_all_meshes: bpy.props.BoolProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if context.active_object.mode == "OBJECT":
|
||||
return True
|
||||
cls.poll_message_set("Only available in OBJECT mode - Press TAB in the viewport")
|
||||
return False
|
||||
|
||||
def _execute(self, context):
|
||||
target_representation = tool.Ifc.get().by_id(self.ifc_definition_id)
|
||||
target = target_representation.ContextOfItems
|
||||
@@ -223,6 +230,8 @@ class SwitchRepresentation(bpy.types.Operator, Operator):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
continue
|
||||
if not obj.mode == "OBJECT":
|
||||
continue
|
||||
if obj == context.active_object:
|
||||
representation = target_representation
|
||||
else:
|
||||
@@ -538,6 +547,8 @@ class OverrideDelete(bpy.types.Operator):
|
||||
row.prop(self, "is_batch", text="Enable Faster Deletion")
|
||||
|
||||
def _execute(self, context):
|
||||
start_time = time()
|
||||
|
||||
if self.is_batch:
|
||||
ifcopenshell.util.element.batch_remove_deep2(tool.Ifc.get())
|
||||
|
||||
@@ -562,6 +573,11 @@ class OverrideDelete(bpy.types.Operator):
|
||||
IfcStore.add_transaction_operation(self)
|
||||
# Required otherwise gizmos are still visible
|
||||
context.view_layer.objects.active = None
|
||||
|
||||
operator_time = time() - start_time
|
||||
if operator_time > 10:
|
||||
self.report({"INFO"}, "IFC Delete was finished in {:.2f} seconds".format(operator_time))
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
def rollback(self, data):
|
||||
@@ -902,7 +918,7 @@ class OverrideDuplicateMove(bpy.types.Operator):
|
||||
if pset:
|
||||
pset = tool.Ifc.get().by_id(pset["id"])
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), pset=pset)
|
||||
|
||||
|
||||
if new[0].is_a("IfcElementAssembly"):
|
||||
linked_aggregate_group = [
|
||||
r.RelatingGroup
|
||||
@@ -910,7 +926,7 @@ class OverrideDuplicateMove(bpy.types.Operator):
|
||||
if r.is_a("IfcRelAssignsToGroup")
|
||||
if "BBIM_Linked_Aggregate" in r.RelatingGroup.Name
|
||||
]
|
||||
tool.Ifc.run("group.unassign_group", group=linked_aggregate_group[0], product=new[0])
|
||||
tool.Ifc.run("group.unassign_group", group=linked_aggregate_group[0], products=[new[0]])
|
||||
|
||||
|
||||
class OverrideDuplicateMoveLinkedMacro(bpy.types.Macro):
|
||||
@@ -980,7 +996,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
|
||||
else:
|
||||
index = add_linked_aggregate_pset(part, index)
|
||||
# index += 1
|
||||
|
||||
|
||||
obj = tool.Ifc.get_object(part)
|
||||
obj.select_set(True)
|
||||
|
||||
@@ -1014,9 +1030,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
|
||||
return
|
||||
|
||||
linked_aggregate_group = ifcopenshell.api.run("group.add_group", tool.Ifc.get(), Name=self.group_name)
|
||||
ifcopenshell.api.run(
|
||||
"group.assign_group", tool.Ifc.get(), products=[element], group=linked_aggregate_group
|
||||
)
|
||||
ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=[element], group=linked_aggregate_group)
|
||||
|
||||
def custom_incremental_naming_for_element_assembly(old_to_new):
|
||||
for new in old_to_new.values():
|
||||
@@ -1040,10 +1054,10 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
|
||||
if re.findall(pattern2, new_obj.name):
|
||||
split_name = new_obj.name.split(".")
|
||||
new_obj.name = split_name[0] + "_" + number
|
||||
|
||||
|
||||
def get_max_index(parts):
|
||||
psets = [ifcopenshell.util.element.get_pset(p, "BBIM_Linked_Aggregate") for p in parts]
|
||||
index = [i['Index'] for i in psets if i]
|
||||
index = [i["Index"] for i in psets if i]
|
||||
if len(index) > 0:
|
||||
index = max(index)
|
||||
return index
|
||||
@@ -1057,14 +1071,14 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
|
||||
new_pset = ifcopenshell.api.run(
|
||||
"pset.add_pset", tool.Ifc.get(), product=new[0], name=self.pset_name
|
||||
)
|
||||
|
||||
|
||||
ifcopenshell.api.run(
|
||||
"pset.edit_pset",
|
||||
tool.Ifc.get(),
|
||||
pset=new_pset,
|
||||
properties={"Index": pset["Index"]},
|
||||
)
|
||||
|
||||
|
||||
if new[0].is_a("IfcElementAssembly"):
|
||||
linked_aggregate_group = [
|
||||
r.RelatingGroup
|
||||
@@ -1083,6 +1097,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
|
||||
location_diff = new_obj.location - base_obj_location
|
||||
new_obj.location = context.scene.cursor.location + location_diff
|
||||
|
||||
|
||||
if len(context.selected_objects) != 1:
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -1102,7 +1117,7 @@ class DuplicateMoveLinkedAggregate(bpy.types.Operator):
|
||||
select_objects_and_add_data(selected_element)
|
||||
|
||||
old_to_new = OverrideDuplicateMove.execute_ifc_duplicate_operator(self, context, linked=True)
|
||||
|
||||
|
||||
tool.Root.recreate_aggregate(old_to_new)
|
||||
|
||||
copy_linked_aggregate_data(old_to_new)
|
||||
@@ -1269,9 +1284,9 @@ class RefreshLinkedAggregate(bpy.types.Operator):
|
||||
selected_matrix = selected_obj.matrix_world
|
||||
object_duplicate = tool.Ifc.get_object(element)
|
||||
duplicate_matrix = object_duplicate.matrix_world.decompose()
|
||||
|
||||
|
||||
return selected_matrix, duplicate_matrix
|
||||
|
||||
|
||||
def set_new_matrix(selected_matrix, duplicate_matrix, old_to_new):
|
||||
for old, new in old_to_new.items():
|
||||
new_obj = tool.Ifc.get_object(new[0])
|
||||
@@ -1279,7 +1294,6 @@ class RefreshLinkedAggregate(bpy.types.Operator):
|
||||
matrix_diff = Matrix.inverted(selected_matrix) @ new_obj.matrix_world
|
||||
new_obj_matrix = new_base_matrix @ matrix_diff
|
||||
new_obj.matrix_world = new_obj_matrix
|
||||
|
||||
|
||||
active_element = tool.Ifc.get_entity(context.active_object)
|
||||
if not active_element:
|
||||
@@ -1465,14 +1479,13 @@ class OverridePasteBuffer(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.view3d.pastebuffer()
|
||||
if IfcStore.get_file():
|
||||
for obj in context.selected_objects:
|
||||
# Pasted objects may come from another Blender session, or even
|
||||
# from the same session where the original object has since
|
||||
# been deleted. As the source element may not exist, paste will
|
||||
# always unlink the element. If you want to duplicate an
|
||||
# element, use the duplicate commands.
|
||||
tool.Root.unlink_object(obj)
|
||||
for obj in context.selected_objects:
|
||||
# Pasted objects may come from another Blender session, or even
|
||||
# from the same session where the original object has since
|
||||
# been deleted. As the source element may not exist, paste will
|
||||
# always unlink the element. If you want to duplicate an
|
||||
# element, use the duplicate commands.
|
||||
tool.Root.unlink_object(obj)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import os
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.doc
|
||||
import ifcopenshell.util.schema
|
||||
import blenderbim.tool as tool
|
||||
@@ -166,6 +167,9 @@ class ObjectMaterialData:
|
||||
cls.data["type_material"] = cls.type_material()
|
||||
cls.data["material_type"] = cls.material_type()
|
||||
cls.data["active_material_constituents"] = cls.active_material_constituents()
|
||||
# after material_name and type_material
|
||||
cls.data["is_type_material_overridden"] = cls.is_type_material_overridden()
|
||||
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
@@ -294,8 +298,7 @@ class ObjectMaterialData:
|
||||
|
||||
@classmethod
|
||||
def material_name(cls):
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
material = ifcopenshell.util.element.get_material(element)
|
||||
material = cls.material
|
||||
if material:
|
||||
return getattr(material, "Name", None) or "Unnamed"
|
||||
|
||||
@@ -339,3 +342,18 @@ class ObjectMaterialData:
|
||||
if not cls.material or not material.is_a("IfcMaterialConstituentSet"):
|
||||
return []
|
||||
return [m.Name for m in material.MaterialConstituents if m.Name]
|
||||
|
||||
@classmethod
|
||||
def is_type_material_overridden(cls) -> bool:
|
||||
if not cls.data["type_material"]:
|
||||
return False
|
||||
|
||||
# try to avoid accessing ifc
|
||||
if cls.data["material_name"] != cls.data["type_material"]:
|
||||
return True
|
||||
|
||||
# in theory material can be overridden by the same material
|
||||
# so we check occurrence material explicitly
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
occurrence_material = ifcopenshell.util.element.get_material(element, should_inherit=False)
|
||||
return bool(occurrence_material)
|
||||
|
||||
@@ -177,7 +177,13 @@ class BIM_PT_object_material(Panel):
|
||||
|
||||
if ObjectMaterialData.data["type_material"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Inherited Material: " + ObjectMaterialData.data["type_material"], icon="CON_CHILDOF")
|
||||
if ObjectMaterialData.data["is_type_material_overridden"]:
|
||||
row.label(
|
||||
text=f"Inherited Material Is Occurrence Overridden",
|
||||
icon="CON_CHILDOF",
|
||||
)
|
||||
else:
|
||||
row.label(text="Inherited Material: " + ObjectMaterialData.data["type_material"], icon="CON_CHILDOF")
|
||||
|
||||
if ObjectMaterialData.data["material_class"]:
|
||||
return self.draw_material_ui()
|
||||
|
||||
@@ -39,6 +39,7 @@ from mathutils import Vector, Matrix
|
||||
from bpy_extras.object_utils import AddObjectHelper
|
||||
from . import prop
|
||||
import json
|
||||
from typing import Any, Union
|
||||
|
||||
|
||||
class EnableAddType(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -511,7 +512,7 @@ def regenerate_profile_usage(usecase_path, ifc_file, settings):
|
||||
)
|
||||
|
||||
|
||||
def ensure_material_assigned(usecase_path, ifc_file, settings):
|
||||
def ensure_material_assigned(usecase_path: str, ifc_file: ifcopenshell.file, settings: dict[str, Any]) -> None:
|
||||
if usecase_path == "material.assign_material":
|
||||
if not settings.get("material", None):
|
||||
return
|
||||
@@ -524,53 +525,76 @@ def ensure_material_assigned(usecase_path, ifc_file, settings):
|
||||
]:
|
||||
elements.extend(rel.RelatedObjects)
|
||||
|
||||
for element in elements:
|
||||
obj = IfcStore.get_element(element.GlobalId)
|
||||
if not obj or not obj.data:
|
||||
continue
|
||||
|
||||
element_material = ifcopenshell.util.element.get_material(element)
|
||||
material = [m for m in ifc_file.traverse(element_material) if m.is_a("IfcMaterial")]
|
||||
|
||||
object_material_ids = [
|
||||
om.BIMObjectProperties.ifc_definition_id
|
||||
for om in obj.data.materials
|
||||
if om is not None and om.BIMObjectProperties.ifc_definition_id
|
||||
]
|
||||
|
||||
if material and material[0].id() in object_material_ids:
|
||||
continue
|
||||
|
||||
if len(obj.data.materials) == 1:
|
||||
obj.data.materials.clear()
|
||||
|
||||
if not material:
|
||||
continue
|
||||
|
||||
obj.data.materials.append(IfcStore.get_element(material[0].id()))
|
||||
update_blender_ifc_materials(elements)
|
||||
|
||||
|
||||
def ensure_material_unassigned(usecase_path, ifc_file, settings):
|
||||
def ensure_material_unassigned(usecase_path: str, ifc_file: ifcopenshell.file, settings: dict[str, Any]) -> None:
|
||||
elements = settings["products"]
|
||||
if elements[0].is_a("IfcElementType"):
|
||||
elements.extend(ifcopenshell.util.element.get_types(elements[0]))
|
||||
update_blender_ifc_materials(elements)
|
||||
|
||||
|
||||
def update_blender_ifc_materials(elements: list[ifcopenshell.entity_instance]) -> None:
|
||||
"""update mesh blender materials that have ifc material connected to them
|
||||
by replacing them with `blender_material`"""
|
||||
# since different elements can share meshes (e.g. occurrecnes without openings)
|
||||
# we need to make sure not to affect them accidentally
|
||||
meshes_users: dict[bpy.types.Mesh, set[bpy.types.Object]] = dict()
|
||||
for obj in bpy.data.objects:
|
||||
if not obj.data:
|
||||
continue
|
||||
meshes_users.setdefault(obj.data, set()).add(obj)
|
||||
|
||||
objects: set[bpy.types.Object] = set()
|
||||
for element in elements:
|
||||
obj = tool.Ifc.get_object(element)
|
||||
obj: bpy.types.Object = tool.Ifc.get_object(element)
|
||||
if not obj or not obj.data:
|
||||
continue
|
||||
element_material = ifcopenshell.util.element.get_material(element)
|
||||
if element_material:
|
||||
objects.add(obj)
|
||||
|
||||
meshes: set[bpy.types.Mesh] = {obj.data for obj in objects}
|
||||
|
||||
for mesh in meshes:
|
||||
mesh_users = meshes_users[mesh]
|
||||
if not mesh_users.issubset(objects):
|
||||
continue
|
||||
to_remove = []
|
||||
for i, slot in enumerate(obj.material_slots):
|
||||
if not slot.material:
|
||||
|
||||
# NOTE: we need `obj` as removing materials and appending them to `mesh.materials`
|
||||
# will mess up mesh faces material indices
|
||||
|
||||
# NOTE: we make an assumption here that all mesh users
|
||||
# have the same material - they either inherit it from the type
|
||||
# or type doesn't have a material.
|
||||
#
|
||||
# If we add option to UI to add materials overriding type materials
|
||||
# then this assumption won't be safe anymore
|
||||
|
||||
obj = next(iter(mesh_users))
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
current_material = ifcopenshell.util.element.get_material(element)
|
||||
if current_material:
|
||||
current_material = tool.Ifc.get_object(current_material)
|
||||
|
||||
material_replaced = False
|
||||
|
||||
for material_slot in obj.material_slots:
|
||||
material = material_slot.material
|
||||
if material is None:
|
||||
continue
|
||||
material = tool.Ifc.get_entity(slot.material)
|
||||
if material:
|
||||
to_remove.append(i)
|
||||
total_removed = 0
|
||||
for i in to_remove:
|
||||
obj.active_material_index = i - total_removed
|
||||
with bpy.context.temp_override(object=obj):
|
||||
bpy.ops.object.material_slot_remove()
|
||||
total_removed += 1
|
||||
ifc_material = tool.Ifc.get_entity(material)
|
||||
# it's blender material for style, so ignore it
|
||||
if not ifc_material:
|
||||
continue
|
||||
if ifc_material == current_material:
|
||||
continue
|
||||
material_slot.material = current_material
|
||||
material_replaced = True
|
||||
|
||||
if not material_replaced and current_material:
|
||||
mesh.materials.append(current_material)
|
||||
|
||||
# clear empty slots
|
||||
for i, material in reversed(list(enumerate(mesh.materials[:]))):
|
||||
if material is None:
|
||||
mesh.materials.pop(index=i)
|
||||
|
||||
@@ -56,8 +56,11 @@ class LaunchTypeManager(bpy.types.Operator):
|
||||
ifc_class = props.ifc_class or AuthoringData.data["ifc_element_type"]
|
||||
else:
|
||||
ifc_class = AuthoringData.data["ifc_element_type"]
|
||||
props.type_class = ifc_class
|
||||
bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class, offset=0, limit=9)
|
||||
|
||||
# will be None if project has no types
|
||||
if ifc_class is not None:
|
||||
props.type_class = ifc_class
|
||||
bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class, offset=0, limit=9)
|
||||
return context.window_manager.invoke_popup(self, width=550)
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
@@ -378,6 +378,7 @@ class BimToolUI:
|
||||
op.depth = cls.props.extrusion_depth
|
||||
|
||||
add_layout_hotkey_operator(cls.layout, "Extend", "S_E", "")
|
||||
add_layout_hotkey_operator(cls.layout, "Flip", "S_F", bpy.ops.bim.flip_object.__doc__)
|
||||
|
||||
if AuthoringData.data["active_class"] in (
|
||||
"IfcCableCarrierSegment",
|
||||
@@ -385,8 +386,8 @@ class BimToolUI:
|
||||
"IfcDuctSegment",
|
||||
"IfcPipeSegment",
|
||||
):
|
||||
add_layout_hotkey_operator(cls.layout, "Add Fitting", "S_F", "")
|
||||
|
||||
add_layout_hotkey_operator(cls.layout, "Add Fitting", "S_Y", "")
|
||||
if context.region.type != "TOOL_HEADER":
|
||||
cls.layout.operator("bim.mep_add_bend")
|
||||
cls.layout.operator("bim.mep_add_transition")
|
||||
@@ -394,7 +395,6 @@ class BimToolUI:
|
||||
|
||||
else:
|
||||
add_layout_hotkey_operator(cls.layout, "Edit Axis", "A_E", "")
|
||||
add_layout_hotkey_operator(cls.layout, "Flip", "S_F", bpy.ops.bim.flip_object.__doc__)
|
||||
add_layout_hotkey_operator(cls.layout, "Butt", "S_T", "")
|
||||
add_layout_hotkey_operator(cls.layout, "Mitre", "S_Y", "")
|
||||
add_layout_hotkey_operator(cls.layout, "Rotate 90", "S_R", bpy.ops.bim.rotate_90.__doc__)
|
||||
@@ -719,10 +719,9 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bpy.ops.bim.flip_wall()
|
||||
elif self.active_class in ("IfcWindow", "IfcWindowStandardCase", "IfcDoor", "IfcDoorStandardCase"):
|
||||
bpy.ops.bim.flip_fill()
|
||||
elif self.active_class in ("IfcBeam", "IfcColumn"):
|
||||
elif self.active_material_usage == "PROFILE":
|
||||
bpy.ops.bim.flip_object(flip_local_axes="XZ")
|
||||
elif self.active_class in ("IfcDuctSegment", "IfcPipeSegment", "IfcCableCarrierSegment", "IfcCableSegment"):
|
||||
bpy.ops.bim.fit_flow_segments()
|
||||
|
||||
|
||||
def hotkey_S_G(self):
|
||||
obj = bpy.context.active_object
|
||||
@@ -808,9 +807,12 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return
|
||||
if self.active_material_usage == "LAYER2":
|
||||
bpy.ops.bim.join_wall(join_type="V")
|
||||
elif self.active_class in ("IfcDuctSegment", "IfcPipeSegment", "IfcCableCarrierSegment", "IfcCableSegment"):
|
||||
bpy.ops.bim.fit_flow_segments()
|
||||
elif self.active_material_usage == "PROFILE":
|
||||
bpy.ops.bim.extend_profile(join_type="V")
|
||||
|
||||
|
||||
def hotkey_S_B(self):
|
||||
bpy.ops.bim.add_boundary()
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ from mathutils import Vector, Matrix
|
||||
from bpy.app.handlers import persistent
|
||||
from blenderbim.bim.module.project.data import LinksData
|
||||
from blenderbim.bim.module.project.decorator import ProjectDecorator, ClippingPlaneDecorator
|
||||
from typing import Union
|
||||
|
||||
|
||||
class NewProject(bpy.types.Operator):
|
||||
@@ -301,7 +302,7 @@ class AssignLibraryDeclaration(bpy.types.Operator):
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration",
|
||||
self.file,
|
||||
definition=self.file.by_id(self.definition),
|
||||
definitions=[self.file.by_id(self.definition)],
|
||||
relating_context=self.file.by_type("IfcProjectLibrary")[0],
|
||||
)
|
||||
element_name = self.props.active_library_element
|
||||
@@ -337,7 +338,7 @@ class UnassignLibraryDeclaration(bpy.types.Operator):
|
||||
ifcopenshell.api.run(
|
||||
"project.unassign_declaration",
|
||||
self.file,
|
||||
definition=self.file.by_id(self.definition),
|
||||
definitions=[self.file.by_id(self.definition)],
|
||||
relating_context=self.file.by_type("IfcProjectLibrary")[0],
|
||||
)
|
||||
element_name = self.props.active_library_element
|
||||
@@ -867,7 +868,16 @@ class LinkIfc(bpy.types.Operator):
|
||||
except:
|
||||
pass # Perhaps on another drive or something
|
||||
new.name = filepath
|
||||
bpy.ops.bim.load_link(filepath=filepath, false_origin=self.false_origin)
|
||||
status = bpy.ops.bim.load_link(filepath=filepath, false_origin=self.false_origin)
|
||||
if status == {"CANCELLED"}:
|
||||
error_msg = (
|
||||
f'Error processing IFC file "{self.filepath}" '
|
||||
"was critical and blend file either wasn't saved or wasn't updated. "
|
||||
"See logs above in system console for details."
|
||||
)
|
||||
print(error_msg)
|
||||
self.report({"ERROR"}, error_msg)
|
||||
return {"FINISHED"}
|
||||
print(f"Finished linking {len(files)} IFCs", time.time() - start)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -946,10 +956,12 @@ class LoadLink(bpy.types.Operator):
|
||||
if self.filepath.lower().endswith(".blend"):
|
||||
self.link_blend(filepath)
|
||||
elif self.filepath.lower().endswith(".ifc"):
|
||||
self.link_ifc()
|
||||
status = self.link_ifc()
|
||||
if status:
|
||||
return status
|
||||
return {"FINISHED"}
|
||||
|
||||
def link_blend(self, filepath):
|
||||
def link_blend(self, filepath: str) -> None:
|
||||
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
|
||||
data_to.scenes = data_from.scenes
|
||||
for scene in bpy.data.scenes:
|
||||
@@ -962,7 +974,7 @@ class LoadLink(bpy.types.Operator):
|
||||
link = bpy.context.scene.BIMProjectProperties.links.get(self.filepath)
|
||||
link.is_loaded = True
|
||||
|
||||
def link_ifc(self):
|
||||
def link_ifc(self) -> Union[set[str], None]:
|
||||
blend_filepath = self.filepath + ".cache.blend"
|
||||
h5_filepath = self.filepath + ".cache.h5"
|
||||
|
||||
@@ -982,11 +994,14 @@ except Exception as e:
|
||||
exit(1)
|
||||
"""
|
||||
|
||||
t = time.time()
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as temp_file:
|
||||
temp_file.write(code)
|
||||
run = subprocess.run([bpy.app.binary_path, "-b", "--python", temp_file.name, "--python-exit-code", "1"])
|
||||
if run.returncode == 1:
|
||||
print("An error occurred while processing your IFC.")
|
||||
if not os.path.exists(blend_filepath) or os.stat(blend_filepath).st_mtime < t:
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.link_blend(blend_filepath)
|
||||
|
||||
|
||||
@@ -185,6 +185,8 @@ class IfcClassData:
|
||||
if element:
|
||||
if element.is_a("IfcOpeningElement") or element.is_a("IfcOpeningStandardCase"):
|
||||
return False
|
||||
if element.is_a() in ("IfcWindowStyle", "IfcDoorStyle"): #see https://github.com/IfcOpenShell/IfcOpenShell/issues/4622#issuecomment-2095676368
|
||||
return True
|
||||
for product in cls.ifc_products():
|
||||
if element.is_a(product[0]):
|
||||
return True
|
||||
|
||||
@@ -23,6 +23,7 @@ import blenderbim.bim.handler
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.style as core
|
||||
import ifcopenshell.util.representation
|
||||
from blenderbim.bim.module.style.prop import switch_shading
|
||||
from pathlib import Path
|
||||
from mathutils import Vector
|
||||
|
||||
@@ -126,6 +127,10 @@ class DisableEditingStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
tool.Style.reload_material_from_ifc(material)
|
||||
props.is_editing_style = 0
|
||||
|
||||
# restore selected style type
|
||||
material = tool.Ifc.get_object(style)
|
||||
material.BIMStyleProperties.active_style_type = material.BIMStyleProperties.active_style_type
|
||||
|
||||
|
||||
class EditStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_style"
|
||||
@@ -246,14 +251,15 @@ class BrowseExternalStyle(bpy.types.Operator):
|
||||
)
|
||||
|
||||
def invoke(self, context, event):
|
||||
external_style = None
|
||||
style_elements = None
|
||||
if self.active_surface_style_id:
|
||||
style = tool.Ifc.get().by_id(self.active_surface_style_id)
|
||||
external_style = tool.Style.get_style_elements(style).get("IfcExternallyDefinedSurfaceStyle", None)
|
||||
style_elements = tool.Style.get_style_elements(style)
|
||||
|
||||
# automatically select previously selected external style in file browser
|
||||
# if it exists in the file
|
||||
if external_style and self.filepath == "":
|
||||
if style_elements and self.filepath == "" and tool.Style.has_blender_external_style(style_elements):
|
||||
external_style = style_elements["IfcExternallyDefinedSurfaceStyle"]
|
||||
style_path = Path(tool.Ifc.resolve_uri(external_style.Location))
|
||||
self.directory = str(style_path.parent)
|
||||
self.filepath = str(style_path)
|
||||
@@ -310,6 +316,9 @@ class BrowseExternalStyle(bpy.types.Operator):
|
||||
attributes["Location"].string_value = filepath
|
||||
attributes["Identification"].string_value = f"{self.data_block_type}/{self.data_block}"
|
||||
attributes["Name"].string_value = self.data_block
|
||||
|
||||
style = tool.Ifc.get().by_id(self.active_surface_style_id)
|
||||
bpy.ops.bim.activate_external_style(material_name=tool.Ifc.get_object(style).name)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -325,14 +334,23 @@ class ActivateExternalStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
material = context.active_object.active_material
|
||||
else:
|
||||
material = bpy.data.materials[self.material_name]
|
||||
external_style = tool.Style.get_style_elements(material)["IfcExternallyDefinedSurfaceStyle"]
|
||||
data_block_type, data_block = external_style.Identification.split("/")
|
||||
style_path = Path(tool.Ifc.resolve_uri(external_style.Location))
|
||||
|
||||
props = context.scene.BIMStylesProperties
|
||||
if props.is_editing:
|
||||
location = props.external_style_attributes["Location"].string_value
|
||||
identification = props.external_style_attributes["Identification"].string_value
|
||||
else:
|
||||
external_style = tool.Style.get_style_elements(material)["IfcExternallyDefinedSurfaceStyle"]
|
||||
location = external_style.Location
|
||||
identification = external_style.Identification
|
||||
|
||||
data_block_type, data_block = identification.split("/")
|
||||
style_path = Path(tool.Ifc.resolve_uri(location))
|
||||
|
||||
if style_path.suffix != ".blend":
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
f"Error loading external style for \"{material.name}\" - only Blender external styles are supported",
|
||||
f'Error loading external style for "{material.name}" - only Blender external styles are supported',
|
||||
)
|
||||
return {"CANCELLED"}
|
||||
|
||||
@@ -587,7 +605,8 @@ class EnableEditingSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
props.is_editing_class = self.ifc_class
|
||||
tool.Style.set_surface_style_props()
|
||||
|
||||
surface_style = tool.Style.get_style_elements(style).get(self.ifc_class, None)
|
||||
style_elements = tool.Style.get_style_elements(style)
|
||||
surface_style = style_elements.get(self.ifc_class, None)
|
||||
attributes = tool.Style.get_style_ui_props_attributes(self.ifc_class)
|
||||
|
||||
# lighting style require special handling since Attribute doesn't support colors
|
||||
@@ -607,6 +626,17 @@ class EnableEditingSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(surface_style or self.ifc_class, attributes, callback)
|
||||
|
||||
material = tool.Ifc.get_object(style)
|
||||
active_style_type = material.BIMStyleProperties.active_style_type
|
||||
if self.ifc_class == "IfcExternallyDefinedSurfaceStyle" and active_style_type != "External":
|
||||
if tool.Style.has_blender_external_style(style_elements):
|
||||
switch_shading(material, "External")
|
||||
elif (
|
||||
self.ifc_class in ("IfcSurfaceStyleShading", "IfcSurfaceStyleRendering", "IfcSurfaceStyleWithTextures")
|
||||
and active_style_type != "Shading"
|
||||
):
|
||||
switch_shading(material, "Shading")
|
||||
|
||||
|
||||
class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_surface_style"
|
||||
@@ -631,6 +661,10 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
self.props.is_editing_style = 0
|
||||
core.load_styles(tool.Style, style_type=self.props.style_type)
|
||||
|
||||
# restore selected style type
|
||||
material = tool.Ifc.get_object(self.style)
|
||||
material.BIMStyleProperties.active_style_type = material.BIMStyleProperties.active_style_type
|
||||
|
||||
def edit_existing_style(self):
|
||||
material = tool.Ifc.get_object(self.style)
|
||||
if self.surface_style.is_a() == "IfcSurfaceStyleShading":
|
||||
|
||||
@@ -33,6 +33,8 @@ from bpy.props import (
|
||||
)
|
||||
|
||||
import gettext
|
||||
from typing import Literal
|
||||
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -251,19 +253,15 @@ class BIMStylesProperties(PropertyGroup):
|
||||
)
|
||||
|
||||
|
||||
def update_shading_style(self, context):
|
||||
blender_material = self.id_data
|
||||
style_elements = tool.Style.get_style_elements(blender_material)
|
||||
if self.active_style_type == "External":
|
||||
if tool.Style.has_blender_external_style(style_elements):
|
||||
try:
|
||||
bpy.ops.bim.activate_external_style(material_name=blender_material.name)
|
||||
except RuntimeError as error:
|
||||
if str(error).startswith("Error: Error loading external style for "):
|
||||
return
|
||||
raise error
|
||||
|
||||
elif self.active_style_type == "Shading":
|
||||
def switch_shading(blender_material: bpy.types.Material, style_type: Literal["External", "Shading"]) -> None:
|
||||
if style_type == "External":
|
||||
try:
|
||||
bpy.ops.bim.activate_external_style(material_name=blender_material.name)
|
||||
except RuntimeError as error:
|
||||
if str(error).startswith("Error: Error loading external style for "):
|
||||
return
|
||||
raise error
|
||||
elif style_type == "Shading":
|
||||
style_elements = tool.Style.get_style_elements(blender_material)
|
||||
rendering_style = None
|
||||
texture_style = None
|
||||
@@ -279,6 +277,16 @@ def update_shading_style(self, context):
|
||||
|
||||
if rendering_style and texture_style:
|
||||
tool.Loader.create_surface_style_with_textures(blender_material, rendering_style, texture_style)
|
||||
|
||||
|
||||
def update_shading_style(self, context):
|
||||
blender_material = self.id_data
|
||||
style_elements = tool.Style.get_style_elements(blender_material)
|
||||
if self.active_style_type == "External":
|
||||
if tool.Style.has_blender_external_style(style_elements):
|
||||
switch_shading(blender_material, self.active_style_type)
|
||||
elif self.active_style_type == "Shading":
|
||||
switch_shading(blender_material, self.active_style_type)
|
||||
tool.Style.record_shading(blender_material)
|
||||
|
||||
|
||||
|
||||
@@ -146,23 +146,51 @@ class SelectType(bpy.types.Operator):
|
||||
relating_type: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
element = tool.Ifc.get().by_id(self.relating_type)
|
||||
obj = tool.Ifc.get_object(element)
|
||||
if obj:
|
||||
try:
|
||||
tool.Blender.select_and_activate_single_object(context, obj)
|
||||
except:
|
||||
self.report({"INFO"}, "Type object is hidden.")
|
||||
# IfcTypeProducts are only used for annotations and not part of the model interface.
|
||||
if element.is_a() != "IfcTypeProduct":
|
||||
try:
|
||||
context.scene.BIMModelProperties.ifc_class = element.is_a()
|
||||
context.scene.BIMModelProperties.relating_type_id = str(self.relating_type)
|
||||
except:
|
||||
# Potentially our BIM Tool is filtered to a specific element.
|
||||
pass
|
||||
|
||||
if self.relating_type: #if operator button sends a relating_type, the iterator only selects this one type
|
||||
element = tool.Ifc.get().by_id(self.relating_type)
|
||||
obj = tool.Ifc.get_object(element)
|
||||
selected_objs = [obj]
|
||||
else: #else, the iterator selects all the types of all the selected objects
|
||||
selected_objs = context.selected_objects
|
||||
active_obj = context.active_object
|
||||
selected_objs.append(active_obj) #update selected_objs so the active_obj is at the end of the list
|
||||
|
||||
last_relating_type_obj = None
|
||||
types_collection_in_view_layer = self.find_collection_in_ifcproject(context, collection_name = "Types")
|
||||
types_collection_in_view_layer.hide_viewport = False
|
||||
types_collection = bpy.data.collections.get("Types")
|
||||
for type_obj in types_collection.objects:
|
||||
type_obj.hide_set(True)
|
||||
for obj in selected_objs:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
relating_type = ifcopenshell.util.element.get_type(element)
|
||||
if relating_type:
|
||||
relating_type_obj = tool.Ifc.get_object(relating_type)
|
||||
if relating_type_obj:
|
||||
if relating_type_obj.hide_get():
|
||||
relating_type_obj.hide_set(False)
|
||||
relating_type_obj.select_set(True)
|
||||
last_relating_type_obj = relating_type_obj
|
||||
if not element.is_a("IfcTypeObject"):
|
||||
obj.select_set(False)
|
||||
|
||||
context.view_layer.objects.active = last_relating_type_obj #makes the active_obj's type the active object
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
def find_collection_in_ifcproject(self, context, collection_name):
|
||||
|
||||
ifc_project_collection = None
|
||||
for child in context.view_layer.layer_collection.children:
|
||||
if "IfcProject" in child.name:
|
||||
ifc_project_collection = child
|
||||
break
|
||||
|
||||
if ifc_project_collection:
|
||||
collection_in_view_layer = ifc_project_collection.children.get(collection_name)
|
||||
return collection_in_view_layer
|
||||
|
||||
|
||||
class SelectSimilarType(bpy.types.Operator):
|
||||
bl_idname = "bim.select_similar_type"
|
||||
|
||||
@@ -88,7 +88,7 @@ class BIM_PT_type(Panel):
|
||||
if TypeData.data["relating_type"]:
|
||||
row.label(text=TypeData.data["relating_type"]["name"])
|
||||
op = row.operator("bim.select_type", icon="OBJECT_DATA", text="")
|
||||
op.relating_type = TypeData.data["relating_type"]["id"]
|
||||
op.relating_type = 0 #will only select the relating types of only the selected objects
|
||||
row.operator("bim.select_similar_type", icon="RESTRICT_SELECT_OFF", text="")
|
||||
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
|
||||
row.operator("bim.unassign_type", icon="X", text="")
|
||||
|
||||
@@ -145,7 +145,7 @@ def rename_sheet(ifc, drawing, sheet: ifcopenshell.entity_instance, identificati
|
||||
|
||||
|
||||
def rename_reference(ifc, drawing, reference=None, identification=None):
|
||||
attributes = drawing.generate_reference_attributes(reference, Identifiaction=identification)
|
||||
attributes = drawing.generate_reference_attributes(reference, Identification=identification)
|
||||
ifc.run("document.edit_reference", reference=reference, attributes=attributes)
|
||||
|
||||
|
||||
|
||||
@@ -23,9 +23,14 @@ import hashlib
|
||||
import logging
|
||||
import numpy as np
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.system
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.core.drawing
|
||||
import blenderbim.core.style
|
||||
import blenderbim.core.spatial
|
||||
import blenderbim.core.system
|
||||
import blenderbim.core.geometry
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.bim.import_ifc
|
||||
|
||||
@@ -160,10 +160,16 @@ class ImportFilterQueryTransformer(lark.Transformer):
|
||||
return args[0]
|
||||
|
||||
def instance(self, args):
|
||||
return {"type": "instance", "value": " ".join([a.children[0].value for a in args])}
|
||||
if args[0].data == "not":
|
||||
return {"type": "instance", "value": "!" + args[1].children[0].value}
|
||||
else:
|
||||
return {"type": "instance", "value": args[0].children[0].value}
|
||||
|
||||
def entity(self, args):
|
||||
return {"type": "entity", "value": " ".join([a.children[0].value for a in args])}
|
||||
if args[0].data == "not":
|
||||
return {"type": "entity", "value": "!" + args[1].children[0].value}
|
||||
else:
|
||||
return {"type": "entity", "value": args[0].children[0].value}
|
||||
|
||||
def attribute(self, args):
|
||||
name, comparison, value = args
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.system
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
@@ -145,7 +146,7 @@ class System(blenderbim.core.tool.System):
|
||||
new.ifc_class = system.is_a()
|
||||
|
||||
@classmethod
|
||||
def load_ports(cls, element, ports):
|
||||
def load_ports(cls, element: ifcopenshell.entity_instance, ports: list[ifcopenshell.entity_instance]) -> None:
|
||||
if not ports:
|
||||
return
|
||||
obj = tool.Ifc.get_object(element)
|
||||
@@ -155,7 +156,13 @@ class System(blenderbim.core.tool.System):
|
||||
ifc_importer.calculate_unit_scale()
|
||||
ifc_importer.process_context_filter()
|
||||
ifc_importer.create_generic_elements(set(ports))
|
||||
|
||||
container = ifcopenshell.util.element.get_container(element)
|
||||
if container:
|
||||
collection = tool.Ifc.get_object(container).BIMObjectProperties.collection
|
||||
ifc_importer.collections[container.GlobalId] = collection
|
||||
ifc_importer.place_objects_in_collections()
|
||||
|
||||
for port_obj in ifc_importer.added_data.values():
|
||||
port_obj.parent = obj
|
||||
port_obj.matrix_parent_inverse = obj.matrix_world.inverted()
|
||||
|
||||
+1
@@ -16,6 +16,7 @@ a {
|
||||
}
|
||||
.sidebar-brand-text {
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
.blockbutton {
|
||||
max-width: 500px;
|
||||
|
||||
@@ -95,7 +95,10 @@ html_theme_options = {
|
||||
"color-background-border": "#cfd0cb",
|
||||
"color-foreground-primary": "#2e3436",
|
||||
"color-sidebar-item-background--hover": "#f7f7f6",
|
||||
"color-link": "#39b54a",
|
||||
"color-link--visited": "#39b54a",
|
||||
"color-link--hover": "#d98014",
|
||||
"color-link--visited--hover": "#d98014",
|
||||
"font-stack": "Nunito, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"
|
||||
},
|
||||
"dark_css_variables": {
|
||||
@@ -106,7 +109,10 @@ html_theme_options = {
|
||||
"color-background-border": "#2e3436",
|
||||
"color-foreground-primary": "#eeeeec",
|
||||
"color-sidebar-item-background--hover": "#2e3436",
|
||||
"color-link": "#39b54a",
|
||||
"color-link--visited": "#39b54a",
|
||||
"color-link--hover": "#d98014",
|
||||
"color-link--visited--hover": "#d98014",
|
||||
"font-stack": "Nunito, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"
|
||||
},
|
||||
|
||||
|
||||
@@ -92,13 +92,14 @@ For Linux or Mac:
|
||||
$ ln -s $PWD/src/blenderbim/blenderbim/tool $BLENDER_ADDON_PATH/tool
|
||||
$ ln -s $PWD/src/blenderbim/blenderbim/bim $BLENDER_ADDON_PATH/bim
|
||||
|
||||
# Remove the IfcOpenShell dependency Python code
|
||||
$ rm -r $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell/api
|
||||
$ rm -r $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell/util
|
||||
# Copy over compiled IfcOpenShell files
|
||||
$ cp $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell/*_wrapper* $PWD/src/ifcopenshell-python/ifcopenshell/
|
||||
|
||||
# Remove the IfcOpenShell dependency
|
||||
$ rm -r $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell
|
||||
|
||||
# Replace them with links to the Git repository
|
||||
$ ln -s $PWD/src/ifcopenshell-python/ifcopenshell/api $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell/api
|
||||
$ ln -s $PWD/src/ifcopenshell-python/ifcopenshell/util $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell/util
|
||||
$ ln -s $PWD/src/ifcopenshell-python/ifcopenshell $BLENDER_ADDON_PATH/libs/site/packages/ifcopenshell
|
||||
|
||||
# Remove and link other IfcOpenShell utilities
|
||||
$ rm -r $BLENDER_ADDON_PATH/libs/site/packages/ifccsv.py
|
||||
@@ -153,21 +154,19 @@ Before running it follow the instructions descibed after `rem` tags.
|
||||
rd /S /Q "%blenderbim%\tool\"
|
||||
rd /S /Q "%blenderbim%\bim\"
|
||||
|
||||
|
||||
echo Replacing them with links to the Git repository...
|
||||
mklink /D "%blenderbim%\core" "%cd%\src\blenderbim\blenderbim\core"
|
||||
mklink /D "%blenderbim%\tool" "%cd%\src\blenderbim\blenderbim\tool"
|
||||
mklink /D "%blenderbim%\bim" "%cd%\src\blenderbim\blenderbim\bim"
|
||||
|
||||
echo Copy over compiled IfcOpenShell files...
|
||||
copy "%blenderbim%\libs\site\packages\ifcopenshell\*_wrapper*" "%cd%\src\ifcopenshell-python\ifcopenshell\"
|
||||
|
||||
echo Remove the IfcOpenShell dependency Python code...
|
||||
rd /S /Q "%blenderbim%\libs\site\packages\ifcopenshell\api"
|
||||
rd /S /Q "%blenderbim%\libs\site\packages\ifcopenshell\util"
|
||||
echo Remove the IfcOpenShell dependency...
|
||||
rd /S /Q "%blenderbim%\libs\site\packages\ifcopenshell"
|
||||
|
||||
|
||||
echo Replacing them with links to the Git repository...
|
||||
mklink /D "%blenderbim%\libs\site\packages\ifcopenshell\api" "%cd%\src\ifcopenshell-python\ifcopenshell\api"
|
||||
mklink /D "%blenderbim%\libs\site\packages\ifcopenshell\util" "%cd%\src\ifcopenshell-python\ifcopenshell\util"
|
||||
echo Replace them with links to the Git repository...
|
||||
mklink /D "%blenderbim%\libs\site\packages\ifcopenshell" "%cd%\src\ifcopenshell-python\ifcopenshell"
|
||||
|
||||
echo Remove and link other IfcOpenShell utilities...
|
||||
del "%blenderbim%\libs\site\packages\ifccsv.py"
|
||||
|
||||
@@ -40,7 +40,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name="Australian Library"
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project
|
||||
)
|
||||
unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
|
||||
@@ -196,7 +196,7 @@ class LibraryGenerator:
|
||||
)
|
||||
layer.Name = layer_data[0]
|
||||
layer.LayerThickness = layer_data[2]
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_layer_type(self, ifc_class, name, thickness):
|
||||
@@ -205,7 +205,7 @@ class LibraryGenerator:
|
||||
layer_set = rel.RelatingMaterial
|
||||
layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"])
|
||||
layer.LayerThickness = thickness
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_profile_type(self, ifc_class, name, profile):
|
||||
@@ -216,7 +216,7 @@ class LibraryGenerator:
|
||||
"material.add_profile", self.file, profile_set=profile_set, material=self.materials["TBD"]["ifc"]
|
||||
)
|
||||
ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
def create_type(self, ifc_class, name, representations):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name)
|
||||
@@ -248,7 +248,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
LibraryGenerator().generate()
|
||||
|
||||
@@ -35,7 +35,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name="BlenderBIM Demo Library"
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project
|
||||
)
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, length={"is_metric": True, "raw": "METERS"})
|
||||
model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model")
|
||||
@@ -209,7 +209,7 @@ class LibraryGenerator:
|
||||
layer_set = rel.RelatingMaterial
|
||||
layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=layer_set, material=self.material)
|
||||
layer.LayerThickness = thickness
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_profile_type(self, ifc_class, name, profile):
|
||||
@@ -220,7 +220,7 @@ class LibraryGenerator:
|
||||
"material.add_profile", self.file, profile_set=profile_set, material=self.material
|
||||
)
|
||||
ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
def create_type(self, ifc_class, name, representations):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name)
|
||||
@@ -252,7 +252,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
LibraryGenerator().generate()
|
||||
|
||||
@@ -42,7 +42,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project
|
||||
)
|
||||
unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
|
||||
@@ -131,7 +131,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -37,7 +37,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project
|
||||
)
|
||||
unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
|
||||
@@ -1797,7 +1797,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation_2d
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_layer_set_type(self, name, data):
|
||||
@@ -1811,7 +1811,7 @@ class LibraryGenerator:
|
||||
)
|
||||
layer.Name = layer_data[0]
|
||||
layer.LayerThickness = layer_data[2]
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_layer_type(self, ifc_class, name, thickness):
|
||||
@@ -1822,7 +1822,7 @@ class LibraryGenerator:
|
||||
"material.add_layer", self.file, layer_set=layer_set, material=self.materials["TBD"]["ifc"]
|
||||
)
|
||||
layer.LayerThickness = thickness
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_profile_type(self, ifc_class, name, profile):
|
||||
@@ -1837,7 +1837,7 @@ class LibraryGenerator:
|
||||
# material=self.materials["TBD"]["ifc"]
|
||||
)
|
||||
ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
def create_type(self, ifc_class, name, representations):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name)
|
||||
@@ -1869,7 +1869,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -319,7 +319,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=library_name
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project
|
||||
)
|
||||
unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, units=[unit])
|
||||
@@ -447,7 +447,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation_2d
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
return element
|
||||
|
||||
def create_type(self, ifc_class, name, representations):
|
||||
@@ -480,7 +480,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name="BlenderBIM Demo Library"
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.library
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.library
|
||||
)
|
||||
ifcopenshell.api.run("unit.assign_unit", self.file, length={"is_metric": True, "raw": "METERS"})
|
||||
model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model")
|
||||
@@ -98,7 +98,7 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.run(
|
||||
"geometry.assign_representation", self.file, product=element, representation=representation
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
LibraryGenerator().generate()
|
||||
|
||||
@@ -43,7 +43,7 @@ class LibraryGenerator:
|
||||
"root.create_entity", self.file, ifc_class="IfcProjectLibrary", name=f"{parse_profiles_type} Steel Profiles Library"
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration", self.file, definition=self.library, relating_context=self.project
|
||||
"project.assign_declaration", self.file, definitions=[self.library], relating_context=self.project
|
||||
)
|
||||
dim_exponents = self.file.createIfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0)
|
||||
length_unit = ifcopenshell.api.run("unit.add_si_unit", self.file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
@@ -182,7 +182,7 @@ class LibraryGenerator:
|
||||
# material=self.materials["TBD"]["ifc"]
|
||||
)
|
||||
ifcopenshell.api.run("material.assign_profile", self.file, material_profile=material_profile, profile=profile)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.library)
|
||||
ifcopenshell.api.run("project.assign_declaration", self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
def create_double_l_profile(self, profile, resulting_profile_name=None, profiles_gap=0, mode = "LLBB"):
|
||||
def create_derived_profile(profile, mirrored=False):
|
||||
|
||||
@@ -91,7 +91,7 @@ def mirror_placement_test():
|
||||
library = ifcopenshell.api.run(
|
||||
"root.create_entity", ifc_file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library"
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definition=library, relating_context=project)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[library], relating_context=project)
|
||||
unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit])
|
||||
model = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Model")
|
||||
@@ -152,7 +152,7 @@ def mirror_placement_test():
|
||||
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcFurnitureType", name="test")
|
||||
ifcopenshell.api.run("geometry.assign_representation", ifc_file, product=element, representation=representation_3d)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definition=element, relating_context=library)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[element], relating_context=library)
|
||||
|
||||
ifc_file.write("tmp.ifc")
|
||||
|
||||
@@ -165,7 +165,7 @@ def curve_between_two_points_test():
|
||||
library = ifcopenshell.api.run(
|
||||
"root.create_entity", ifc_file, ifc_class="IfcProjectLibrary", name=f"Non-structural assets library"
|
||||
)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definition=library, relating_context=project)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[library], relating_context=project)
|
||||
unit = ifcopenshell.api.run("unit.add_si_unit", ifc_file, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
ifcopenshell.api.run("unit.assign_unit", ifc_file, units=[unit])
|
||||
model = ifcopenshell.api.run("context.add_context", ifc_file, context_type="Model")
|
||||
@@ -217,7 +217,7 @@ def curve_between_two_points_test():
|
||||
print(representation_2d)
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcFurnitureType", name="test")
|
||||
ifcopenshell.api.run("geometry.assign_representation", ifc_file, product=element, representation=representation_2d)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definition=element, relating_context=library)
|
||||
ifcopenshell.api.run("project.assign_declaration", ifc_file, definitions=[element], relating_context=library)
|
||||
|
||||
ifc_file.write("tmp.ifc")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user