This commit is contained in:
Andrej730
2026-03-13 18:28:51 +05:00
parent 1576302caf
commit eba798c544
30 changed files with 142 additions and 75 deletions
+11 -2
View File
@@ -16,8 +16,9 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy.props
import bpy.types
from typing import TYPE_CHECKING
import bpy
class AuginProperties(bpy.types.PropertyGroup):
@@ -27,3 +28,11 @@ class AuginProperties(bpy.types.PropertyGroup):
project_name: bpy.props.StringProperty(name="Project Name")
project_filename: bpy.props.StringProperty(name="IFC Filename")
is_success: bpy.props.BoolProperty(name="Is Successful Upload", default=False)
if TYPE_CHECKING:
username: str
password: str
token: str
project_name: str
project_filename: str
is_success: bool
+18 -5
View File
@@ -663,10 +663,17 @@ class BIM_UL_cost_items_trait:
split2.label(text="Rate")
def draw_item(
self, context, layout: bpy.types.UILayout, data, item: CostProp.CostItem, icon, active_data, active_propname
self,
context,
layout: bpy.types.UILayout,
data: BIMCostProperties,
item: CostProp.CostItem,
icon,
active_data,
active_propname,
) -> None:
if item:
self.props = tool.Cost.get_cost_props()
self.props = data
cost_item = CostSchedulesData.data["cost_items"][item.ifc_definition_id]
row = layout.row(align=True)
@@ -812,10 +819,16 @@ class BIM_UL_cost_columns(UIList):
class BIM_UL_cost_item_types(UIList):
def draw_item(
self, context, layout: bpy.types.UILayout, data, item: CostProp.CostItemType, icon, active_data, active_propname
self,
context,
layout: bpy.types.UILayout,
data: BIMCostProperties,
item: CostProp.CostItemType,
icon,
active_data,
active_propname,
) -> None:
props = tool.Cost.get_cost_props()
cost_item = props.cost_items[props.active_cost_item_index]
cost_item = data.cost_items[data.active_cost_item_index]
if item:
row = layout.row(align=True)
@@ -19,6 +19,7 @@
import json
import bpy
import ifcopenshell.util.element
import bonsai.core.document as core
import bonsai.tool as tool
+22 -7
View File
@@ -26,7 +26,11 @@ from bpy.types import Panel, UIList
import bonsai.tool as tool
if TYPE_CHECKING:
from bonsai.bim.module.document.prop import Document, DocumentObject
from bonsai.bim.module.document.prop import (
BIMDocumentProperties,
Document,
DocumentObject,
)
from bonsai.bim.helper import draw_attributes
from bonsai.bim.module.document.data import DocumentData, ObjectDocumentData
@@ -217,7 +221,14 @@ class BIM_PT_object_documents(Panel):
class BIM_UL_documents(UIList):
def draw_item(
self, context, layout: bpy.types.UILayout, data, item: Document, icon, active_data, active_propname
self,
context,
layout: bpy.types.UILayout,
data: BIMDocumentProperties,
item: Document,
icon,
active_data,
active_propname,
) -> None:
if item:
row = layout.row(align=True)
@@ -264,17 +275,21 @@ class BIM_UL_documents(UIList):
class BIM_UL_document_objects(UIList):
def draw_item(
self, context, layout: bpy.types.UILayout, data, item: DocumentObject, icon, active_data, active_propname
self,
context,
layout: bpy.types.UILayout,
data: BIMDocumentProperties,
item: DocumentObject,
icon,
active_data,
active_propname,
) -> None:
if item:
row = layout.row(align=True)
row.prop(item, "name", text="", emboss=False, icon="OBJECT_DATA")
row.operator("bim.select_object", text="", icon="RESTRICT_SELECT_OFF").obj_name = item.name
props = tool.Document.get_document_props()
if props.active_document:
document = props.active_document
if document := data.active_document:
op = row.operator("bim.unassign_document", text="", icon="X")
op.document = document.ifc_definition_id
op.obj = item.name
@@ -22,7 +22,9 @@ from pathlib import Path
from typing import Any, Union
import bpy
import ifcopenshell.util.classification
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.unit
from natsort import natsorted
@@ -151,7 +151,7 @@ from bpy_extras.view3d_utils import (
)
from gpu_extras.batch import batch_for_shader
from ifcopenshell.util.unit import si_conversions
from mathutils import Matrix, Vector
from mathutils import Matrix, Vector, geometry
from mathutils.geometry import intersect_line_line
from mathutils.kdtree import KDTree
@@ -42,6 +42,7 @@ import bmesh
import bpy
import ifcopenshell
import ifcopenshell.api.document
import ifcopenshell.api.geometry
import ifcopenshell.api.pset
import ifcopenshell.api.style
import ifcopenshell.geom
+13
View File
@@ -16,6 +16,9 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from typing import TYPE_CHECKING
import bpy
from bpy.props import BoolProperty, CollectionProperty, EnumProperty, StringProperty
from bpy.types import PropertyGroup
@@ -37,3 +40,13 @@ class BIMCityJsonProperties(PropertyGroup):
lod: EnumProperty(name="LOD", description="", items=get_lods, options={"ANIMATABLE"}, default=None)
is_lod_found: BoolProperty(name="Is LOD Found", default=False)
load_after_convert: BoolProperty(name="Load After Converting", default=True)
if TYPE_CHECKING:
input: str
output: str
name: str
split_lod: bool
lods: bpy.types.bpy_prop_collection_idprop[StrProperty]
lod: str
is_lod_found: bool
load_after_convert: bool
@@ -19,7 +19,7 @@
from __future__ import annotations
import math
from math import cos, radians, sin, tan
from math import cos, pi, radians, sin, tan
from typing import Any, Literal
import blf
@@ -27,6 +27,10 @@ import bmesh
import bpy
import gpu
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.unit
import mathutils
from bpy.types import SpaceView3D
from bpy_extras import view3d_utils
@@ -35,6 +39,7 @@ from gpu_extras.batch import batch_for_shader
from gpu_extras.presets import draw_circle_2d
from mathutils import Matrix, Quaternion, Vector
import bonsai.core.geometry
import bonsai.tool as tool
from bonsai.bim.module.drawing.helper import format_distance
@@ -1566,7 +1571,7 @@ class ProductDecorator:
obj_type,
representation,
)
context.view_layer.update()
bpy.context.view_layer.update()
break
translate_mouse = Matrix.Translation(mouse_point)
@@ -733,6 +733,9 @@ class BIMStairProperties(PropertyGroup):
class BIMSverchokProperties(PropertyGroup):
node_group: bpy.props.PointerProperty(name="Node Group", type=NodeTree)
if TYPE_CHECKING:
node_group: bpy.types.NodeTree | None
def window_type_prop_update(self, context):
number_of_panels, panels_data = self.window_types_panels[self.window_type]
@@ -69,7 +69,7 @@ class CreateNewSverchokGraph(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER"}
def _execute(self, context):
import sverchok
import sverchok.ui.sv_temporal_viewers
obj = context.active_object
props = tool.Model.get_sverchok_props(obj)
@@ -193,7 +193,7 @@ class ImportSverchokGraph(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
filename_ext = ".json"
def _execute(self, context):
import sverchok
import sverchok.utils.sv_json_import
importer = sverchok.utils.sv_json_import.JSONImporter.init_from_path(self.filepath)
obj = context.active_object
@@ -232,7 +232,7 @@ class ExportSverchokGraph(bpy.types.Operator, tool.Ifc.Operator, ExportHelper):
compress: bpy.props.BoolProperty()
def _execute(self, context):
import sverchok
import sverchok.utils.sv_json_export
obj = context.active_object
props = tool.Model.get_sverchok_props(obj)
+1 -2
View File
@@ -810,11 +810,10 @@ class BIM_UL_task_columns(UIList):
active_data,
active_propname,
):
props = tool.Sequence.get_work_schedule_props()
if item:
row = layout.row(align=True)
row.prop(item, "name", emboss=False, text="")
if props.sort_column == item.name:
if data.sort_column == item.name:
row.label(text="", icon="SORTALPHA")
row.operator("bim.remove_task_column", text="", icon="X").name = item.name
+2 -3
View File
@@ -123,7 +123,6 @@ class BIM_UL_units(UIList):
active_data,
active_propname,
) -> None:
props = tool.Unit.get_unit_props()
if item:
icon = tool.Unit.get_icon_for_unit_class(item.ifc_class)
row = layout.row(align=True)
@@ -137,10 +136,10 @@ class BIM_UL_units(UIList):
op = row.operator("bim.assign_unit", text="", icon="KEYFRAME", emboss=False)
op.unit = item.ifc_definition_id
if props.active_unit_id == item.ifc_definition_id:
if data.active_unit_id == item.ifc_definition_id:
row.operator("bim.edit_unit", text="", icon="CHECKMARK").unit = item.ifc_definition_id
row.operator("bim.disable_editing_unit", text="", icon="CANCEL")
elif props.active_unit_id:
elif data.active_unit_id:
row.operator("bim.remove_unit", text="", icon="X").unit = item.ifc_definition_id
else:
op = row.operator("bim.enable_editing_unit", text="", icon="GREASEPENCIL")
+4 -4
View File
@@ -841,7 +841,7 @@ class Cad:
return new_verts
@classmethod
def region_2d_to_vector_3d_np(cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3d, coord: Vector) -> Vector:
def region_2d_to_vector_3d_np(cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3D, coord: Vector) -> Vector:
"""
Numpy version of view3d_utils.region_2d_to_vector_3d
Return a direction vector from the viewport at the specific 2d region
@@ -880,7 +880,7 @@ class Cad:
@classmethod
def region_2d_to_location_3d_np(
cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3d, coord: Vector, depth_location: Vector
cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3D, coord: Vector, depth_location: Vector
) -> Vector:
"""
Numpy version of view3d_utils.region_2d_to_location_3d
@@ -913,7 +913,7 @@ class Cad:
@classmethod
def region_2d_to_origin_3d_np(
cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3d, coord: Vector, *, clamp: float = None
cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3D, coord: Vector, *, clamp: float = None
) -> Vector:
"""
Numpy version of view3d_utils.region_2d_to_origin_3d
@@ -971,7 +971,7 @@ class Cad:
@classmethod
def location_3d_to_region_2d_np(
cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3d, coord: Vector, *, default=None
cls, region: bpy.types.Region, rv3d: bpy.types.RegionView3D, coord: Vector, *, default=None
) -> Vector:
"""
Numpy version of view3d_utils.location_3d_to_region_2d
+3 -2
View File
@@ -123,10 +123,11 @@ class Nest(bonsai.core.tool.Nest):
return {"FINISHED"}
@classmethod
def disable_nest_mode(cls):
def disable_nest_mode(cls) -> None:
props = cls.get_nest_props()
for obj_prop in props.not_editing_objects:
obj = obj_prop.obj
assert obj and obj.original
obj.original.display_type = obj_prop.previous_display_type
element = tool.Ifc.get_entity(obj)
if not element:
@@ -134,7 +135,7 @@ class Nest(bonsai.core.tool.Nest):
components = ifcopenshell.util.element.get_components(tool.Ifc.get_entity(props.editing_nest))
objs = [tool.Ifc.get_object(component) for component in components]
if context.space_data.local_view:
if bpy.context.space_data.local_view:
bpy.ops.view3d.localview()
props.in_nest_mode = False
+1 -1
View File
@@ -43,7 +43,7 @@ import ifcopenshell.util.shape_builder
import numpy as np
import numpy.typing as npt
from ifcopenshell.api.project.append_asset import APPENDABLE_ASSET_TYPES
from mathutils import Matrix
from mathutils import Matrix, Vector
import bonsai.bim.schema
import bonsai.core.aggregate
+1
View File
@@ -24,6 +24,7 @@ from typing import TYPE_CHECKING, Any, Literal, Union
import bpy
import ifcopenshell
import ifcopenshell.util.unit
from lark import Lark, Transformer
import bonsai.bim.helper
+2 -2
View File
@@ -273,8 +273,8 @@ if BPY_IS_LOADED:
f"Couldn't find locale path in the source directory, creating dummy directory: {source_locale_path}.",
)
from ui_translate.settings import (
settings as ui_translate_settings, # pyright: ignore[reportMissingImports]
from ui_translate.settings import ( # pyright: ignore[reportMissingImports]
settings as ui_translate_settings,
)
from ui_translate.update_ui import ( # pyright: ignore[reportMissingImports]
UI_OT_i18n_updatetranslation_init_settings,
+1
View File
@@ -23,6 +23,7 @@ import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.root
import ifcopenshell.api.system
import ifcopenshell.util.system
import ifcopenshell.util.unit
import numpy as np
from mathutils import Euler, Matrix, Vector
@@ -20,11 +20,11 @@ from __future__ import annotations
import math
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
import bmesh
import bpy.types
import bmesh # pyright: ignore[reportMissingImports]
import bpy # pyright: ignore[reportMissingImports]
import numpy as np
import numpy.typing as npt
from mathutils import Matrix, Vector
from mathutils import Matrix, Vector # pyright: ignore[reportMissingImports]
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
@@ -22,7 +22,7 @@ from typing import TYPE_CHECKING, Any, Optional
import ifcopenshell
if TYPE_CHECKING:
import bpy
import bpy # pyright: ignore[reportMissingImports]
def add_surface_textures(
@@ -33,14 +33,14 @@ def _has_occ():
# Previous versions (pythonocc<=0.17.3) are using just OCC.
try:
import OCC.Core.BRepTools
import OCC.Core.BRepTools # pyright: ignore[reportMissingImports]
return True
except ImportError:
pass
try:
import OCC.BRepTools # noqa: F401
import OCC.BRepTools # noqa: F401 # pyright: ignore[reportMissingImports]
return True
except ImportError:
@@ -28,7 +28,7 @@ from ..file import file
from . import has_occ
if TYPE_CHECKING:
from OCC.Core import TopoDS
from OCC.Core import TopoDS # pyright: ignore[reportMissingImports]
IteratorOutput = Union["ShapeElementType", "utils.shape_tuple"]
@@ -47,9 +47,9 @@ if has_occ:
from . import occ_utils as utils
try:
from OCC.Core import TopoDS
from OCC.Core import TopoDS # pyright: ignore[reportMissingImports]
except ImportError:
from OCC import TopoDS
from OCC import TopoDS # pyright: ignore[reportMissingImports]
def wrap_shape_creation(settings: settings, shape: ifcopenshell_wrapper.Element):
if getattr(settings, "use_python_opencascade", False):
@@ -26,17 +26,17 @@ import warnings
from collections.abc import Iterable
from typing import NamedTuple, Union
import OCC
import OCC # pyright: ignore[reportMissingImports]
from typing_extensions import assert_never
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
try:
from OCC.Core import AIS, BRepTools, Graphic3d, Quantity, TopoDS, V3d, gp
from OCC.Core import AIS, BRepTools, Graphic3d, Quantity, TopoDS, V3d, gp # pyright: ignore[reportMissingImports]
USE_OCCT_HANDLE = False
except ImportError:
from OCC import AIS, BRepTools, Graphic3d, Quantity, TopoDS, V3d, gp
from OCC import AIS, BRepTools, Graphic3d, Quantity, TopoDS, V3d, gp # pyright: ignore[reportMissingImports]
USE_OCCT_HANDLE = True
@@ -68,7 +68,7 @@ DEFAULT_STYLES = {
def initialize_display():
import OCC.Display.SimpleGui
import OCC.Display.SimpleGui # pyright: ignore[reportMissingImports]
global handle, main_loop, add_menu, add_function_to_menu
handle, main_loop, add_menu, add_function_to_menu = OCC.Display.SimpleGui.init_display()
@@ -40,7 +40,7 @@ if TYPE_CHECKING:
# NOTE: mathutils is never used at runtime in ifcopenshell,
# only for type checking to ensure methods are compatible with
# Blender vectors.
from mathutils import Vector
from mathutils import Vector # pyright: ignore[reportMissingImports]
# Support both numpy arrays and python sequences as inputs.
VectorType = Union[Sequence[float], Vector, np.ndarray]
@@ -60,7 +60,6 @@ from typing import TYPE_CHECKING, Any, Optional, Union
import ifcopenshell
import ifcopenshell.express.rule_executor
import ifcopenshell.ifcopenshell_wrapper
import ifcopenshell.ifcopenshell_wrapper as W
if TYPE_CHECKING:
import ifcopenshell.simple_spf
@@ -705,10 +704,10 @@ def validate_ifc_header(
log_error(header_entity, name, index, STRING_TYPE, type(value).__name__)
# Ignore header.file_schema as file won't load to IfcOpenShell with invalid file_schema.
file_description: W.FileDescription = header.file_description
file_description = header.file_description
validate_attribute(file_description, "description", 0, aggregate=True)
validate_attribute(file_description, "implementation_level", 1)
file_name: W.FileName = header.file_name
file_name = header.file_name
validate_attribute(file_name, "name", 0)
validate_attribute(file_name, "time_stamp", 1)
validate_attribute(file_name, "author", 2, aggregate=True)
+2 -2
View File
@@ -215,11 +215,11 @@ def _extract_docs(cls: type, method_name: str, boilerplate_args: Union[Sequence[
input_data = inputs[input_name]
# E.g. list[str].
if isinstance(type_hint, typing.GenericAlias):
if isinstance(type_hint, typing.GenericAlias): # pyright: ignore[reportAttributeAccessIssue]
input_data["generic_type"] = type_hint.__name__
type_hint = typing.get_args(type_hint)[0]
if isinstance(type_hint, typing._UnionGenericAlias):
if isinstance(type_hint, typing._UnionGenericAlias): # pyright: ignore[reportAttributeAccessIssue]
inputs[input_name]["type"] = [t.__name__ for t in typing.get_args(type_hint)]
elif type_hint.__name__ == "Literal":
inputs[input_name]["type"] = "Literal"
@@ -67,9 +67,9 @@ class Patcher:
def patch(self) -> None:
import bonsai.tool as tool
import bpy
import bpy # pyright: ignore[reportMissingImports]
import ifcopenshell.util.element
from mathutils import Matrix, Vector
from mathutils import Matrix, Vector # pyright: ignore[reportMissingImports]
if len(bpy.data.objects) > 0:
bpy.data.batch_remove(bpy.data.objects)
@@ -18,11 +18,15 @@
import logging
from typing import Optional
from typing import Optional, TYPE_CHECKING
import ifcopenshell
import ifcopenshell.util.shape_builder
if TYPE_CHECKING:
import bpy # pyright: ignore[reportMissingImports]
class Patcher:
def __init__(
@@ -109,12 +113,14 @@ class Patcher:
self.should_create_edges = should_create_edges
def patch(self) -> None:
import bmesh
import bmesh # pyright: ignore[reportMissingImports]
import bonsai.tool as tool
import bpy
import ifcopenshell.util.shape_builder
import bpy # pyright: ignore[reportMissingImports]
import ifcopenshell.util.schema
import ifcopenshell.util.unit
bpy.context.scene.BIMProjectProperties.should_use_native_meshes = True
props = tool.Project.get_project_props()
props.should_use_native_meshes = True
bpy.ops.bim.load_project(filepath=self.filepath)
old_history_size = tool.Ifc.get().history_size
@@ -125,7 +131,7 @@ class Patcher:
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
for obj in bpy.data.objects:
if not obj.BIMObjectProperties.ifc_definition_id or not obj.data:
if not tool.Blender.get_ifc_definition_id(obj) or not obj.data:
continue
if not obj.data.polygons:
continue
@@ -159,14 +165,14 @@ class Patcher:
self.file = tool.Ifc.get()
def create_edges(self, obj):
import bmesh
def create_edges(self, obj: bpy.types.Object) -> None:
import bmesh # pyright: ignore[reportMissingImports]
import bonsai.tool as tool
import bpy
import bpy # pyright: ignore[reportMissingImports]
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.schema
element = tool.Ifc.get_entity(obj)
data = obj.data
@@ -224,16 +230,16 @@ class Patcher:
ifcopenshell.util.schema.reassign_class(tool.Ifc.get(), element2, "IfcVirtualElement")
bm.free()
def create_face_sampleable_object(self, obj):
def create_face_sampleable_object(self, obj: bpy.types.Object) -> None:
# No sharp faces
from math import degrees
import bmesh
import bmesh # pyright: ignore[reportMissingImports]
import bonsai.tool as tool
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
print("working on ", obj.name)
element = tool.Ifc.get_entity(obj)
@@ -271,17 +277,17 @@ class Patcher:
bm.free()
def create_edge_sampleable_object(self, obj):
def create_edge_sampleable_object(self, obj: bpy.types.Object) -> None:
# This is crazy but we need a sharp face per island
from math import degrees, radians, sin
import bmesh
import bmesh # pyright: ignore[reportMissingImports]
import bonsai.tool as tool
import ifcopenshell.api.geometry
import ifcopenshell.api.root
import ifcopenshell.util.element
import ifcopenshell.util.representation
from mathutils import Matrix
import ifcopenshell.util.shape_builder
from mathutils import Matrix # pyright: ignore[reportMissingImports]
# Get the active object (assumed to have a mesh)
mesh = obj.data
@@ -430,7 +436,6 @@ class Patcher:
bm.free()
print("Added a triangle to", islands_count, "mesh island(s).")
return
def create_curves_from_curve_ifc2x3(
self, is_2d: bool = False, curve_object_data=None
@@ -80,9 +80,9 @@ class Patcher:
def patch(self) -> None:
from math import degrees
import bmesh
import bmesh # pyright: ignore[reportMissingImports]
import bonsai.tool as tool
import bpy
import bpy # pyright: ignore[reportMissingImports]
props = tool.Project.get_project_props()
props.should_use_native_meshes = True