This commit is contained in:
Andrej730
2025-07-15 11:19:32 +05:00
parent a461281b1e
commit f18c93c9ee
15 changed files with 65 additions and 44 deletions
@@ -1208,9 +1208,11 @@ class ActivateBcfViewpoint(bpy.types.Operator):
self.file = tool.Ifc.get()
bcfxml = bcfstore.BcfStore.get_bcfxml()
assert bcfxml
assert context.scene
props = tool.Bcf.get_bcf_props()
blender_topic = props.active_topic
assert blender_topic
topic = bcfxml.topics[blender_topic.name]
if self.viewpoint_guid:
viewpoint_guid = self.viewpoint_guid
@@ -1234,6 +1236,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
cam_height = context.scene.render.resolution_y
cam_aspect = cam_width / cam_height
assert isinstance(obj.data, bpy.types.Camera)
obj.data.background_images.clear()
if viewpoint.snapshot:
obj.data.show_background_images = True
+1 -1
View File
@@ -48,7 +48,7 @@ class BIM_PT_materials(Panel):
MaterialsData.load()
self.props = tool.Material.get_material_props()
material = tool.Material.get_active_material_item()
material = self.props.active_material
material_id = material.ifc_definition_id if material else None
row = self.layout.row(align=True)
@@ -371,7 +371,9 @@ def get_vertical_profile_preview_data(
return data
def get_horizontal_profile_preview_data(context, relating_type):
def get_horizontal_profile_preview_data(
context: bpy.types.Context, relating_type: ifcopenshell.entity_instance
) -> dict[str, Any]:
material = ifcopenshell.util.element.get_material(relating_type)
try:
profile_curve = material.MaterialProfiles[0].Profile
@@ -385,7 +387,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
polyline_points = polyline_data[0].polyline_points if polyline_data else []
if len(polyline_points) < 2:
return
return {}
for point in polyline_points:
polyline_verts.append(Vector((point.x, point.y, point.z)))
polyline_edges = [(i, i + 1) for i in range(len(polyline_verts) - 1)]
@@ -433,7 +435,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
case "9":
grouped_verts = [(v[0] + x_offset, v[1] - y_offset, v[2]) for v in grouped_verts]
data = {}
data: dict[str, Any] = {}
data["verts"] = []
data["edges"] = []
data["tris"] = []
+10 -6
View File
@@ -115,7 +115,7 @@ def get_material_pset_names(self: "PsetProperties", context: object) -> tool.Ble
return MaterialPsetsData.data["pset_name"]
def get_material_set_pset_names(self: "PsetProperties", context: object):
def get_material_set_pset_names(self: "PsetProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
global psetnames
if not ObjectMaterialData.is_loaded:
ObjectMaterialData.load()
@@ -128,12 +128,14 @@ def get_material_set_pset_names(self: "PsetProperties", context: object):
return psetnames[ifc_class]
def get_material_set_item_pset_names(self: "PsetProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
def get_material_set_item_pset_names(
self: "PsetProperties", context: bpy.types.Context
) -> tool.Blender.BLENDER_ENUM_ITEMS:
global psetnames
obj = context.active_object
assert obj
omprops = tool.Material.get_object_material_props(obj)
if not omprops.active_material_set_item_id:
if not (ifc_definition_id := omprops.active_material_set_item_id):
return []
ifc_class = tool.Ifc.get().by_id(ifc_definition_id).is_a()
if ifc_class not in psetnames:
@@ -151,7 +153,7 @@ def get_task_qto_names(self: "PsetProperties", context: object) -> tool.Blender.
return qtonames[ifc_class]
def get_resource_pset_names(self: "PsetProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
def get_resource_pset_names(self: "PsetProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
global psetnames
rprops = context.scene.BIMResourceProperties
rtprops = context.scene.BIMResourceTreeProperties
@@ -162,7 +164,7 @@ def get_resource_pset_names(self: "PsetProperties", context: object) -> tool.Ble
return psetnames[ifc_class]
def get_resource_qto_names(self: "PsetProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
def get_resource_qto_names(self: "PsetProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
global qtonames
rprops = context.scene.BIMResourceProperties
rtprops = context.scene.BIMResourceTreeProperties
@@ -223,7 +225,9 @@ def get_qto_name(self: "PsetProperties", context: bpy.types.Context) -> tool.Ble
results = get_resource_qto_names(self, context)
elif prop_type == "GroupPsetProperties":
results = get_group_qto_names(self, context)
return [("BBIM_CUSTOM", "Custom Qto", "Create a quantity set without using a template."), None] + results
else:
assert False
return [("BBIM_CUSTOM", "Custom Qto", "Create a quantity set without using a template."), None] + list(results)
def get_object_qto_name(self: "PsetProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
+17 -9
View File
@@ -484,7 +484,7 @@ class BIM_PT_material_psets(Panel):
elif ifc_definition_id != MaterialPsetsData.data["ifc_definition_id"]:
MaterialPsetsData.load()
props = context.scene.MaterialPsetProperties
props = tool.Pset.get_pset_props("", "Material")
row = self.layout.row(align=True)
prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
@@ -524,6 +524,7 @@ class BIM_PT_material_set_item_psets(Panel):
if not MaterialSetItemPsetsData.is_loaded:
MaterialSetItemPsetsData.load()
assert self.layout
obj = context.active_object
assert obj
omprops = tool.Material.get_object_material_props(obj)
@@ -531,7 +532,7 @@ class BIM_PT_material_set_item_psets(Panel):
self.layout.label(text="No Material Set Item Edited.")
return
props = obj.MaterialSetItemPsetProperties
props = tool.Pset.get_pset_props(obj.name, "MaterialSetItem")
row = self.layout.row(align=True)
prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
@@ -570,7 +571,8 @@ class BIM_PT_task_qtos(Panel):
if not TaskQtosData.is_loaded:
TaskQtosData.load()
props = context.scene.TaskPsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "Task")
row = self.layout.row(align=True)
row.prop(props, "qto_name", text="")
op = row.operator("bim.add_qto", icon="ADD", text="")
@@ -604,7 +606,8 @@ class BIM_PT_resource_qtos(Panel):
if not ResourceQtosData.is_loaded:
ResourceQtosData.load()
props = context.scene.ResourcePsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "Resource")
row = self.layout.row(align=True)
row.prop(props, "qto_name", text="")
op = row.operator("bim.add_qto", icon="ADD", text="")
@@ -638,7 +641,8 @@ class BIM_PT_resource_psets(Panel):
if not ResourcePsetsData.is_loaded:
ResourcePsetsData.load()
props = context.scene.ResourcePsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "Resource")
row = self.layout.row(align=True)
prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
@@ -672,7 +676,8 @@ class BIM_PT_group_qtos(Panel):
if not GroupQtosData.is_loaded:
GroupQtosData.load()
props = context.scene.GroupPsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "Group")
row = self.layout.row(align=True)
row.prop(props, "qto_name", text="")
op = row.operator("bim.add_qto", icon="ADD", text="")
@@ -706,7 +711,8 @@ class BIM_PT_group_psets(Panel):
if not GroupPsetData.is_loaded:
GroupPsetData.load()
props = context.scene.GroupPsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "Group")
row = self.layout.row(align=True)
prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
@@ -750,7 +756,8 @@ class BIM_PT_profile_psets(Panel):
):
ProfilePsetsData.load()
props = context.scene.ProfilePsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "Profile")
row = self.layout.row(align=True)
prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
@@ -782,7 +789,8 @@ class BIM_PT_work_schedule_psets(Panel):
if not WorkSchedulePsetsData.is_loaded:
WorkSchedulePsetsData.load()
props = context.scene.WorkSchedulePsetProperties
assert self.layout
props = tool.Pset.get_pset_props("", "WorkSchedule")
row = self.layout.row(align=True)
prop_with_search(row, props, "pset_name", text="")
op = row.operator("bim.add_pset", icon="ADD", text="")
+1 -1
View File
@@ -33,7 +33,7 @@ from bpy.props import (
FloatVectorProperty,
CollectionProperty,
)
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Literal
def get_element_key(self: "BIMSearchProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
-1
View File
@@ -543,7 +543,6 @@ class Material:
def ensure_material_assigned(cls, elements, material_type, material): pass
def ensure_material_unassigned(cls, elements): pass
def ensure_new_material_set_is_valid(cls, material): pass
def get_active_material_item(cls): pass
def get_active_material_type(cls): pass
def get_default_material(cls): pass
def get_elements_by_material(cls, material): pass
+3
View File
@@ -19,6 +19,7 @@
from __future__ import annotations
import os
import json
import bmesh
import bpy
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.api.material
@@ -70,6 +71,7 @@ class Debug(bonsai.core.tool.Debug):
mesh = bpy.data.meshes.new("Debug")
bm.to_mesh(mesh)
obj = bpy.data.objects.new(name, mesh)
assert bpy.context.scene
bpy.context.scene.collection.objects.link(obj)
return obj
@@ -80,6 +82,7 @@ class Debug(bonsai.core.tool.Debug):
mesh = bpy.data.meshes.new("Debug")
mesh.from_pydata(verts, edges, [])
obj = bpy.data.objects.new(name, mesh)
assert bpy.context.scene
bpy.context.scene.collection.objects.link(obj)
return obj
+1 -9
View File
@@ -76,14 +76,6 @@ class Material(bonsai.core.tool.Material):
def get_elements_by_material(cls, material: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)
@classmethod
def get_active_material_item(cls) -> Union[MaterialItem, None]:
"""Get active material props item if index is valid, otherwise, return None."""
props = tool.Material.get_material_props()
if 0 <= props.active_material_index < len(props.materials):
return props.materials[props.active_material_index]
return None
@classmethod
def get_material_category(cls, material: ifcopenshell.entity_instance) -> str:
# IfcMaterial has Category since IFC4.
@@ -95,7 +87,7 @@ class Material(bonsai.core.tool.Material):
# Store active category name to reselect it later.
# Occurs when we expand/contract all categories.
active_item = cls.get_active_material_item()
active_item = props.active_material
previously_selected_category = None
if active_item and active_item.is_category:
previously_selected_category = active_item.name
+2 -2
View File
@@ -75,11 +75,11 @@ class Pset(bonsai.core.tool.Pset):
@classmethod
def get_pset_props(cls, obj: str, obj_type: tool.Ifc.OBJECT_TYPE) -> PsetProperties:
if obj_type == "Object":
return bpy.data.objects.get(obj).PsetProperties
return bpy.data.objects[obj].PsetProperties
elif obj_type == "Material":
return bpy.context.scene.MaterialPsetProperties
elif obj_type == "MaterialSetItem":
return bpy.data.objects.get(obj).MaterialSetItemPsetProperties
return bpy.data.objects[obj].MaterialSetItemPsetProperties
elif obj_type == "Task":
return bpy.context.scene.TaskPsetProperties
elif obj_type == "Resource":
+6 -2
View File
@@ -33,9 +33,10 @@ import ifcopenshell.util.date as ifcdateutils
import ifcopenshell.util.cost
import ifcopenshell.util.resource
import ifcopenshell.util.constraint
from typing import Any, Union, TYPE_CHECKING
from typing import Any, Union, TYPE_CHECKING, Literal
if TYPE_CHECKING:
from bonsai.bim.prop import Attribute
from bonsai.bim.module.resource.prop import BIMResourceProperties
@@ -142,7 +143,9 @@ class Resource(bonsai.core.tool.Resource):
@classmethod
def get_resource_time_attributes(cls) -> dict[str, Any]:
def callback(attributes, prop):
import bonsai.bim.module.sequence.helper as helper
def callback(attributes: dict[str, Any], prop: Attribute) -> bool:
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
if prop.is_null:
attributes[prop.name] = None
@@ -155,6 +158,7 @@ class Resource(bonsai.core.tool.Resource):
return True
attributes[prop.name] = helper.parse_duration(prop.string_value)
return True
return False
props = bpy.context.scene.BIMResourceProperties
return bonsai.bim.helper.export_attributes(props.resource_time_attributes, callback)
+2 -2
View File
@@ -561,8 +561,8 @@ class Spatial(bonsai.core.tool.Spatial):
@classmethod
def get_active_container(cls) -> Union[ifcopenshell.entity_instance, None]:
props = cls.get_spatial_props()
if props.active_container_index < len(props.containers):
container = tool.Ifc.get().by_id(props.containers[props.active_container_index].ifc_definition_id)
if active_container := props.active_container:
container = tool.Ifc.get().by_id(active_container.ifc_definition_id)
return container
@classmethod
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api.alignment
from ifcopenshell import entity_instance
import math
@@ -5,6 +5,8 @@ defaults = {"Girth": 1.0, "WallThickness": 0.11}
depths = [2.0, 3.0]
widths = [0.2, 0.3]
Girth, Depth, WallThickness, Width = 0.0, 0.0, 0.0, 0.0
for d, w in itertools.product(depths, widths):
D = dict(defaults, Depth=d, Width=w)
@@ -17,17 +17,21 @@
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
import os
import logging
import math
import os
from typing import Union
import ifcpatch
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.unit
import ifcopenshell.util.schema
import ifcopenshell.util.element
import ifcopenshell.util.schema
import ifcopenshell.util.unit
class Patcher:
def __init__(self, file, logger):
class Patcher(ifcpatch.BasePatcher):
def __init__(self, file: ifcopenshell.file, logger: Union[logging.Logger, None] = None):
"""Fix missing door swings in Revit when viewing ArchiCAD IFCs
ArchiCAD has the ability to store 2D data with objects like doors for
@@ -56,10 +60,9 @@ class Patcher:
ifcpatch.execute({"input": "input.ifc", "file": model, "recipe": "FixArchiCADToRevitDoorSwings", "arguments": []})
"""
self.file = file
self.logger = logger
super().__init__(file, logger)
def patch(self):
def patch(self) -> None:
# Revit has the ability to switch between 3D representations and 2D
# representations (e.g. in plan view). It does this by detecting IFC
# representations that belong to either the Model Body representation