This commit is contained in:
Andrej730
2025-07-10 11:30:46 +05:00
parent 8a6eb1b60f
commit 05cb06a28e
6 changed files with 32 additions and 17 deletions
@@ -28,9 +28,12 @@ import bonsai.bim.helper
import bonsai.tool as tool
import bonsai.core.material as core
import bonsai.bim.module.model.profile as model_profile
from typing import Any, Union, TYPE_CHECKING
from typing import Any, Union, TYPE_CHECKING, Literal
from bonsai.bim.module.model import wall, slab
if TYPE_CHECKING:
from bonsai.bim.prop import Attribute
class LoadMaterials(bpy.types.Operator):
bl_idname = "bim.load_materials"
@@ -508,7 +511,9 @@ class EnableEditingAssignedMaterial(bpy.types.Operator):
bonsai.bim.helper.import_attributes2(material, props.material_set_attributes)
return {"FINISHED"}
def import_attributes(self, name, prop, data):
def import_attributes(
self, name: str, prop: Union["Attribute", None], data: dict[str, Any]
) -> None | Literal[True]:
if name == "CardinalPoint":
# TODO: complain to buildingSMART
cardinal_point_map = {
@@ -532,6 +537,7 @@ class EnableEditingAssignedMaterial(bpy.types.Operator):
18: "right in line with the shear centre",
19: "top in line with the shear centre",
}
assert prop
prop.data_type = "enum"
prop.enum_items = json.dumps(cardinal_point_map)
if data[name]:
@@ -30,6 +30,7 @@ import bonsai.tool as tool
from math import degrees
from mathutils import Vector, Matrix
from bonsai.bim.module.structural.decorator import LoadsDecorator
from typing import Literal
class ShowLoads(bpy.types.Operator):
@@ -40,6 +41,7 @@ class ShowLoads(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"}
def modal(self, context, event):
assert context.screen
if event.type == "F5":
LoadsDecorator.update()
for area in context.screen.areas:
@@ -54,6 +56,7 @@ class ShowLoads(bpy.types.Operator):
return {"PASS_THROUGH"}
def invoke(self, context, event):
assert context.window and context.window_manager and context.screen
collection = bpy.data.collections.get("IfcStructuralItem")
if collection is None:
self.report({"ERROR"}, "No IfcStructuralItems found.")
@@ -87,6 +90,7 @@ class AddStructuralMemberConnection(bpy.types.Operator, tool.Ifc.Operator):
props = tool.Structural.get_object_structural_props(obj)
file = tool.Ifc.get()
related_structural_connection = file.by_id(oprops.ifc_definition_id)
assert props.relating_structural_member
relating_structural_member = tool.Ifc.get_entity(props.relating_structural_member)
assert relating_structural_member
if not relating_structural_member.is_a("IfcStructuralMember"):
@@ -613,7 +617,7 @@ class EnableEditingStructuralLoadCase(bpy.types.Operator):
)
return {"FINISHED"}
def import_attributes(self, name, prop, data):
def import_attributes(self, name: str, prop: object, data: object) -> None | Literal[False]:
if name in ["SelfWeightCoefficients"]:
return False
+5 -3
View File
@@ -46,7 +46,7 @@ class Context(bonsai.core.tool.Context):
props.context_attributes.clear()
context = cls.get_context()
def callback(name: str, prop, data) -> Union[bool, None]:
def callback(name: str, prop: Union[Attribute, None], data: dict[str, Any]) -> Union[bool, None]:
if context.is_a("IfcGeometricRepresentationSubContext"):
if name == "Precision":
props.context_attributes.remove(props.context_attributes.find("Precision"))
@@ -57,8 +57,9 @@ class Context(bonsai.core.tool.Context):
elif name == "TargetScale":
props.context_attributes.remove(props.context_attributes.find("TargetScale"))
scale_denominator = None
if data.get(name) is not None and data.get(name) != 0:
scale_denominator = 1.0 / data.get(name)
value = data.get(name)
if value not in (None, 0):
scale_denominator = 1.0 / value
new_prop = props.context_attributes.add()
new_prop.name = "ScaleDenominator"
new_prop.data_type = "float"
@@ -68,6 +69,7 @@ class Context(bonsai.core.tool.Context):
else: # IfcGeometricRepresentationContext
# Import precision as a string because Blender has problem displaying 1e-7 and smaller numbers in UI.
if name == "Precision":
assert prop
prop.data_type = "string"
bonsai.bim.helper.import_attributes(context.is_a(), props.context_attributes, context.get_info(), callback)
+11 -8
View File
@@ -22,6 +22,7 @@ import bonsai.core.tool
import bonsai.tool as tool
import ifcopenshell.api
import ifcopenshell.api.cost
import ifcopenshell.api.document
import ifcopenshell.api.nest
import ifcopenshell.util.element
import ifcopenshell.util.date
@@ -34,6 +35,7 @@ from typing import Optional, Any, Union, Literal, TYPE_CHECKING, assert_never
from collections.abc import Generator
if TYPE_CHECKING:
from bonsai.bim.prop import Attribute
from bonsai.bim.module.cost.prop import BIMCostProperties, CostItemQuantity
@@ -415,7 +417,13 @@ class Cost(bonsai.core.tool.Cost):
@classmethod
def load_cost_item_value_attributes(cls, cost_value: ifcopenshell.entity_instance) -> None:
def import_attributes(name, prop, data, cost_value, is_rates, props_collection):
props = cls.get_cost_props()
props.cost_value_attributes.clear()
props_collection = props.cost_value_attributes
# is_rates = cls.is_active_schedule_of_rates()
is_rates = True # so it is possible to assign a cost item rate that it not only from a Schedule of Rate
def import_attributes_callback(name: str, prop: Union[Attribute, None], data) -> None | Literal[True]:
if name == "AppliedValue":
# TODO: for now, only support simple IfcValues (which are effectively IfcMonetaryMeasure)
prop = props_collection.add()
@@ -452,14 +460,9 @@ class Cost(bonsai.core.tool.Cost):
break
return True
props = cls.get_cost_props()
props.cost_value_attributes.clear()
# is_rates = cls.is_active_schedule_of_rates()
is_rates = True # so it is possible to assign a cost item rate that it not only from a Schedule of Rate
callback = lambda name, prop, data: import_attributes(
name, prop, data, cost_value, is_rates, props.cost_value_attributes
bonsai.bim.helper.import_attributes2(
cost_value, props.cost_value_attributes, callback=import_attributes_callback
)
bonsai.bim.helper.import_attributes2(cost_value, props.cost_value_attributes, callback=callback)
@classmethod
def calculate_applied_value(
+1 -1
View File
@@ -91,7 +91,7 @@ class Owner(bonsai.core.tool.Owner):
address = cls.get_address()
def callback(name: str, prop, data: dict[str, Any]) -> None:
def callback(name: str, prop: object, data: dict[str, Any]) -> None:
if name in cls.ADDREESS_ATTRIBUTE_TYPES:
collection = cls.get_address_collection(name)
for line in data[name] or []:
@@ -20,11 +20,11 @@ import ifcopenshell
import ifcopenshell.api.spatial
import ifcopenshell.util.representation
from ifcopenshell import entity_instance
import typing
from typing import Union
def add_survey_point(
file: ifcopenshell.file, survey_point: entity_instance, site: entity_instance = None
file: ifcopenshell.file, survey_point: entity_instance, site: Union[entity_instance, None] = None
) -> entity_instance:
"""
Adds a single survey point to the model based on IFC Concept Template 4.1.7.1.2.5.