Merge branch 'v0.8.0' of https://github.com/IfcOpenShell/IfcOpenShell into light/newUI

This commit is contained in:
Chirag Singh
2026-02-10 13:37:05 +05:30
1498 changed files with 75982 additions and 51592 deletions
-64
View File
@@ -1,64 +0,0 @@
# ****************************************************************************
# line endings
# to suppress line ending changes in github, add ?w=1 at link end of a diff
# for more information see
# FreeCAD source code src/Mod/.gitattributes
# FreeCAD forum topic https://forum.freecadweb.org/viewtopic.php?f=17&t=41117
# FreeCAD pull request https://github.com/FreeCAD/FreeCAD/pull/2752
# get all used file types
# in a directory in a bash use
# find . -type f -name '*.*' | sed 's|.*\.||' | sort -u
# search for a specific file ending
# find . -type f -name '*.ico'
# normalize the line endings of the following files
*.cpp text
*.css text
*.csv text
*.feature text
*.gitattributes text
*.gitignore text
*.gitkeep
*.h text
*.html text
*.ifc text
*.json text
*.md text
*.po text
*.pot text
*.py text
*.txt text
# files not normalized ATM
# bat
# bnf
# blend
# i
# ico
# mo
# mpass
# png
# pth
# pyc
# rst
# svg
# ttf
# xsd
# line endings of all directories will be normalized
# to exclude a directory from being normalized add it here
# example: to exclude dirctory ifcbimtester use the following line without #
# ifcbimtester/** -text
# use git to manually correct the file endings
# git add --renormalize .
+3 -2
View File
@@ -1,7 +1,8 @@
from dataclasses import fields
from typing import NamedTuple, Union
import bcf.v2.model.extensions
import bcf.v3.model.extensions
from typing import NamedTuple, Union
from dataclasses import fields
class AttributeData(NamedTuple):
+2 -1
View File
@@ -1,6 +1,7 @@
from typing import Union
import bcf.v2.model
import bcf.v3.model
from typing import Union
BimSnippet = Union[bcf.v2.model.BimSnippet, bcf.v3.model.BimSnippet]
BitMap = Union[bcf.v2.model.VisualizationInfoBitmap, bcf.v3.model.Bitmap]
+6 -4
View File
@@ -1,14 +1,16 @@
import tempfile
from pathlib import Path
from typing import Optional, Union
from typing_extensions import assert_never
import bcf.agnostic.model as mdl
import bcf.v2.bcfxml
import bcf.v2.model
import bcf.v2.topic
import bcf.v3.bcfxml
import bcf.v3.model
import bcf.v3.topic
import bcf.agnostic.model as mdl
from pathlib import Path
from typing import Union, Optional
from typing_extensions import assert_never
TopicHandler = Union[bcf.v2.topic.TopicHandler, bcf.v3.topic.TopicHandler]
+3 -2
View File
@@ -1,5 +1,6 @@
import bcf.v2.visinfo
import bcf.v3.visinfo
from typing import Union
import bcf.v2.visinfo
import bcf.v3.visinfo
VisualizationInfoHandler = Union[bcf.v2.visinfo.VisualizationInfoHandler, bcf.v3.visinfo.VisualizationInfoHandler]
-1
View File
@@ -29,7 +29,6 @@ from bcf.v3.bcfxml import BcfXml as BcfXml3
from bcf.v3.model import Version as Version3
from bcf.xml_parser import AbstractXmlParserSerializer, XmlParserSerializer
BcfXml = Union[BcfXml2, BcfXml3]
+2 -1
View File
@@ -7,6 +7,7 @@ original idea from https://stackoverflow.com/a/19722365/1307905
"""
from __future__ import annotations
import zipfile
from io import BytesIO
from os import PathLike
@@ -26,7 +27,7 @@ class InMemoryZipFile:
self._file_name: Optional[str | Path] = str(file_name) if hasattr(file_name, "_from_parts") else file_name
self.in_memory_data = BytesIO()
# Create the in-memory zipfile
self.in_memory_zip = zipfile.ZipFile(self.in_memory_data, "w", compression, False)
self.in_memory_zip = zipfile.ZipFile(self.in_memory_data, "w", compression, True)
self.in_memory_zip.debug = debug
def writestr(self, filename_in_zip: str | zipfile.ZipInfo, file_contents: bytes | str) -> None:
+1
View File
@@ -1,6 +1,7 @@
"""BCF XML V2 handler."""
from __future__ import annotations
import uuid
import warnings
import zipfile
+9 -13
View File
@@ -14,15 +14,11 @@
# Currently extensions support for v2 is only read-only.
import sys
from dataclasses import dataclass, field, fields
from dataclasses import dataclass, field
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsPriorities:
class Meta:
global_type = False
@@ -39,7 +35,7 @@ class ExtensionsPriorities:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsSnippetTypes:
class Meta:
global_type = False
@@ -56,7 +52,7 @@ class ExtensionsSnippetTypes:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsStages:
class Meta:
global_type = False
@@ -73,7 +69,7 @@ class ExtensionsStages:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsTopicLabels:
class Meta:
global_type = False
@@ -90,7 +86,7 @@ class ExtensionsTopicLabels:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsTopicStatuses:
class Meta:
global_type = False
@@ -107,7 +103,7 @@ class ExtensionsTopicStatuses:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsTopicTypes:
class Meta:
global_type = False
@@ -124,7 +120,7 @@ class ExtensionsTopicTypes:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsUsers:
class Meta:
global_type = False
@@ -141,7 +137,7 @@ class ExtensionsUsers:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Extensions:
topic_types: Optional[ExtensionsTopicTypes] = field(
default=None,
+10 -13
View File
@@ -1,13 +1,10 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
from xsdata.models.datatype import XmlDateTime
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class BimSnippet:
reference: str = field(
metadata={
@@ -41,7 +38,7 @@ class BimSnippet:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class CommentViewpoint:
class Meta:
global_type = False
@@ -56,7 +53,7 @@ class CommentViewpoint:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class HeaderFile:
class Meta:
global_type = False
@@ -112,7 +109,7 @@ class HeaderFile:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicDocumentReference:
class Meta:
global_type = False
@@ -150,7 +147,7 @@ class TopicDocumentReference:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicRelatedTopic:
class Meta:
global_type = False
@@ -165,7 +162,7 @@ class TopicRelatedTopic:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ViewPoint:
viewpoint: Optional[str] = field(
default=None,
@@ -201,7 +198,7 @@ class ViewPoint:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Comment:
date: XmlDateTime = field(
metadata={
@@ -261,7 +258,7 @@ class Comment:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Header:
file: list[HeaderFile] = field(
default_factory=list,
@@ -274,7 +271,7 @@ class Header:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Topic:
reference_link: list[str] = field(
default_factory=list,
@@ -428,7 +425,7 @@ class Topic:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Markup:
header: Optional[Header] = field(
default=None,
+2 -5
View File
@@ -1,11 +1,8 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Project:
name: Optional[str] = field(
default=None,
@@ -24,7 +21,7 @@ class Project:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ProjectExtension:
project: Optional[Project] = field(
default=None,
+1 -4
View File
@@ -1,11 +1,8 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Version:
detailed_version: Optional[str] = field(
default=None,
+18 -21
View File
@@ -1,17 +1,14 @@
import sys
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
class BitmapFormat(Enum):
PNG = "PNG"
JPG = "JPG"
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Component:
originating_system: Optional[str] = field(
default=None,
@@ -38,7 +35,7 @@ class Component:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Direction:
x: float = field(
metadata={
@@ -63,7 +60,7 @@ class Direction:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Point:
x: float = field(
metadata={
@@ -88,7 +85,7 @@ class Point:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ViewSetupHints:
spaces_visible: Optional[bool] = field(
default=None,
@@ -113,7 +110,7 @@ class ViewSetupHints:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ClippingPlane:
location: Point = field(
metadata={
@@ -131,7 +128,7 @@ class ClippingPlane:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentColoringColor:
class Meta:
global_type = False
@@ -154,7 +151,7 @@ class ComponentColoringColor:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentSelection:
component: list[Component] = field(
default_factory=list,
@@ -166,7 +163,7 @@ class ComponentSelection:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentVisibilityExceptions:
class Meta:
global_type = False
@@ -181,7 +178,7 @@ class ComponentVisibilityExceptions:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Line:
start_point: Point = field(
metadata={
@@ -199,7 +196,7 @@ class Line:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class OrthogonalCamera:
"""
Attributes
@@ -239,7 +236,7 @@ class OrthogonalCamera:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class PerspectiveCamera:
"""
Attributes
@@ -284,7 +281,7 @@ class PerspectiveCamera:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfoBitmap:
class Meta:
global_type = False
@@ -333,7 +330,7 @@ class VisualizationInfoBitmap:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentColoring:
color: list[ComponentColoringColor] = field(
default_factory=list,
@@ -345,7 +342,7 @@ class ComponentColoring:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentVisibility:
exceptions: Optional[ComponentVisibilityExceptions] = field(
default=None,
@@ -363,7 +360,7 @@ class ComponentVisibility:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfoClippingPlanes:
class Meta:
global_type = False
@@ -377,7 +374,7 @@ class VisualizationInfoClippingPlanes:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfoLines:
class Meta:
global_type = False
@@ -392,7 +389,7 @@ class VisualizationInfoLines:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Components:
view_setup_hints: Optional[ViewSetupHints] = field(
default=None,
@@ -424,7 +421,7 @@ class Components:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfo:
"""
VisualizationInfo documentation.
+2 -2
View File
@@ -1,12 +1,12 @@
"""BCF XML V2 Topic handler."""
from __future__ import annotations
import datetime
import tempfile
import uuid
import zipfile
from pathlib import Path
from typing import Any, NoReturn, Optional, Union
from typing import Any, NoReturn, Optional
import numpy as np
from ifcopenshell import entity_instance
+3 -3
View File
@@ -1,12 +1,12 @@
import uuid
import zipfile
from typing import Any, Optional, Literal, Union
from collections.abc import Iterable
from typing import Literal, Optional, Union
import ifcopenshell.util.placement
import ifcopenshell.util.unit
import numpy as np
from ifcopenshell import entity_instance
import ifcopenshell.util.unit
import ifcopenshell.util.placement
from numpy.typing import NDArray
import bcf.v2.model as mdl
-1
View File
@@ -24,7 +24,6 @@ import time
import urllib.parse
import uuid
import webbrowser
from re import A
from typing import Any, Optional
import requests
+1
View File
@@ -1,6 +1,7 @@
"""BCF XML V3 handlers."""
from __future__ import annotations
import uuid
import warnings
import zipfile
+1 -1
View File
@@ -1,7 +1,7 @@
"""BCF XML V3 Documents handler."""
import zipfile
from typing import Any, Optional
from typing import Optional
import bcf.v3.model as mdl
from bcf.inmemory_zipfile import ZipFileInterface
+3 -6
View File
@@ -1,11 +1,8 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Document:
filename: str = field(
metadata={
@@ -37,7 +34,7 @@ class Document:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class DocumentInfoDocuments:
class Meta:
global_type = False
@@ -52,7 +49,7 @@ class DocumentInfoDocuments:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class DocumentInfo:
documents: Optional[DocumentInfoDocuments] = field(
default=None,
+8 -11
View File
@@ -1,11 +1,8 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsPriorities:
class Meta:
global_type = False
@@ -22,7 +19,7 @@ class ExtensionsPriorities:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsSnippetTypes:
class Meta:
global_type = False
@@ -39,7 +36,7 @@ class ExtensionsSnippetTypes:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsStages:
class Meta:
global_type = False
@@ -56,7 +53,7 @@ class ExtensionsStages:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsTopicLabels:
class Meta:
global_type = False
@@ -73,7 +70,7 @@ class ExtensionsTopicLabels:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsTopicStatuses:
class Meta:
global_type = False
@@ -90,7 +87,7 @@ class ExtensionsTopicStatuses:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsTopicTypes:
class Meta:
global_type = False
@@ -107,7 +104,7 @@ class ExtensionsTopicTypes:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ExtensionsUsers:
class Meta:
global_type = False
@@ -124,7 +121,7 @@ class ExtensionsUsers:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Extensions:
topic_types: Optional[ExtensionsTopicTypes] = field(
default=None,
+17 -20
View File
@@ -1,13 +1,10 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
from xsdata.models.datatype import XmlDateTime
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class BimSnippet:
reference: str = field(
metadata={
@@ -47,7 +44,7 @@ class BimSnippet:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class CommentViewpoint:
class Meta:
global_type = False
@@ -62,7 +59,7 @@ class CommentViewpoint:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class DocumentReference:
document_guid: Optional[str] = field(
default=None,
@@ -103,7 +100,7 @@ class DocumentReference:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class File:
filename: Optional[str] = field(
default=None,
@@ -160,7 +157,7 @@ class File:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicLabels:
class Meta:
global_type = False
@@ -177,7 +174,7 @@ class TopicLabels:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicReferenceLinks:
class Meta:
global_type = False
@@ -194,7 +191,7 @@ class TopicReferenceLinks:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicRelatedTopicsRelatedTopic:
class Meta:
global_type = False
@@ -209,7 +206,7 @@ class TopicRelatedTopicsRelatedTopic:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ViewPoint:
viewpoint: Optional[str] = field(
default=None,
@@ -249,7 +246,7 @@ class ViewPoint:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Comment:
date: XmlDateTime = field(
metadata={
@@ -315,7 +312,7 @@ class Comment:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class HeaderFiles:
class Meta:
global_type = False
@@ -330,7 +327,7 @@ class HeaderFiles:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicDocumentReferences:
class Meta:
global_type = False
@@ -345,7 +342,7 @@ class TopicDocumentReferences:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicRelatedTopics:
class Meta:
global_type = False
@@ -360,7 +357,7 @@ class TopicRelatedTopics:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicViewpoints:
class Meta:
global_type = False
@@ -375,7 +372,7 @@ class TopicViewpoints:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Header:
files: Optional[HeaderFiles] = field(
default=None,
@@ -387,7 +384,7 @@ class Header:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class TopicComments:
class Meta:
global_type = False
@@ -402,7 +399,7 @@ class TopicComments:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Topic:
reference_links: Optional[TopicReferenceLinks] = field(
default=None,
@@ -599,7 +596,7 @@ class Topic:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Markup:
header: Optional[Header] = field(
default=None,
+2 -5
View File
@@ -1,11 +1,8 @@
import sys
from dataclasses import dataclass, field
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Project:
name: Optional[str] = field(
default=None,
@@ -28,7 +25,7 @@ class Project:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ProjectInfo:
project: Project = field(
metadata={
+1 -4
View File
@@ -1,10 +1,7 @@
import sys
from dataclasses import dataclass, field
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Version:
version_id: str = field(
metadata={
+20 -24
View File
@@ -1,18 +1,14 @@
import sys
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
class BitmapFormat(Enum):
PNG = "png"
JPG = "jpg"
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Component:
originating_system: Optional[str] = field(
default=None,
@@ -43,7 +39,7 @@ class Component:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Direction:
x: float = field(
metadata={
@@ -68,7 +64,7 @@ class Direction:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Point:
x: float = field(
metadata={
@@ -93,7 +89,7 @@ class Point:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ViewSetupHints:
spaces_visible: bool = field(
default=False,
@@ -118,7 +114,7 @@ class ViewSetupHints:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Bitmap:
format: BitmapFormat = field(
metadata={
@@ -166,7 +162,7 @@ class Bitmap:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ClippingPlane:
location: Point = field(
metadata={
@@ -184,7 +180,7 @@ class ClippingPlane:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentColoringColorComponents:
class Meta:
global_type = False
@@ -199,7 +195,7 @@ class ComponentColoringColorComponents:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentSelection:
component: list[Component] = field(
default_factory=list,
@@ -210,7 +206,7 @@ class ComponentSelection:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentVisibilityExceptions:
class Meta:
global_type = False
@@ -224,7 +220,7 @@ class ComponentVisibilityExceptions:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Line:
start_point: Point = field(
metadata={
@@ -242,7 +238,7 @@ class Line:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class OrthogonalCamera:
"""
Attributes
@@ -292,7 +288,7 @@ class OrthogonalCamera:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class PerspectiveCamera:
"""
Attributes
@@ -348,7 +344,7 @@ class PerspectiveCamera:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentColoringColor:
class Meta:
global_type = False
@@ -370,7 +366,7 @@ class ComponentColoringColor:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentVisibility:
view_setup_hints: Optional[ViewSetupHints] = field(
default=None,
@@ -395,7 +391,7 @@ class ComponentVisibility:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfoBitmaps:
class Meta:
global_type = False
@@ -409,7 +405,7 @@ class VisualizationInfoBitmaps:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfoClippingPlanes:
class Meta:
global_type = False
@@ -423,7 +419,7 @@ class VisualizationInfoClippingPlanes:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfoLines:
class Meta:
global_type = False
@@ -437,7 +433,7 @@ class VisualizationInfoLines:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class ComponentColoring:
color: list[ComponentColoringColor] = field(
default_factory=list,
@@ -448,7 +444,7 @@ class ComponentColoring:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class Components:
selection: Optional[ComponentSelection] = field(
default=None,
@@ -473,7 +469,7 @@ class Components:
)
@dataclass(**DATACLASS_KWARGS)
@dataclass(slots=True, kw_only=True)
class VisualizationInfo:
"""
VisualizationInfo documentation.
+1
View File
@@ -1,6 +1,7 @@
"""BCF XML V3 Topic handler."""
from __future__ import annotations
import datetime
import uuid
import zipfile
+3 -3
View File
@@ -1,12 +1,12 @@
import uuid
import zipfile
from typing import Any, Optional, Literal, Union
from collections.abc import Iterable
from typing import Literal, Optional, Union
import ifcopenshell.util.placement
import ifcopenshell.util.unit
import numpy as np
from ifcopenshell import entity_instance
import ifcopenshell.util.unit
import ifcopenshell.util.placement
from numpy.typing import NDArray
import bcf.v3.model as mdl
+6
View File
@@ -140,3 +140,9 @@ max-attributes = 10
[tool.pylint.format]
expected-line-ending-format = "LF"
max-line-length = 120
[tool.ruff]
extend = "../../pyproject.toml"
lint.select = [
"F401", # unused imports
]
-2
View File
@@ -1,4 +1,3 @@
import json
import os
import zipfile
from pathlib import Path
@@ -7,7 +6,6 @@ from xsdata.models.datatype import XmlDateTime
import bcf.v3.model as mdl
from bcf.v3.bcfxml import BcfXml
from bcf.v3.topic import TopicHandler
def test_doc_ref_internal() -> None:
+22
View File
@@ -0,0 +1,22 @@
# Build Bonsai .zip.
# Usage:
# # While in `bonsai` folder.
# docker build -t bonsai-dist .
# # Output zip file will be in `dist` folder.
# # See possible values for variables in `Makefile`'s `dist` target description.
# docker run --rm -v "$PWD/../../:/work" -w /work -e PLATFORM=win -e PYVERSION=py313 bonsai-dist
FROM ubuntu:24.04
RUN apt-get update
RUN apt-get install -y make git wget unzip zip
# Python
RUN apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update
RUN apt-get install -y python3.11 python3.11-venv
RUN apt-get install -y npm
WORKDIR /work
CMD cd src/bonsai && make dist PLATFORM=$PLATFORM PYVERSION=$PYVERSION
+44 -21
View File
@@ -48,18 +48,33 @@ VERSION_PATCH:=$(shell cat '../../VERSION' | cut -d '.' -f 3)
VERSION_DATE:=$(shell date '+%y%m%d')
LAST_COMMIT_HASH:=$(shell git rev-parse HEAD)
LAST_COMMIT_DATE:=$(shell git show -s --format=%cI)
PYVERSION:=py310
PYPI_IMP:=cp
ifeq ($(PYVERSION), py311)
PYLIBDIR:=python3.11
PYNUMBER:=311
PYPI_VERSION:=3.11
ifdef PYVERSION
SUPPORTED_PYVERSIONS := py311 py312 py313
ifeq ($(filter $(PYVERSION),$(SUPPORTED_PYVERSIONS)),)
$(error Unsupported PYVERSION=$(PYVERSION). Must be one of $(SUPPORTED_PYVERSIONS))
endif
PYMINOR:=$(subst py3,,$(PYVERSION))
PYLIBDIR:=python3.$(PYMINOR)
PYNUMBER:=3$(PYMINOR)
PYPI_VERSION:=3.$(PYMINOR)
endif # def PYVERSION
ifdef PLATFORM
SUPPORTED_PLATFORMS := linux macos macosm1 win
ifeq ($(filter $(PLATFORM),$(SUPPORTED_PLATFORMS)),)
$(error Unsupported PLATFORM=$(PLATFORM). Must be one of $(SUPPORTED_PLATFORMS))
endif
ifeq ($(PLATFORM),macos)
ifeq ($(PYVERSION),py313)
$(error Blender 5.1 with Python 3.13 doesn't support intel macOS.)
endif
ifeq ($(PYVERSION), py312)
PYLIBDIR:=python3.12
PYNUMBER:=312
PYPI_VERSION:=3.12
endif
ifeq ($(PLATFORM), linux)
@@ -86,8 +101,10 @@ PYPI_PLATFORM:=--platform win_amd64
BLENDER_PLATFORM:=windows-x64
endif
endif # def PLATFORM
# Current build commit hash.
OLD:=6924012
OLD:=e8eb5e4
.PHONY: bump
bump:
ifndef NEW
@@ -99,7 +116,10 @@ endif
.PHONY: dist
dist:
ifndef PLATFORM
$(error PLATFORM is not set)
$(error PLATFORM is not set. Example values: $(SUPPORTED_PLATFORMS).)
endif
ifndef PYVERSION
$(error PYVERSION is not set. Example values: $(SUPPORTED_PYVERSIONS). )
endif
rm -rf build
mkdir -p build
@@ -125,9 +145,6 @@ endif
cd ../ifc5d && make dist && mv dist/*.whl ../bonsai/build/wheels/
cd ../ifccityjson && make dist && mv dist/*.whl ../bonsai/build/wheels/
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download GitPython --dest=./wheels
# Provides audio playback for costing
# This is a REALLY IMPORTANT feature
cd build && . env/$(VENV_ACTIVATE) && $(PIP) wheel git+https://github.com/zdhoward/aud --wheel-dir=./wheels
# IfcOpenShell dependency - support for new typing features
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download typing_extensions --dest=./wheels
# Required by IfcCSV
@@ -155,6 +172,9 @@ endif
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download six --dest=./wheels
# Required by drawing module
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download lxml $(PYPI_PLATFORM) --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
# Required by drawing module for markdown hyperlinks in annotations
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download markdown-it-py --dest=./wheels
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download mdurl --dest=./wheels
# Required by qto and drawing module
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download shapely $(PYPI_PLATFORM) --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
# Required by the BIM type manager thumbnail generator
@@ -186,7 +206,7 @@ endif
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download tzfpy $(PYPI_PLATFORM) --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
# pyradiance is using different platform versions than defaults in our makefile.
ifeq ($(PLATFORM), linux)
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download pyradiance --platform manylinux_2_35_x86_64 --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download pyradiance --platform manylinux_2_28_x86_64 --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
else ifeq ($(PLATFORM), macos)
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download pyradiance --platform macosx_10_13_x86_64 --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
else
@@ -264,6 +284,11 @@ else
$(SED) 's/version = "0.0.0"/version = "$(VERSION)-alpha$(VERSION_DATE)"/' build/pyproject.toml
endif
# Blender 5.1+ requires Python 3.13.
ifeq ($(PYVERSION), py313)
$(SED) 's/blender_version_min = "4\.2\.0"/blender_version_min = "5.1.0"/' build/bonsai/blender_manifest.toml
endif
$(SED) "s/os-arch/$(BLENDER_PLATFORM)/" build/bonsai/blender_manifest.toml
# Provides bonsai Add-on functionality
@@ -285,12 +310,6 @@ endif
fi
mv build/wheels/*.whl build/bonsai/wheels/
# Temporary workaround for Blender not handling non-3.11 wheels #5743.
# Use '-n' as on macos x86-64 doesn't have a binary wheel and it autoincludes 'cp311'.
prev_whl_name=$$(find build/bonsai/wheels/tzfpy-*.whl); \
whl_name=$$(echo $$prev_whl_name | sed "s/-cp39-/-cp$(PYNUMBER)-/"); \
mv --update=none "$$prev_whl_name" "$$whl_name";
ifneq ($(PLATFORM), linux)
# Safeguard: in case one of `pip download` will break,
# it will produce a linux wheel for non-linux build (our github action machine is using linux).
@@ -333,7 +352,11 @@ test:
.PHONY: test-core
test-core:
ifndef MODULE
pytest -p no:pytest-blender test/core
else
pytest -p no:pytest-blender test/core/test_${MODULE}.py
endif
.PHONY: test-bim
test-bim:
+26 -8
View File
@@ -32,17 +32,16 @@ if IN_BLENDER:
# and then as a bonsai-package.
IN_PACKAGE = __package__ == "bonsai"
import re
import platform
import traceback
import webbrowser
import uuid
import re
import shutil
import traceback
import uuid
import webbrowser
from collections import deque
from pathlib import Path
from typing import Union, Any
from collections.abc import Generator
from pathlib import Path
from typing import Any, Union
last_commit_hash = "8888888"
last_commit_date = "9999999"
@@ -98,7 +97,7 @@ def initialize_bbim_semver():
def get_debug_info():
bbim_version = bbim_semver["version"]
return {
debug_info = {
"os": platform.system(),
"os_version": platform.version(),
"python_version": platform.python_version(),
@@ -113,6 +112,25 @@ def get_debug_info():
"last_error": last_error,
}
# Add .blend file save information
if bpy.data.is_saved:
debug_info["blend_file_path"] = bpy.data.filepath
debug_info["blend_file_dirty"] = bpy.data.is_dirty
else:
debug_info["blend_file_path"] = "Not saved"
debug_info["blend_file_dirty"] = "N/A"
# Add IFC file information
bim_props = tool.Blender.get_bim_props()
if bim_props.ifc_file:
debug_info["ifc_file_path"] = bim_props.ifc_file
debug_info["ifc_is_dirty"] = bim_props.is_dirty
else:
debug_info["ifc_file_path"] = "No IFC loaded"
debug_info["ifc_is_dirty"] = "N/A"
return debug_info
def format_debug_info(info: dict):
last_actions = ""
+48 -13
View File
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import importlib
import os
from collections.abc import Callable
from typing import Union
import bpy
import bpy.utils.previews
import importlib
from bpy_extras.io_utils import ImportHelper, ExportHelper
from . import handler, ui, prop, operator
from typing import Union
from collections.abc import Callable
from bpy_extras.io_utils import ExportHelper, ImportHelper
from . import handler, operator, prop, ui
try:
from bonsai.translations import translations_dict
@@ -120,6 +122,7 @@ classes = [
operator.OpenUri,
operator.ReloadIfcFile,
operator.RevertClippingPlaneCut,
operator.SaveBlendMetadataFile,
operator.SelectDir,
operator.SelectIfcFile,
operator.SelectURIAttribute,
@@ -129,12 +132,16 @@ classes = [
prop.StrProperty,
operator.BIM_OT_enum_property_search, # /!\ Register AFTER prop.StrProperty
operator.BIM_OT_attribute_search_values,
operator.BIM_OT_manage_tab_visibility,
operator.BIM_OT_reset_ui_layout,
prop.ObjProperty,
prop.MultipleFileSelect,
prop.Attribute,
prop.ISODuration,
prop.BIMAreaProperties,
prop.BIMTabProperties,
prop.BIMTabVisibility, # Must be registered before BIMProperties
prop.BIMPanelVisibility, # Must be registered before BIMProperties
prop.BIMProperties,
prop.IfcParameter,
prop.PsetQto,
@@ -147,8 +154,14 @@ classes = [
prop.BIMSnapGroups,
ui.BIM_UL_clipping_plane,
ui.BIM_UL_generic,
ui.BIM_UL_tab_visibilities,
ui.BIM_UL_panel_visibilities,
ui.DocPreferences,
ui.BIM_ADDON_preferences,
ui.GizmoPreferencesDoor, # Register before GizmoPreferences
ui.GizmoPreferencesWindow, # Register before GizmoPreferences
ui.GizmoPreferencesStair, # Register before GizmoPreferences
ui.GizmoPreferences,
# ui.DefaultParameters and ui.BIM_ADDON_preferences are registered separately after modules (see late_classes below)
# Tabs panel
ui.BIM_PT_tabs,
# Project overview
@@ -225,14 +238,33 @@ def on_register(scene):
is_registering = False
def register():
for cls in classes:
# Classes that need to be registered after modules (due to cross-module dependencies)
late_classes = (
ui.DefaultParameters, # Register before BIM_ADDON_preferences
ui.BIM_ADDON_preferences,
)
def register_classes(classes_to_register):
for cls in classes_to_register:
# Prevent crashes in Blender 4.4.0, see #6420.
if issubclass(cls, (ImportHelper, ExportHelper)):
assert getattr(cls, "bl_description", "") or cls.__doc__, cls
bpy.utils.register_class(cls)
def unregister_classes(classes_to_unregister):
for cls in reversed(classes_to_unregister):
if getattr(cls, "is_registered", None) is None:
bpy.utils.unregister_class(cls)
elif cls.is_registered:
bpy.utils.unregister_class(cls)
def register():
register_classes(classes)
bpy.app.handlers.depsgraph_update_post.append(on_register)
bpy.app.handlers.undo_post.append(handler.undo_post)
bpy.app.handlers.redo_post.append(handler.redo_post)
@@ -249,6 +281,7 @@ def register():
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.PointLight.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
if hasattr(bpy.types, "UI_MT_button_context_menu"):
bpy.types.UI_MT_button_context_menu.append(ui.draw_custom_context_menu)
bpy.types.STATUSBAR_HT_header.append(ui.draw_statusbar)
@@ -256,6 +289,9 @@ def register():
for mod in modules.values():
mod.register()
# Delay registering classes that depend on module classes
register_classes(late_classes)
wm = bpy.context.window_manager
if wm.keyconfigs.addon:
km = wm.keyconfigs.addon.keymaps.new(name="Window", space_type="EMPTY")
@@ -287,11 +323,7 @@ def unregister():
bpy.utils.previews.remove(icons)
for cls in reversed(classes):
if getattr(cls, "is_registered", None) is None:
bpy.utils.unregister_class(cls)
elif cls.is_registered:
bpy.utils.unregister_class(cls)
unregister_classes(classes)
bpy.app.handlers.load_post.remove(handler.load_post)
bpy.app.handlers.load_post.remove(handler.loadIfcStore)
@@ -306,6 +338,9 @@ def unregister():
bpy.types.UI_MT_button_context_menu.remove(ui.draw_custom_context_menu)
bpy.types.STATUSBAR_HT_header.remove(ui.draw_statusbar)
# Unregister late classes before modules
unregister_classes(late_classes)
for mod in reversed(list(modules.values())):
mod.unregister()
@@ -20,6 +20,8 @@
* { stroke-linecap: round; stroke-linejoin: round; }
text, tspan { /* 2.5mm */ fill: black; stroke: none; font-family: 'OpenGost Type B TT', 'DejaVu Sans Condensed', 'Liberation Sans', 'Arial Narrow', 'Arial'; font-size: 4.13px; }
a text, a tspan { fill: blue !important; text-decoration: underline;}
a:hover { cursor: pointer; }
.cut { fill: black; stroke: black; stroke-linecap: 'round'; stroke-width: 0.35; fill-rule: evenodd; }
.projection { fill: white; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
.surface { stroke: none; fill: #fff; fill-rule: evenodd; }
@@ -7,12 +7,6 @@
1.0,
1.0
],
"scene.render.bake_bias": 0.0010000000474974513,
"scene.render.bake_margin": 16,
"scene.render.bake_margin_type": "ADJACENT_FACES",
"scene.render.bake_samples": 256,
"scene.render.bake_type": "NORMALS",
"scene.render.bake_user_scale": 0.0,
"scene.render.border_max_x": 1.0,
"scene.render.border_max_y": 1.0,
"scene.render.border_min_x": 0.0,
@@ -54,11 +48,6 @@
"scene.render.stamp_note_text": "",
"scene.render.threads": 20,
"scene.render.threads_mode": "AUTO",
"scene.render.use_bake_clear": true,
"scene.render.use_bake_lores_mesh": false,
"scene.render.use_bake_multires": false,
"scene.render.use_bake_selected_to_active": false,
"scene.render.use_bake_user_scale": false,
"scene.render.use_border": false,
"scene.render.use_compositing": true,
"scene.render.use_crop_to_border": false,
@@ -253,12 +242,6 @@
1.0,
1.0
],
"scene.render.bake_bias": 0.0010000000474974513,
"scene.render.bake_margin": 16,
"scene.render.bake_margin_type": "ADJACENT_FACES",
"scene.render.bake_samples": 256,
"scene.render.bake_type": "NORMALS",
"scene.render.bake_user_scale": 0.0,
"scene.render.border_max_x": 1.0,
"scene.render.border_max_y": 1.0,
"scene.render.border_min_x": 0.0,
@@ -300,11 +283,6 @@
"scene.render.stamp_note_text": "",
"scene.render.threads": 20,
"scene.render.threads_mode": "AUTO",
"scene.render.use_bake_clear": true,
"scene.render.use_bake_lores_mesh": false,
"scene.render.use_bake_multires": false,
"scene.render.use_bake_selected_to_active": false,
"scene.render.use_bake_user_scale": false,
"scene.render.use_border": false,
"scene.render.use_compositing": true,
"scene.render.use_crop_to_border": false,
@@ -377,7 +355,7 @@
1.0,
1.0
],
"scene.display.shading.studio_light": "Default",
"scene.display.shading.studio_light": "forest.exr",
"scene.display.shading.studiolight_background_alpha": 0.0,
"scene.display.shading.studiolight_background_blur": 0.0,
"scene.display.shading.studiolight_intensity": 0.0,
@@ -503,18 +481,12 @@
"scene.eevee.shadow_ray_count": 1,
"scene.eevee.shadow_step_count": 6,
"scene.eevee.shadow_resolution_scale": 1.0,
"scene.render.bake_bias": 0.0010000000474974513,
"scene.render.bake_margin": 16,
"scene.render.bake_margin_type": "ADJACENT_FACES",
"scene.render.bake_samples": 256,
"scene.render.bake_type": "NORMALS",
"scene.render.bake_user_scale": 0.0,
"scene.render.border_max_x": 1.0,
"scene.render.border_max_y": 1.0,
"scene.render.border_min_x": 0.0,
"scene.render.border_min_y": 0.0,
"scene.render.dither_intensity": 1.0,
"scene.render.engine": "BLENDER_EEVEE_NEXT",
"scene.render.engine": "BLENDER_EEVEE",
"scene.render.film_transparent": false,
"scene.render.filter_size": 1.5,
"scene.render.fps": 24,
@@ -550,11 +522,6 @@
"scene.render.stamp_note_text": "",
"scene.render.threads": 20,
"scene.render.threads_mode": "AUTO",
"scene.render.use_bake_clear": true,
"scene.render.use_bake_lores_mesh": false,
"scene.render.use_bake_multires": false,
"scene.render.use_bake_selected_to_active": false,
"scene.render.use_bake_user_scale": false,
"scene.render.use_border": false,
"scene.render.use_compositing": true,
"scene.render.use_crop_to_border": false,
@@ -627,7 +594,7 @@
0.800000011920929,
0.800000011920929
],
"scene.display.shading.studio_light": "Default",
"scene.display.shading.studio_light": "forest.exr",
"scene.display.shading.studiolight_background_alpha": 0.0,
"scene.display.shading.studiolight_background_blur": 0.0,
"scene.display.shading.studiolight_intensity": 0.0,
@@ -1,6 +1,5 @@
import sys
import os
import sys
bonsai_lib_path = os.environ.get("BONSAI_LIB_PATH")
bonsai_version = os.environ.get("BONSAI_VERSION")
@@ -9,13 +8,14 @@ if bonsai_lib_path:
sys.path.insert(0, bonsai_lib_path)
import argparse
from aiohttp import web
import socketio
import pystache
import json
import base64
import json
import xml.etree.ElementTree as ET
import pystache
import socketio
from aiohttp import web
sio_port = 8080 # default port
sio = socketio.AsyncServer(cors_allowed_origins="*", async_mode="aiohttp", max_http_buffer_size=10000000)
+20 -16
View File
@@ -17,26 +17,30 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import os
import bpy
import json
import datetime
import zipfile
import json
import os
import tempfile
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.placement
import ifcopenshell.util.unit
import bonsai.tool as tool
import bonsai.core.geometry
import bonsai.core.aggregate
import bonsai.core.spatial
import bonsai.core.style
from bonsai.bim.ifc import IfcStore
from mathutils import Vector
from typing import Union
import zipfile
from logging import Logger
from math import radians
from typing import Union
import bpy
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.unit
from mathutils import Vector
import bonsai.core.aggregate
import bonsai.core.geometry
import bonsai.core.spatial
import bonsai.core.style
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
class IfcExporter:
+16 -11
View File
@@ -17,26 +17,31 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import os
import weakref
from collections.abc import Callable
from math import cos
from typing import Union
import bpy
import ifcopenshell.api.owner.settings
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.unit
import ifcopenshell.api.owner.settings
from bpy.app.handlers import persistent
from mathutils import Vector
import bonsai.bim
import bonsai.tool as tool
import weakref
from bpy.app.handlers import persistent
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.model.data import AuthoringData
from bonsai.bim.module.aggregate.decorator import AggregateDecorator
from bonsai.bim.module.georeference.decorator import GeoreferenceDecorator
from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator, BoundingBoxDecorator
from bonsai.bim.module.model.data import AuthoringData
from bonsai.bim.module.model.decorator import (
BoundingBoxDecorator,
SlabDirectionDecorator,
WallAxisDecorator,
)
from bonsai.bim.module.nest.decorator import NestDecorator
from mathutils import Vector
from math import cos
from typing import Union
from collections.abc import Callable
cwd = os.path.dirname(os.path.realpath(__file__))
global_subscription_owner = object()
@@ -202,8 +207,8 @@ def refresh_ui_data():
Note that calling non-ifc-operators by itself doesn't refresh the UI data
and it need to be refreshed manually if needed.
"""
from bonsai.bim import modules
import bonsai.bim.ui
from bonsai.bim import modules
bonsai.bim.ui.refresh()
+241 -18
View File
@@ -17,24 +17,31 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import importlib
import bpy
import json
from collections.abc import Callable, Iterable, Sequence
from types import EllipsisType
from typing import TYPE_CHECKING, Any, Optional, Union
import bpy
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.attribute
import ifcopenshell.util.element
import ifcopenshell.util.unit
from ifcopenshell.util.doc import get_attribute_doc, get_predefined_type_doc, get_property_doc
from ifcopenshell.util.doc import (
get_attribute_doc,
get_predefined_type_doc,
get_property_doc,
)
import bonsai.tool as tool
from types import EllipsisType
from typing import Optional, Any, Union, TYPE_CHECKING
from collections.abc import Callable, Iterable, Sequence
if TYPE_CHECKING:
import bonsai.bim.prop
from bonsai.bim.prop import Attribute
from bonsai.bim.module.search.prop import BIMFilterGroup
from bonsai.bim.prop import Attribute
# ImportCallback return values:
# - None - property should be imported by default workflow
@@ -428,7 +435,11 @@ def get_enum_items(
else:
annotations_data = data
prop = annotations_data.__annotations__[prop_name]
try:
annotations = annotations_data.__annotations__
except AttributeError:
annotations = type(annotations_data).__annotations__
prop = annotations[prop_name]
items = prop.keywords.get("items")
if items is None:
return
@@ -498,6 +509,8 @@ def draw_filter(
if data.data["saved_searches"]:
row.operator("bim.load_search", text="", icon="IMPORT").module = module
row.operator("bim.save_search", text="", icon="EXPORT").module = module
if data.data["saved_searches"]:
row.operator("bim.remove_search", text="", icon="REMOVE").module = module
if module != "search":
if module == "drawing_include":
row.operator("bim.edit_element_filter", icon="CHECKMARK", text="").filter_mode = "INCLUDE"
@@ -505,62 +518,272 @@ def draw_filter(
row.operator("bim.edit_element_filter", icon="CHECKMARK", text="").filter_mode = "EXCLUDE"
row.operator("bim.enable_editing_element_filter", icon="CANCEL", text="").filter_mode = "NONE"
row = layout.row(align=True)
row.operator("bim.add_filter_group", text="Add Search Group", icon="ADD").module = module
row.operator("bim.edit_filter_query", text="", icon="FILTER").module = module
preferences = tool.Blender.get_addon_preferences()
if not preferences.chain_filter_with_set_operations:
row.operator("bim.add_filter_group", text="Add Search Group", icon="ADD").module = module
else:
row.prop(sprops, "facet", text="")
op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
op.type = sprops.facet
op.index = 0
op.module = module
op = row.operator("bim.edit_filter_query", text="", icon="FILTER")
if "module" in op.bl_rna.properties:
op.module = module
for i, filter_group in enumerate(filter_groups):
box = layout.box()
row = box.row(align=True)
row.prop(sprops, "facet", text="")
op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
op.type = sprops.facet
op.index = i
op.module = module
op = row.operator("bim.remove_filter_group", text="", icon="X")
op.index = i
op.module = module
preferences = tool.Blender.get_addon_preferences()
if not preferences.chain_filter_with_set_operations:
row = box.row(align=True)
row.prop(sprops, "facet", text="")
op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
op.type = sprops.facet
op.index = i
op.module = module
op = row.operator("bim.remove_filter_group", text="", icon="X")
op.index = i
op.module = module
for j, ifc_filter in enumerate(filter_group.filters):
if ifc_filter.type == "entity":
row = box.row(align=True)
preferences = tool.Blender.get_addon_preferences()
show_mode_toggle = preferences.chain_filter_with_set_operations and j > 0
if show_mode_toggle:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="FILE_3D")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "attribute":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "name", text="", icon="COPY_ID")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
op.suggestion_type = "attribute_name"
row.prop(ifc_filter, "value", text="")
if ifc_filter.name:
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
op.suggestion_type = "attribute_value"
elif ifc_filter.type == "type":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="FILE_VOLUME")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "material":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="MATERIAL")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "property":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "pset", text="", icon="PROPERTIES")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
op.suggestion_type = "pset"
row.prop(ifc_filter, "name", text="")
if ifc_filter.pset:
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
op.suggestion_type = "property_name"
row.prop(ifc_filter, "comparison", text="")
row.prop(ifc_filter, "value", text="")
if ifc_filter.pset and ifc_filter.name:
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
op.suggestion_type = "property_value"
elif ifc_filter.type == "classification":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="OUTLINER")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "location":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="PACKAGE")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "group":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="OUTLINER_COLLECTION")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "parent":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="FILE_PARENT")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
elif ifc_filter.type == "query":
row = box.row(align=True)
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "name", text="", icon="POINTCLOUD_DATA")
row.prop(ifc_filter, "comparison", text="")
row.prop(ifc_filter, "value", text="")
elif ifc_filter.type == "instance":
row = box.row(align=True)
preferences = tool.Blender.get_addon_preferences()
show_mode_toggle = preferences.chain_filter_with_set_operations and j > 0
if show_mode_toggle:
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
op = row.operator(
"bim.toggle_filter_inclusion",
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
text="",
depress=ifc_filter.filter_mode != "ADD",
)
op.group_index = i
op.filter_index = j
op.module = module
row.prop(ifc_filter, "value", text="", icon="GRIP")
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
op.group_index = i
op.filter_index = j
op.module = module
op.filter_type = ifc_filter.type
op = row.operator("bim.select_filter_elements", text="", icon="EYEDROPPER")
op.group_index = i
op.index = j
+12 -10
View File
@@ -17,26 +17,28 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import os
import bpy
import uuid
import shutil
import hashlib
import zipfile
import os
import shutil
import tempfile
import traceback
import uuid
import zipfile
from collections.abc import Callable
from pathlib import Path
from typing import Literal, NotRequired, Optional, TypedDict, Union
import bpy
import ifcopenshell
import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper
from ifcopenshell.file import UndoSystemError
import bonsai
import bonsai.bim.handler
import bonsai.tool as tool
from ifcopenshell.file import UndoSystemError
from pathlib import Path
from bonsai.tool.brick import BrickStore
from typing import Union, Optional, TypedDict, NotRequired, Literal
from collections.abc import Callable
IFC_CONNECTED_TYPE = Union[bpy.types.Material, bpy.types.Object]
+61 -16
View File
@@ -17,32 +17,36 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import time
import json
import ifcpatch
import logging
import traceback
import mathutils
import numpy as np
import numpy.typing as npt
import multiprocessing
import time
import traceback
from collections.abc import Iterable
from typing import Any, Literal, Optional, Union
import bpy
import ifcopenshell
import ifcopenshell.api.pset
import ifcopenshell.geom
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.util.unit
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
from bonsai.tool.loader import OBJECT_DATA_TYPE
from typing import Union, Optional, Any, Literal
from collections.abc import Iterable
import ifcopenshell.util.unit
import ifcpatch
import mathutils
import numpy as np
import numpy.typing as npt
from ifcopenshell.util.shape import MatrixType
import bonsai.tool as tool
from bonsai.bim.ifc import IFC_CONNECTED_TYPE, IfcStore
from bonsai.tool.loader import OBJECT_DATA_TYPE
class MaterialCreator:
mesh: bpy.types.Mesh
@@ -888,6 +892,48 @@ class IfcImporter:
obj, tool.Loader.apply_blender_offset_to_matrix_world(obj, self.get_element_matrix(element))
)
if element.is_a("IfcAnnotation") and getattr(element, "ObjectType", None) == "IMAGE":
image = None
if obj.data and obj.data.materials and obj.data.materials[0]:
material = obj.data.materials[0]
if material.use_nodes and material.node_tree:
for node in material.node_tree.nodes:
if node.type == "TEX_IMAGE" and node.image:
image = node.image
break
if image:
import bmesh
bm = bmesh.new()
bm.from_mesh(obj.data)
if not bm.loops.layers.uv:
uv_layer = bm.loops.layers.uv.new()
else:
uv_layer = bm.loops.layers.uv.active
if bm.verts:
min_x = min(v.co.x for v in bm.verts)
max_x = max(v.co.x for v in bm.verts)
min_y = min(v.co.y for v in bm.verts)
max_y = max(v.co.y for v in bm.verts)
width = max_x - min_x
height = max_y - min_y
for face in bm.faces:
for loop in face.loops:
vert = loop.vert
u = (vert.co.x - min_x) / width if width > 0 else 0.5
v = (vert.co.y - min_y) / height if height > 0 else 0.5
u = max(0.0, min(1.0, u))
v = max(0.0, min(1.0, v))
loop[uv_layer].uv = (u, v)
bm.to_mesh(obj.data)
bm.free()
obj.data.update()
return obj
def load_existing_meshes(self) -> None:
@@ -1237,8 +1283,7 @@ class IfcImporter:
if not pset:
return
if "Aggregate_Index" not in pset.keys():
ifcopenshell.api.run(
"pset.edit_pset",
ifcopenshell.api.pset.edit_pset(
self.file,
pset=self.file.by_id(pset["id"]),
properties={"Aggregate_Index": aggregate_index, "Name": name},
@@ -1261,7 +1306,7 @@ class IfcImportSettings:
self.should_load_geometry = True
self.should_clean_mesh = False
self.should_cache = True
self.deflection_tolerance = 0.001
self.deflection_tolerance = 0.05 # Default is 0.001, but I find this to be more practical
self.angular_tolerance = 0.5
self.void_limit = 30
self.style_limit = 300
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.BIM_OT_add_aggregate,
@@ -16,11 +16,13 @@
# 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
import bonsai.tool as tool
import ifcopenshell.util.element
from typing import Union
import bpy
import ifcopenshell.util.element
import bonsai.tool as tool
def refresh():
AggregateData.is_loaded = False
@@ -21,11 +21,12 @@ import bpy
import gpu
import ifcopenshell
import ifcopenshell.util.element
import bonsai.tool as tool
from bpy.types import SpaceView3D
from bpy_extras import view3d_utils
from gpu_extras.batch import batch_for_shader
from mathutils import Vector
import bonsai.tool as tool
from bonsai.bim.module.geometry.decorator import ItemDecorator
@@ -16,16 +16,19 @@
# 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
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.group
import ifcopenshell.api.pset
import ifcopenshell.api.root
import ifcopenshell.util.element
import bonsai.tool as tool
import bonsai.core.aggregate as core
import bonsai.core.spatial
from typing import TYPE_CHECKING
import bonsai.tool as tool
class BIM_OT_aggregate_assign_object(bpy.types.Operator, tool.Ifc.Operator):
@@ -126,6 +129,10 @@ class BIM_OT_aggregate_unassign_object(bpy.types.Operator, tool.Ifc.Operator):
# Second pass: delete aggregates that now have no parts
deleted_aggregates = []
for aggregate in aggregates_to_check:
# Skip spatial elements - they should not be deleted even if empty
if aggregate.is_a("IfcSpatialElement"):
continue
related_objects = ifcopenshell.util.element.get_parts(aggregate)
if len(related_objects) == 0:
aggregate_name = aggregate.Name or f"{aggregate.is_a()} #{aggregate.id()}"
@@ -217,7 +224,7 @@ class BIM_OT_add_aggregate(bpy.types.Operator, tool.Ifc.Operator):
tool.Collector,
tool.Spatial,
container=current_container,
element_obj=aggregate,
objs=[aggregate],
)
core.assign_object(tool.Ifc, tool.Aggregate, tool.Collector, relating_obj=aggregate, related_obj=obj)
@@ -321,6 +328,21 @@ class BIM_OT_select_aggregate(bpy.types.Operator):
aggregate_obj.select_set(True)
bpy.context.view_layer.objects.active = aggregate_obj
# copy selection query to clipboard
result = ""
for aggregate in all_parts:
aggregate_class = aggregate.is_a()
aggregate_name = aggregate.Name or ""
query = f'parent = "{aggregate_name}"'
if not result:
result = query
else:
result += f" + {query}"
if result:
bpy.context.window_manager.clipboard = result
self.report({"INFO"}, f"({result}) was copied to the clipboard.")
self.one_level_deep = False # <-- forcibly reset
return {"FINISHED"}
+16 -11
View File
@@ -16,24 +16,29 @@
# 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, Union
import bpy
import ifcopenshell.util.element
import bonsai.tool as tool
from bonsai.bim.prop import StrProperty, Attribute
from bonsai.bim.module.spatial.data import SpatialData
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from bonsai.bim.module.aggregate.decorator import AggregateDecorator, AggregateModeDecorator
from typing import TYPE_CHECKING, Union
from bpy.types import PropertyGroup
import bonsai.tool as tool
from bonsai.bim.module.aggregate.decorator import (
AggregateDecorator,
AggregateModeDecorator,
)
from bonsai.bim.module.spatial.data import SpatialData
from bonsai.bim.prop import Attribute, StrProperty
def can_aggregate(relating_obj: bpy.types.Object, related_obj: bpy.types.Object) -> bool:
+3 -2
View File
@@ -17,10 +17,11 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from bpy.types import Panel
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.aggregate.data import AggregateData
from bonsai.bim.module.group.data import GroupsData, ObjectGroupsData
from bonsai.bim.ifc import IfcStore
import bonsai.tool as tool
class BIM_PT_aggregate(Panel):
@@ -18,25 +18,25 @@
# pyright: reportUnnecessaryTypeIgnoreComment=error
import calendar
import json
import os
import ifcopenshell.api.alignment
import time
from datetime import datetime
import bpy
import json
import time
import calendar
import isodate
import bonsai.core.sequence as core
import bonsai.tool as tool
import bonsai.bim.module.sequence.helper as helper
import ifcopenshell.api.alignment
import ifcopenshell.api.spatial
import ifcopenshell.geom
import ifcopenshell.util.sequence
import ifcopenshell.util.selector
from datetime import datetime
from dateutil import parser, relativedelta
import ifcopenshell.util.sequence
import isodate
from bpy_extras.io_utils import ImportHelper
from dateutil import parser, relativedelta
import bonsai.bim.module.sequence.helper as helper
import bonsai.core.sequence as core
import bonsai.tool as tool
class ImportAlignmentCSV(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.EnableEditingAttributes,
@@ -18,6 +18,7 @@
import bpy
import ifcopenshell
import bonsai.tool as tool
@@ -16,22 +16,25 @@
# 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
import json
from typing import TYPE_CHECKING, Any, Literal, Union
import bpy
import ifcopenshell
import ifcopenshell.api.attribute
import ifcopenshell.guid
import ifcopenshell.util.element
import bonsai.bim.helper
import bonsai.tool as tool
import bonsai.core.attribute as core
import bonsai.core.spatial
from typing import TYPE_CHECKING, Any, Union, Literal
import bonsai.tool as tool
if TYPE_CHECKING:
from bonsai.bim.prop import Attribute
import bpy.stub_internal.rna_enums as rna_enums
from bonsai.bim.prop import Attribute
def get_objs_for_operation(
operator_properties: "AttributesOperator", context: bpy.types.Context
+11 -9
View File
@@ -16,21 +16,23 @@
# 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, Union
import bpy
import bonsai.tool as tool
from bonsai.bim.prop import StrProperty, Attribute
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from typing import TYPE_CHECKING, Union
from bpy.types import PropertyGroup
import bonsai.tool as tool
from bonsai.bim.prop import Attribute, StrProperty
class BIMAttributeProperties(PropertyGroup):
+7 -4
View File
@@ -17,12 +17,15 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bonsai.bim.helper
from typing import TYPE_CHECKING
import bpy.types
from bpy.types import Panel
from bonsai.bim.module.attribute.data import AttributesData
import bonsai.bim.helper
import bonsai.tool as tool
from typing import TYPE_CHECKING
from bonsai.bim.module.attribute.data import AttributesData
if TYPE_CHECKING:
from bonsai.bim.module.attribute.prop import BIMExplorerProperties, ExplorerEntity
@@ -58,7 +61,7 @@ def draw_ui(context: bpy.types.Context, layout: bpy.types.UILayout, attributes)
class BIM_PT_object_attributes(Panel):
bl_label = "Attributes"
bl_label = "Object Attributes"
bl_idname = "BIM_PT_object_attributes"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
prop.AuginProperties,
@@ -16,14 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import datetime
import os
import bpy
import string
import random
import shutil
import requests
import string
import tempfile
import datetime
import bpy
import requests
import bonsai.tool as tool
+1
View File
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy.types
import bonsai.tool as tool
+2 -1
View File
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.ActivateBcfViewpoint,
+4 -2
View File
@@ -17,12 +17,14 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import os
import bpy
from typing import Union
import bcf
import bcf.bcfxml
import bcf.v2.bcfxml
import bpy
import bonsai.tool as tool
from typing import Union
class BcfStore:
+21 -19
View File
@@ -17,6 +17,20 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import os
import tempfile
import uuid
import webbrowser
from math import atan, cos, degrees, radians, sin, tan
from pathlib import Path
import bcf
import bcf.agnostic.topic
import bcf.agnostic.visinfo
import bcf.bcfxml
import bcf.v2.bcfxml
import bcf.v2.model
import bcf.v2.topic
import bcf.v2.visinfo
import bcf.v3
import bcf.v3.bcfxml
import bcf.v3.document
@@ -24,30 +38,18 @@ import bcf.v3.model
import bcf.v3.topic
import bcf.v3.visinfo
import bpy
import bcf
import bcf.bcfxml
import bcf.v2.bcfxml
import bcf.v2.model
import bcf.v2.topic
import bcf.v2.visinfo
import bcf.agnostic.topic
import bcf.agnostic.visinfo
import uuid
import numpy as np
import tempfile
import webbrowser
import ifcopenshell
import ifcopenshell.util.geolocation
import ifcopenshell.util.unit
import bonsai.tool as tool
import bonsai.bim.module.bcf.prop as bcf_prop
import bonsai.bim.module.bcf.bcfstore as bcfstore
from bpy_extras.io_utils import ImportHelper, ExportHelper
from pathlib import Path
from math import radians, degrees, atan, tan, cos, sin
from mathutils import Vector, Matrix, Euler, geometry
import numpy as np
from bpy_extras.io_utils import ExportHelper, ImportHelper
from mathutils import Euler, Matrix, Vector, geometry
from xsdata.models.datatype import XmlDateTime
import bonsai.bim.module.bcf.bcfstore as bcfstore
import bonsai.bim.module.bcf.prop as bcf_prop
import bonsai.tool as tool
class NewBcfProject(bpy.types.Operator):
bl_idname = "bim.new_bcf_project"
+18 -16
View File
@@ -16,24 +16,26 @@
# 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
import bonsai.tool as tool
from . import bcfstore
from bonsai.bim.prop import StrProperty
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
)
from bcf.agnostic.extensions import get_extensions_attributes
from typing import TYPE_CHECKING, Union
import bpy
from bcf.agnostic.extensions import get_extensions_attributes
from bpy.props import (
BoolProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from bpy.types import PropertyGroup
import bonsai.tool as tool
from bonsai.bim.prop import StrProperty
from . import bcfstore
bcfviewpoints_enum = None
+9 -5
View File
@@ -17,15 +17,19 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import os
import bpy
import bonsai.tool as tool
from . import bcfstore
from bpy.types import Panel
from typing import TYPE_CHECKING
import bpy
from bpy.types import Panel
import bonsai.tool as tool
from . import bcfstore
if TYPE_CHECKING:
from bonsai.bim.module.bcf.prop import BcfTopic, BCFProperties
from bonsai.bim.module.bcf.prop import BCFProperties, BcfTopic
class BIM_PT_bcf(Panel):
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, operator, prop
from . import operator, prop, ui
classes = (
operator.AddBoundary,
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import bonsai.tool as tool
@@ -16,12 +16,13 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import gpu
import bmesh
import bonsai.tool as tool
import gpu
from bpy.types import SpaceView3D
from mathutils import Vector
from gpu_extras.batch import batch_for_shader
from mathutils import Vector
import bonsai.tool as tool
class BoundaryDecorator:
@@ -16,34 +16,36 @@
# 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
import bmesh
import logging
import shapely
import shapely.ops
import mathutils
import numpy as np
import multiprocessing
from math import acos, degrees, inf, pi, radians
from typing import Optional, Union
import bmesh
import bpy
import ifcopenshell.api
import ifcopenshell.api.boundary
import ifcopenshell.api.root
import ifcopenshell.geom
import ifcopenshell.util.unit
import ifcopenshell.util.shape
import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import bonsai.tool as tool
import bonsai.bim.import_ifc as import_ifc
from math import pi, inf, degrees, acos, radians
from mathutils import Vector, Matrix
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.model.decorator import ProfileDecorator
from bonsai.bim.module.boundary.decorator import BoundaryDecorator
import ifcopenshell.util.shape
import ifcopenshell.util.unit
import mathutils
import numpy as np
import shapely
import shapely.ops
from ifcopenshell.util.shape_builder import ShapeBuilder
from mathutils import Matrix, Vector
import bonsai.bim.import_ifc as import_ifc
import bonsai.core
import bonsai.core.geometry
from typing import Union, Optional
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.boundary.decorator import BoundaryDecorator
from bonsai.bim.module.model.decorator import ProfileDecorator
def disable_editing_boundary_geometry(context):
+10 -8
View File
@@ -16,21 +16,23 @@
# 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, Union
import bpy
from bpy.types import PropertyGroup
from bonsai.bim.prop import ObjProperty
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from bpy.types import PropertyGroup
import bonsai.tool as tool
from typing import TYPE_CHECKING, Union
from bonsai.bim.prop import ObjProperty
def space_filter(self: "BIMObjectBoundaryProperties", object: bpy.types.Object) -> bool:
@@ -18,6 +18,7 @@
import bpy
from bpy.types import Panel, UIList
import bonsai.tool as tool
from bonsai.bim.module.boundary.data import SpaceBoundariesData
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.AddBrick,
+2 -1
View File
@@ -17,11 +17,12 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import bonsai.tool as tool
from bonsai.tool.brick import BrickStore
try:
from rdflib import URIRef, BNode
from rdflib import BNode, URIRef
except:
# See #1860
print("Warning: brickschema not available.")
@@ -17,12 +17,14 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import os
import bpy
import ifcopenshell.api
import bonsai.tool as tool
import bonsai.core.brick as core
from bpy_extras.io_utils import ExportHelper, ImportHelper
import bonsai.bim.handler
from bpy_extras.io_utils import ImportHelper, ExportHelper
import bonsai.core.brick as core
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
from bonsai.tool.brick import BrickStore
+11 -9
View File
@@ -16,24 +16,26 @@
# 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 bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
from bonsai.bim.prop import StrProperty, Attribute
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from bpy.types import PropertyGroup
import bonsai.core.brick as core
import bonsai.tool.brick as tool
from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
from bonsai.bim.prop import Attribute, StrProperty
from bonsai.tool.brick import BrickStore
from typing import TYPE_CHECKING
def update_active_brick_index(self, context):
+2 -1
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 bonsai.tool as tool
from bpy.types import Panel, UIList
import bonsai.tool as tool
from bonsai.bim.helper import prop_with_search
from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
from bonsai.tool.brick import BrickStore
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.AddBSDDProperties,
+2 -1
View File
@@ -18,8 +18,9 @@
import bpy
import ifcopenshell
import ifcopenshell.util.date
import ifcopenshell.util.classification
import ifcopenshell.util.date
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
@@ -16,13 +16,15 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import textwrap
from typing import Any
import bpy
import bsdd
import bonsai.tool as tool
import ifcopenshell.api.pset
import ifcopenshell.util.element
import bonsai.tool as tool
from bonsai.core import bsdd as core
from typing import Any
class LoadBSDDDictionaries(bpy.types.Operator):
+14 -12
View File
@@ -16,23 +16,25 @@
# 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, Literal, Union
import bpy
import bonsai.tool as tool
from bpy.props import (
BoolProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from bpy.types import PropertyGroup
import bonsai.tool as tool
from bonsai.bim.module.bsdd.data import BSDDData
from bonsai.bim.module.classification.data import ClassificationsData
from bonsai.bim.prop import Attribute, StrProperty
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
)
from typing import Union, TYPE_CHECKING, Literal
def get_active_dictionary(self: "BIMBSDDProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
+13 -5
View File
@@ -17,14 +17,22 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import bonsai.tool as tool
from bonsai.bim.module.bsdd.data import BSDDData
from bpy.types import Panel, UIList
from typing import TYPE_CHECKING
import bpy
from bpy.types import Panel, UIList
import bonsai.tool as tool
from bonsai.bim.module.bsdd.data import BSDDData
if TYPE_CHECKING:
from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDDictionary, BSDDClassification, BSDDProperty
from bonsai.bim.module.bsdd.prop import (
BIMBSDDProperties,
BSDDClassification,
BSDDDictionary,
BSDDProperty,
)
class BIM_PT_bsdd(Panel):
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import operator, prop, workspace
classes = (
+9 -8
View File
@@ -16,17 +16,18 @@
# 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
import math
import bmesh
import mathutils
import bpy_extras
import bonsai.tool as tool
from mathutils import Vector, Matrix
from math import pi, radians, sin, cos, sqrt
import ifcopenshell.util.unit
from math import cos, pi, radians, sin, sqrt
from typing import Union
import bmesh
import bpy
import bpy_extras
import ifcopenshell.util.unit
import mathutils
from mathutils import Matrix, Vector
import bonsai.tool as tool
messages = {
"SHARED_VERTEX": "Shared Vertex, no intersection possible",
+5 -3
View File
@@ -16,12 +16,14 @@
# 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
from bonsai.bim.module.model.data import AuthoringData
from bpy.types import PropertyGroup
from math import pi
from typing import TYPE_CHECKING
import bpy
from bpy.types import PropertyGroup
from bonsai.bim.module.model.data import AuthoringData
class BIMCadProperties(PropertyGroup):
resolution: bpy.props.IntProperty(name="Arc Resolution", min=1, default=1)
@@ -17,13 +17,15 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import os
from functools import partial
import bpy
import bonsai.tool as tool
import bonsai.bim.module.type.prop as type_prop
import ifcopenshell.util.unit
from bpy.types import WorkSpaceTool
import bonsai.bim.module.type.prop as type_prop
import bonsai.tool as tool
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData
from functools import partial
def load_custom_icons():
@@ -17,13 +17,15 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.AddClashSet,
operator.AddClashSource,
operator.ExecuteIfcClash,
operator.ExportClashSets,
operator.HideClash,
operator.ImportClashSets,
operator.LoadSmartGroupsForActiveClashSet,
operator.RemoveClashSet,
+3 -1
View File
@@ -16,9 +16,11 @@
# 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
import json
import bpy
import ifcopenshell.util.element
import bonsai.tool as tool
@@ -17,13 +17,14 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blf
import gpu
import bmesh
import bonsai.tool as tool
import gpu
from bpy.types import SpaceView3D
from mathutils import Vector
from gpu_extras.batch import batch_for_shader
from bpy_extras.view3d_utils import location_3d_to_region_2d
from gpu_extras.batch import batch_for_shader
from mathutils import Vector
import bonsai.tool as tool
class ClashDecorator:
+33 -10
View File
@@ -16,22 +16,24 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import os
import bpy
import json
import tempfile
import bmesh
import logging
import numpy as np
import ifcopenshell
import bonsai.tool as tool
from pathlib import Path
from bpy_extras.io_utils import ExportHelper, ImportHelper
import os
import tempfile
from math import radians
from pathlib import Path
from typing import TYPE_CHECKING
import bmesh
import bpy
import ifcopenshell
import numpy as np
from bpy_extras.io_utils import ExportHelper, ImportHelper
from mathutils import Matrix, Vector
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.clash.decorator import ClashDecorator
from typing import TYPE_CHECKING
class ExportClashSets(bpy.types.Operator, ExportHelper):
@@ -443,6 +445,27 @@ class SelectClash(bpy.types.Operator):
return {"FINISHED"}
class HideClash(bpy.types.Operator):
bl_idname = "bim.hide_clash"
bl_label = "Hide Clash"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Hide the clash decorator"
@classmethod
def poll(cls, context):
if not ClashDecorator.is_installed:
cls.poll_message_set("No clash selected.")
return False
return True
def execute(self, context):
ClashDecorator.uninstall()
for area in context.screen.areas:
if area.type == "VIEW_3D":
area.tag_redraw()
return {"FINISHED"}
class SmartClashGroup(bpy.types.Operator):
bl_idname = "bim.smart_clash_group"
bl_label = "Smart Group Clashes"
+12 -10
View File
@@ -16,23 +16,25 @@
# 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, Literal, Union
import bpy
import bonsai.tool as tool
from bonsai.bim.prop import StrProperty, Attribute, BIMFilterGroup
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from ifcopenshell.geom.main import ClashType, CLASH_TYPE_ITEMS
from bpy.types import PropertyGroup
from ifcopenshell.geom.main import CLASH_TYPE_ITEMS, ClashType
from mathutils import Vector
from typing import TYPE_CHECKING, Literal, Union
import bonsai.tool as tool
from bonsai.bim.prop import Attribute, BIMFilterGroup, StrProperty
class ClashSource(PropertyGroup):
+15 -6
View File
@@ -17,15 +17,23 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import bonsai.tool as tool
import bonsai.bim.helper
from bpy.types import Panel
from bonsai.bim.module.clash.data import ClashData
from typing import TYPE_CHECKING, assert_never
import bpy
from bpy.types import Panel
import bonsai.bim.helper
import bonsai.tool as tool
from bonsai.bim.module.clash.data import ClashData
if TYPE_CHECKING:
from bonsai.bim.module.clash.prop import BIMClashProperties, ClashSet, SmartClashGroup, Clash
from bonsai.bim.module.clash.prop import (
BIMClashProperties,
Clash,
ClashSet,
SmartClashGroup,
)
class BIM_PT_ifcclash(Panel):
@@ -165,6 +173,7 @@ class BIM_PT_ifcclash(Panel):
layout.template_list("BIM_UL_clashes", "", props.active_clash_set, "clashes", props, "active_clash_index")
row = layout.row()
row.operator("bim.select_clash")
row.operator("bim.hide_clash", text="", icon="HIDE_ON")
else:
row.label(text="Clashes Are Not Loaded", icon="PIVOT_CURSOR")
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.AddClassification,
@@ -16,12 +16,14 @@
# 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 Any, Literal, Union
import bpy
import ifcopenshell
import ifcopenshell.util.date
import ifcopenshell.util.classification
import ifcopenshell.util.date
import bonsai.tool as tool
from typing import Any, Literal, Union
from bonsai.bim.ifc import IfcStore
@@ -104,6 +106,7 @@ class ReferencesData:
if element:
for reference in ifcopenshell.util.classification.get_references(element):
data = reference.get_info()
data["ifcClassificationReference"] = reference
del data["ReferencedSource"]
results.append(data)
return results
@@ -19,13 +19,14 @@
import bpy
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.pset
import ifcopenshell.api.classification
import ifcopenshell.api.pset
import ifcopenshell.util.classification
import ifcopenshell.util.element
import bonsai.tool as tool
import bonsai.bim.helper
from bpy_extras.io_utils import ImportHelper
import bonsai.bim.helper
import bonsai.tool as tool
from bonsai.bim.ifc import IfcStore
@@ -257,7 +258,9 @@ class EnableEditingClassificationReference(bpy.types.Operator):
def execute(self, context):
props = tool.Classification.get_classification_reference_props()
props.reference_attributes.clear()
bonsai.bim.helper.import_attributes(tool.Ifc.get().by_id(self.reference), props.reference_attributes)
ifc_reference = tool.Ifc.get().by_id(self.reference)
bonsai.bim.helper.import_attributes(ifc_reference, props.reference_attributes)
props.classification_system_name = ifc_reference.ReferencedSource.Name or ""
props.active_reference_id = self.reference
return {"FINISHED"}
@@ -324,9 +327,13 @@ class EditClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
props = tool.Classification.get_classification_reference_props()
attributes = bonsai.bim.helper.export_attributes(props.reference_attributes)
ifc_file = tool.Ifc.get()
reference_entity = ifc_file.by_id(props.active_reference_id)
referenced_source = reference_entity.ReferencedSource
if props.classification_system_name:
referenced_source.Name = props.classification_system_name
ifcopenshell.api.classification.edit_reference(
ifc_file,
reference=ifc_file.by_id(props.active_reference_id),
reference=reference_entity,
attributes=attributes,
)
bpy.ops.bim.disable_editing_classification_reference()
@@ -16,22 +16,27 @@
# 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
import bonsai.tool as tool
from bonsai.bim.prop import Attribute
from bonsai.bim.module.classification.data import ClassificationsData, ObjectClassificationsData
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from typing import TYPE_CHECKING
from bpy.types import PropertyGroup
import bonsai.tool as tool
from bonsai.bim.module.classification.data import (
ClassificationsData,
ObjectClassificationsData,
)
from bonsai.bim.prop import Attribute
def get_available_classifications(
@@ -95,6 +100,7 @@ class BIMClassificationReferenceProperties(PropertyGroup):
classifications: EnumProperty(items=get_classifications, name="Classifications")
reference_attributes: CollectionProperty(name="Reference Attributes", type=Attribute)
active_reference_id: IntProperty(name="Active Reference Id")
classification_system_name: StringProperty(name="Classification System Name")
if TYPE_CHECKING:
is_adding: bool
@@ -17,22 +17,29 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import bonsai.bim.helper
import bonsai.tool as tool
import bonsai.bim.module.classification.prop as classification_prop
from bpy.types import Panel, UIList
from bonsai.bim.module.classification.data import (
ClassificationsData,
ObjectClassificationsData,
MaterialClassificationsData,
CostClassificationsData,
ZoneClassificationsData,
)
from typing import TYPE_CHECKING, Any, Union
import bpy
import ifcopenshell.util.classification
from bpy.types import Panel, UIList
import bonsai.bim.helper
import bonsai.bim.module.classification.prop as classification_prop
import bonsai.tool as tool
from bonsai.bim.module.classification.data import (
ClassificationsData,
CostClassificationsData,
MaterialClassificationsData,
ObjectClassificationsData,
ZoneClassificationsData,
)
if TYPE_CHECKING:
from bonsai.bim.module.classification.prop import BIMClassificationProperties, ClassificationReference
from bonsai.bim.module.classification.prop import (
BIMClassificationProperties,
ClassificationReference,
)
class BIM_PT_classifications(Panel):
@@ -152,7 +159,15 @@ class ReferenceUI:
row = self.layout.row(align=True)
row.label(text="No References")
for reference in self.data.data["references"]:
def get_classification_name(reference):
classification_entity = ifcopenshell.util.classification.get_classification(
reference["ifcClassificationReference"]
)
return classification_entity.Name if classification_entity else ""
sorted_references = sorted(self.data.data["references"], key=get_classification_name)
for reference in sorted_references:
if self.props.active_reference_id == reference["id"]:
self.draw_editable_ui()
else:
@@ -248,10 +263,20 @@ class ReferenceUI:
row = self.layout.row(align=True)
row.operator("bim.edit_classification_reference", text="Save changes", icon="CHECKMARK")
row.operator("bim.disable_editing_classification_reference", text="", icon="CANCEL")
row = self.layout.row()
row.prop(self.props, "classification_system_name", text="Classification System Name")
bonsai.bim.helper.draw_attributes(self.props.reference_attributes, self.layout)
def draw_reference_ui(self, reference: dict[str, Any]) -> None:
row = self.layout.row(align=True)
classification_entity = ifcopenshell.util.classification.get_classification(
reference["ifcClassificationReference"]
)
classification_name = classification_entity.Name if classification_entity else ""
row.label(text=classification_name, icon="OUTLINER_COLLECTION")
if self.file.schema == "IFC2X3":
name = reference["ItemReference"] or "No Identification"
else:
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.LoadObjectives,
@@ -17,9 +17,10 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import bonsai.tool as tool
from ifcopenshell.util.doc import get_entity_doc
import bonsai.tool as tool
def refresh():
ConstraintsData.is_loaded = False
@@ -16,12 +16,14 @@
# 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
import ifcopenshell.api
import ifcopenshell.api.constraint
import bonsai.bim.helper
import bonsai.tool as tool
from typing import TYPE_CHECKING
def get_active_object(context: bpy.types.Context, obj_name: str) -> bpy.types.Object:
+13 -11
View File
@@ -16,23 +16,25 @@
# 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, Literal
import bpy
from ifcopenshell.util.doc import get_entity_doc
import bonsai.tool as tool
from bonsai.bim.prop import Attribute
from bonsai.bim.module.constraint.data import ConstraintsData
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from typing import TYPE_CHECKING, Literal
from bpy.types import PropertyGroup
from ifcopenshell.util.doc import get_entity_doc
import bonsai.tool as tool
from bonsai.bim.module.constraint.data import ConstraintsData
from bonsai.bim.prop import Attribute
def get_available_constraint_types(self, context):
+12 -5
View File
@@ -17,14 +17,21 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bonsai.tool as tool
from bpy.types import Panel, UIList
from bonsai.bim.helper import draw_attributes
from bonsai.bim.module.constraint.data import ConstraintsData, ObjectConstraintsData
from typing import TYPE_CHECKING
from bpy.types import Panel, UIList
import bonsai.tool as tool
from bonsai.bim.helper import draw_attributes
from bonsai.bim.module.constraint.data import ConstraintsData, ObjectConstraintsData
if TYPE_CHECKING:
from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties, Constraint
from bonsai.bim.module.constraint.prop import (
BIMConstraintProperties,
BIMObjectConstraintProperties,
Constraint,
)
class BIM_PT_constraints(Panel):
@@ -17,7 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
from . import ui, prop, operator
from . import operator, prop, ui
classes = (
operator.AddContext,
+5 -3
View File
@@ -16,11 +16,13 @@
# 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
import bonsai.tool as tool
import ifcopenshell
from typing import Any
import bpy
import ifcopenshell
import bonsai.tool as tool
def refresh():
ContextData.is_loaded = False
@@ -17,8 +17,9 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import bonsai.tool as tool
import bonsai.core.context as core
import bonsai.tool as tool
class AddContext(bpy.types.Operator, tool.Ifc.Operator):
+11 -9
View File
@@ -16,21 +16,23 @@
# 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 bonsai.bim.prop import StrProperty, Attribute
from bonsai.bim.module.context.data import ContextData
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
StringProperty,
EnumProperty,
BoolProperty,
IntProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
FloatVectorProperty,
CollectionProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from typing import TYPE_CHECKING
from bpy.types import PropertyGroup
from bonsai.bim.module.context.data import ContextData
from bonsai.bim.prop import Attribute, StrProperty
class BIMContextProperties(PropertyGroup):

Some files were not shown because too many files have changed in this diff Show More