This commit is contained in:
Andrej730
2026-03-12 20:19:34 +05:00
parent 71442bd4d4
commit 77697aeefc
13 changed files with 93 additions and 29 deletions
+1
View File
@@ -747,6 +747,7 @@ class IfcImporter:
self.update_progress((percent_average / 100 * progress_range) + start_progress) self.update_progress((percent_average / 100 * progress_range) + start_progress)
shape = iterator.get() shape = iterator.get()
if shape: if shape:
assert isinstance(shape, W.TriangulationElement)
product = self.file.by_id(shape.id) product = self.file.by_id(shape.id)
self.create_product(product, shape) self.create_product(product, shape)
results.add(product) results.add(product)
@@ -27,6 +27,7 @@ import ifcopenshell.api
import ifcopenshell.api.boundary import ifcopenshell.api.boundary
import ifcopenshell.api.root import ifcopenshell.api.root
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.shape import ifcopenshell.util.shape
@@ -701,6 +702,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
while True: while True:
tree.add_element(iterator.get_native()) tree.add_element(iterator.get_native())
shape = iterator.get() shape = iterator.get()
assert isinstance(shape, W.TriangulationElement)
shapes[shape.id] = { shapes[shape.id] = {
"verts": ifcopenshell.util.shape.get_vertices(shape.geometry), "verts": ifcopenshell.util.shape.get_vertices(shape.geometry),
"faces": ifcopenshell.util.shape.get_faces(shape.geometry), "faces": ifcopenshell.util.shape.get_faces(shape.geometry),
+12 -1
View File
@@ -16,9 +16,18 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING
import bpy
from bpy.types import Panel, UIList from bpy.types import Panel, UIList
import bonsai.tool as tool import bonsai.tool as tool
if TYPE_CHECKING:
from bonsai.bim.module.brick.prop import Brick
from bonsai.bim.helper import prop_with_search from bonsai.bim.helper import prop_with_search
from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
from bonsai.tool.brick import BrickStore from bonsai.tool.brick import BrickStore
@@ -274,7 +283,9 @@ class BIM_PT_brickschema_viewport(Panel):
class BIM_UL_bricks(UIList): class BIM_UL_bricks(UIList):
split_screen = False split_screen = False
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: Brick, icon, active_data, active_propname
) -> None:
if item: if item:
split = layout.split(factor=0.85, align=True) split = layout.split(factor=0.85, align=True)
row = split.row() row = split.row()
+27 -11
View File
@@ -26,10 +26,11 @@ from bpy.types import Panel, UIList
import bonsai.bim.helper import bonsai.bim.helper
import bonsai.bim.module.cost.prop as CostProp import bonsai.bim.module.cost.prop as CostProp
import bonsai.tool as tool import bonsai.tool as tool
from bonsai.bim.module.cost.data import CostSchedulesData from bonsai.bim.module.cost.data import CostItem, CostSchedulesData
if TYPE_CHECKING: if TYPE_CHECKING:
from bonsai.bim.module.cost.prop import BIMCostProperties, CostItemQuantity from bonsai.bim.module.cost.prop import BIMCostProperties, CostItemQuantity
from bonsai.bim.prop import StrProperty
class BIM_PT_cost_schedules(Panel): class BIM_PT_cost_schedules(Panel):
@@ -661,7 +662,9 @@ class BIM_UL_cost_items_trait:
split2.alignment = "LEFT" split2.alignment = "LEFT"
split2.label(text="Rate") split2.label(text="Rate")
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: CostProp.CostItem, icon, active_data, active_propname
) -> None:
if item: if item:
self.props = tool.Cost.get_cost_props() self.props = tool.Cost.get_cost_props()
cost_item = CostSchedulesData.data["cost_items"][item.ifc_definition_id] cost_item = CostSchedulesData.data["cost_items"][item.ifc_definition_id]
@@ -694,7 +697,7 @@ class BIM_UL_cost_items_trait:
# TODO: reimplement "bim.copy_cost_item_values" somewhere with better UX # TODO: reimplement "bim.copy_cost_item_values" somewhere with better UX
def draw_parent_operator(self, row, cost_item_id): def draw_parent_operator(self, row: bpy.types.UILayout, cost_item_id: int) -> None:
if self.props.active_cost_item_id: if self.props.active_cost_item_id:
if self.props.active_cost_item_id != cost_item_id: if self.props.active_cost_item_id != cost_item_id:
op = row.operator("bim.change_parent_cost_item", text="", icon="LINKED", emboss=False).new_parent = ( op = row.operator("bim.change_parent_cost_item", text="", icon="LINKED", emboss=False).new_parent = (
@@ -703,7 +706,7 @@ class BIM_UL_cost_items_trait:
else: else:
row.label(text="", icon="BLANK1") row.label(text="", icon="BLANK1")
def draw_hierarchy(self, row, item): def draw_hierarchy(self, row: bpy.types.UILayout, item: CostProp.CostItem) -> None:
for i in range(0, item.level_index): for i in range(0, item.level_index):
row.label(text="", icon="BLANK1") row.label(text="", icon="BLANK1")
if item.has_children: if item.has_children:
@@ -749,7 +752,7 @@ class BIM_UL_cost_items_trait:
else: else:
row.label(text="-") row.label(text="-")
def draw_value_column(self, layout, cost_item): def draw_value_column(self, layout: bpy.types.UILayout, cost_item: CostItem) -> None:
if cost_item["TotalAppliedValue"]: if cost_item["TotalAppliedValue"]:
text = "{0:,.2f}".format(cost_item["TotalAppliedValue"]).replace(",", " ") text = "{0:,.2f}".format(cost_item["TotalAppliedValue"]).replace(",", " ")
if cost_item["UnitBasisValueComponent"] not in [None, 1]: if cost_item["UnitBasisValueComponent"] not in [None, 1]:
@@ -760,13 +763,13 @@ class BIM_UL_cost_items_trait:
else: else:
layout.label(text="-") layout.label(text="-")
def draw_total_cost_column(self, layout, cost_item): def draw_total_cost_column(self, layout: bpy.types.UILayout, cost_item: CostItem) -> None:
format_numbers = "{0:,.2f}".format(cost_item["TotalCost"]).replace(",", " ") format_numbers = "{0:,.2f}".format(cost_item["TotalCost"]).replace(",", " ")
currency = CostSchedulesData.data["currency"] currency = CostSchedulesData.data["currency"]
text = "{} {}".format(format_numbers, currency["name"]) if currency else format_numbers text = "{} {}".format(format_numbers, currency["name"]) if currency else format_numbers
layout.label(text=text) layout.label(text=text)
def draw_order_operator(self, row, ifc_definition_id, cost_item): def draw_order_operator(self, row: bpy.types.UILayout, ifc_definition_id: int, cost_item: CostItem) -> None:
if cost_item["NestingIndex"] is not None: if cost_item["NestingIndex"] is not None:
if cost_item["NestingIndex"] == 0: if cost_item["NestingIndex"] == 0:
op = row.operator("bim.reorder_cost_item_nesting", icon="TRIA_DOWN", text="") op = row.operator("bim.reorder_cost_item_nesting", icon="TRIA_DOWN", text="")
@@ -793,12 +796,14 @@ class BIM_UL_cost_item_rates(BIM_UL_cost_items_trait, UIList):
def draw_quantity_column(self, layout, cost_item): def draw_quantity_column(self, layout, cost_item):
self.draw_uom_column(layout, cost_item) self.draw_uom_column(layout, cost_item)
def draw_total_cost_column(self, layout, cost_item): def draw_total_cost_column(self, layout: bpy.types.UILayout, cost_item: CostItem) -> None:
pass # No such thing as a total cost in a schedule of rates pass # No such thing as a total cost in a schedule of rates
class BIM_UL_cost_columns(UIList): class BIM_UL_cost_columns(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: StrProperty, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.prop(item, "name", emboss=False, text="") row.prop(item, "name", emboss=False, text="")
@@ -806,7 +811,9 @@ class BIM_UL_cost_columns(UIList):
class BIM_UL_cost_item_types(UIList): class BIM_UL_cost_item_types(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: CostProp.CostItemType, icon, active_data, active_propname
) -> None:
props = tool.Cost.get_cost_props() props = tool.Cost.get_cost_props()
cost_item = props.cost_items[props.active_cost_item_index] cost_item = props.cost_items[props.active_cost_item_index]
@@ -844,7 +851,16 @@ class BIM_UL_cost_item_quantities(UIList):
class BIM_UL_product_cost_items(UIList): class BIM_UL_product_cost_items(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self,
context,
layout: bpy.types.UILayout,
data,
item: CostItemQuantity,
icon,
active_data,
active_propname,
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
op = row.operator("bim.highlight_product_cost_item", text="", icon="STYLUS_PRESSURE") op = row.operator("bim.highlight_product_cost_item", text="", icon="STYLUS_PRESSURE")
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Union from typing import TYPE_CHECKING, Literal, Union
import bpy import bpy
from bpy.props import ( from bpy.props import (
@@ -66,7 +66,7 @@ class Document(PropertyGroup):
tree_depth: int tree_depth: int
has_children: bool has_children: bool
is_expanded: bool is_expanded: bool
document_type: str document_type: Literal["PROJECT", "INFORMATION", "REFERENCE"]
class DocumentObject(PropertyGroup): class DocumentObject(PropertyGroup):
+15 -2
View File
@@ -16,9 +16,18 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING
import bpy
from bpy.types import Panel, UIList from bpy.types import Panel, UIList
import bonsai.tool as tool import bonsai.tool as tool
if TYPE_CHECKING:
from bonsai.bim.module.document.prop import Document, DocumentObject
from bonsai.bim.helper import draw_attributes from bonsai.bim.helper import draw_attributes
from bonsai.bim.module.document.data import DocumentData, ObjectDocumentData from bonsai.bim.module.document.data import DocumentData, ObjectDocumentData
@@ -207,7 +216,9 @@ class BIM_PT_object_documents(Panel):
class BIM_UL_documents(UIList): class BIM_UL_documents(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: Document, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
indent_depth = 0 indent_depth = 0
@@ -252,7 +263,9 @@ class BIM_UL_documents(UIList):
class BIM_UL_document_objects(UIList): class BIM_UL_document_objects(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: DocumentObject, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.prop(item, "name", text="", emboss=False, icon="OBJECT_DATA") row.prop(item, "name", text="", emboss=False, icon="OBJECT_DATA")
@@ -30,6 +30,7 @@ from typing import TYPE_CHECKING, Union
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.geolocation import ifcopenshell.util.geolocation
import pyradiance as pr import pyradiance as pr
import requests import requests
@@ -106,9 +107,8 @@ class ExportOBJ(bpy.types.Operator):
if iterator.initialize(): if iterator.initialize():
while True: while True:
shape = iterator.get() shape = iterator.get()
assert isinstance(shape, W.TriangulationElement)
materials = shape.geometry.materials materials = shape.geometry.materials
material_ids = shape.geometry.material_ids
# material_names = shape.geometry.material_names
for material in materials: for material in materials:
ifc_materials.append(material.name) ifc_materials.append(material.name)
@@ -2142,6 +2142,7 @@ class LoadLinkedProject(bpy.types.Operator, ImportHelper):
if iterator.initialize(): if iterator.initialize():
while True: # Main loop. while True: # Main loop.
shape = iterator.get() shape = iterator.get()
assert isinstance(shape, W.TriangulationElement)
results.add(self.file.by_id(shape.id)) results.add(self.file.by_id(shape.id))
geometry = shape.geometry geometry = shape.geometry
+1 -1
View File
@@ -255,7 +255,7 @@ class BIM_PT_project(Panel):
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.operator("bim.load_project_elements") row.operator("bim.load_project_elements")
def draw_editing_buttons(self, context, row): def draw_editing_buttons(self, context: object, row: bpy.types.UILayout) -> None:
pprops = self.props pprops = self.props
if tool.Ifc.get(): if tool.Ifc.get():
if pprops.is_editing: if pprops.is_editing:
+21 -6
View File
@@ -37,8 +37,11 @@ from bonsai.bim.module.sequence.data import (
if TYPE_CHECKING: if TYPE_CHECKING:
from bonsai.bim.module.sequence.prop import ( from bonsai.bim.module.sequence.prop import (
BIMTaskTreeProperties, BIMTaskTreeProperties,
BIMTaskTypeColor,
BIMWorkScheduleProperties, BIMWorkScheduleProperties,
Task, Task,
TaskProduct,
TaskResource,
) )
from bonsai.bim.prop import Attribute from bonsai.bim.prop import Attribute
@@ -815,7 +818,9 @@ class BIM_UL_task_columns(UIList):
class BIM_UL_task_inputs(UIList): class BIM_UL_task_inputs(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: TaskProduct, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
op = row.operator("bim.select_product", text="", icon="RESTRICT_SELECT_OFF") op = row.operator("bim.select_product", text="", icon="RESTRICT_SELECT_OFF")
@@ -825,7 +830,9 @@ class BIM_UL_task_inputs(UIList):
class BIM_UL_task_resources(UIList): class BIM_UL_task_resources(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: TaskResource, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.go_to_resource", text="", icon="STYLUS_PRESSURE").resource = item.ifc_definition_id row.operator("bim.go_to_resource", text="", icon="STYLUS_PRESSURE").resource = item.ifc_definition_id
@@ -834,7 +841,9 @@ class BIM_UL_task_resources(UIList):
class BIM_UL_animation_colors(UIList): class BIM_UL_animation_colors(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: BIMTaskTypeColor, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row() row = layout.row()
row.prop(item, "color", text="") row.prop(item, "color", text="")
@@ -842,7 +851,9 @@ class BIM_UL_animation_colors(UIList):
class BIM_UL_task_outputs(UIList): class BIM_UL_task_outputs(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: TaskProduct, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
op = row.operator("bim.select_product", text="", icon="RESTRICT_SELECT_OFF") op = row.operator("bim.select_product", text="", icon="RESTRICT_SELECT_OFF")
@@ -851,7 +862,9 @@ class BIM_UL_task_outputs(UIList):
class BIM_UL_product_input_tasks(UIList): class BIM_UL_product_input_tasks(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: TaskProduct, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
op = row.operator("bim.go_to_task", text="", icon="STYLUS_PRESSURE") op = row.operator("bim.go_to_task", text="", icon="STYLUS_PRESSURE")
@@ -861,7 +874,9 @@ class BIM_UL_product_input_tasks(UIList):
class BIM_UL_product_output_tasks(UIList): class BIM_UL_product_output_tasks(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: TaskProduct, icon, active_data, active_propname
) -> None:
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
op = row.operator("bim.go_to_task", text="", icon="STYLUS_PRESSURE") op = row.operator("bim.go_to_task", text="", icon="STYLUS_PRESSURE")
+1 -1
View File
@@ -357,7 +357,7 @@ class BIM_UL_elements(UIList):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.use_filter_show = True self.use_filter_show = True
def draw_toggle(self, row: bpy.types.UILayout, is_expanded: bool, index: int): def draw_toggle(self, row: bpy.types.UILayout, is_expanded: bool, index: int) -> None:
icon_id = "DISCLOSURE_TRI_DOWN" if is_expanded else "DISCLOSURE_TRI_RIGHT" icon_id = "DISCLOSURE_TRI_DOWN" if is_expanded else "DISCLOSURE_TRI_RIGHT"
row.operator("bim.toggle_container_element", text="", emboss=False, icon=icon_id).element_index = index row.operator("bim.toggle_container_element", text="", emboss=False, icon=icon_id).element_index = index
+5 -1
View File
@@ -29,6 +29,8 @@ from bonsai.bim.module.void.data import BooleansData, VoidsData
if TYPE_CHECKING: if TYPE_CHECKING:
import bpy.stub_internal.rna_enums as rna_enums import bpy.stub_internal.rna_enums as rna_enums
from bonsai.bim.module.void.prop import Boolean
OPENING_ICON = "SELECT_SUBTRACT" OPENING_ICON = "SELECT_SUBTRACT"
FILLING_ICON = "SELECT_INTERSECT" FILLING_ICON = "SELECT_INTERSECT"
@@ -175,7 +177,9 @@ class BIM_PT_booleans(Panel):
class BIM_UL_booleans(UIList): class BIM_UL_booleans(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(
self, context, layout: bpy.types.UILayout, data, item: Boolean, icon, active_data, active_propname
) -> None:
if item: if item:
if item.operator == "DIFFERENCE": if item.operator == "DIFFERENCE":
icon = "SELECT_DIFFERENCE" icon = "SELECT_DIFFERENCE"
+3 -2
View File
@@ -1032,7 +1032,6 @@ class BIM_PT_tabs(Panel):
if not UIData.is_loaded: if not UIData.is_loaded:
UIData.load() UIData.load()
aprops = tool.Blender.get_active_area_props(context) aprops = tool.Blender.get_active_area_props(context)
addon_prefs = tool.Blender.get_addon_preferences()
row = self.layout.row() row = self.layout.row()
row.alignment = "CENTER" row.alignment = "CENTER"
@@ -1119,7 +1118,9 @@ class BIM_PT_tabs(Panel):
op = row.operator("bim.open_uri", text="", icon="QUESTION") op = row.operator("bim.open_uri", text="", icon="QUESTION")
op.uri = "https://docs.bonsaibim.org/guides/troubleshooting.html#incompatible-blender-features" op.uri = "https://docs.bonsaibim.org/guides/troubleshooting.html#incompatible-blender-features"
def draw_tab_entry(self, row, icon, tab_name, enabled=True, highlight=True): def draw_tab_entry(
self, row: bpy.types.UILayout, icon: int | str, tab_name: str, enabled: bool = True, highlight: bool = True
) -> None:
tab_entry = row.row(align=True) tab_entry = row.row(align=True)
if isinstance(icon, int): if isinstance(icon, int):
tab_entry.operator("bim.set_tab", text="", emboss=highlight, icon_value=icon).tab = tab_name tab_entry.operator("bim.set_tab", text="", emboss=highlight, icon_value=icon).tab = tab_name