mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 16:22:53 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a531bd8c1f | |||
| f44769c138 | |||
| a6e3cc667c | |||
| 59b17fc593 | |||
| fb1b5bea51 | |||
| e8aa508405 | |||
| 363083104b | |||
| 2798bf3b68 | |||
| e41c4bf7ae | |||
| 3bdce4fbc3 | |||
| ad7473ff1f | |||
| 3d77fc7c7d | |||
| 92a222cda7 | |||
| cc60794293 | |||
| c7b4033f6f | |||
| 1ab288de0b | |||
| 48f62c0b5b | |||
| 5fc549453c | |||
| bd5f5a30b3 | |||
| baf3edca13 | |||
| c23e973575 | |||
| a5801e439f | |||
| 4e65c33bae | |||
| c3652a56ee | |||
| e1b3b68a8b | |||
| dbce4c5d98 | |||
| 0663c5130a |
@@ -136,3 +136,7 @@ jobs:
|
||||
cd ../ifcpatch && make test
|
||||
pip install -e ../ifctester --no-deps
|
||||
cd ../ifctester && make test
|
||||
# Run mathutils related tests at the end to ensure no other code is relying on mathutils.
|
||||
cd ../ifcopenshell-python
|
||||
pip install mathutils
|
||||
make test-mathutils
|
||||
|
||||
@@ -86,6 +86,7 @@ src/bonsai/bonsai/bim/data/build/
|
||||
src/bonsai/bonsai/bim/data/gantt/index.html
|
||||
src/bonsai/bonsai/bim/data/gantt/jsgantt.js
|
||||
src/bonsai/bonsai/bim/data/gantt/jsgantt.css
|
||||
src/bonsai/bonsai/bim/data/webui/static/js/jquery.min.js
|
||||
|
||||
src/bonsai/drawings
|
||||
src/bonsai/layouts
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
python:
|
||||
- 3.12
|
||||
|
||||
occt:
|
||||
- 7.8.1
|
||||
|
||||
@@ -28,7 +31,7 @@ hdf5:
|
||||
libboost_devel:
|
||||
- '1.86'
|
||||
libxml2:
|
||||
- '2'
|
||||
- 2.13
|
||||
mpfr:
|
||||
- '4'
|
||||
gmp:
|
||||
@@ -52,4 +55,4 @@ MACOSX_DEPLOYMENT_TARGET: # [osx]
|
||||
- 10.13 # [osx and x86_64]
|
||||
|
||||
CONDA_BUILD_SYSROOT: # [osx]
|
||||
- "/Users/runner/work/MacOSX10.13.sdk" # [osx and x86_64]
|
||||
- "/Users/runner/work/MacOSX10.13.sdk" # [osx and x86_64]
|
||||
|
||||
@@ -14,11 +14,15 @@
|
||||
# Currently extensions support for v2 is only read-only.
|
||||
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field, fields
|
||||
from typing import List, NamedTuple, Optional
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsPriorities:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -35,7 +39,7 @@ class ExtensionsPriorities:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsSnippetTypes:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -52,7 +56,7 @@ class ExtensionsSnippetTypes:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsStages:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -69,7 +73,7 @@ class ExtensionsStages:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsTopicLabels:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -86,7 +90,7 @@ class ExtensionsTopicLabels:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsTopicStatuses:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -103,7 +107,7 @@ class ExtensionsTopicStatuses:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsTopicTypes:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -120,7 +124,7 @@ class ExtensionsTopicTypes:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsUsers:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -137,7 +141,7 @@ class ExtensionsUsers:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Extensions:
|
||||
topic_types: Optional[ExtensionsTopicTypes] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional
|
||||
|
||||
from xsdata.models.datatype import XmlDateTime
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class BimSnippet:
|
||||
reference: str = field(
|
||||
metadata={
|
||||
@@ -38,7 +41,7 @@ class BimSnippet:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class CommentViewpoint:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -53,7 +56,7 @@ class CommentViewpoint:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class HeaderFile:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -109,7 +112,7 @@ class HeaderFile:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicDocumentReference:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -147,7 +150,7 @@ class TopicDocumentReference:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicRelatedTopic:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -162,7 +165,7 @@ class TopicRelatedTopic:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ViewPoint:
|
||||
viewpoint: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -198,7 +201,7 @@ class ViewPoint:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Comment:
|
||||
date: XmlDateTime = field(
|
||||
metadata={
|
||||
@@ -258,7 +261,7 @@ class Comment:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Header:
|
||||
file: List[HeaderFile] = field(
|
||||
default_factory=list,
|
||||
@@ -271,7 +274,7 @@ class Header:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Topic:
|
||||
reference_link: List[str] = field(
|
||||
default_factory=list,
|
||||
@@ -425,7 +428,7 @@ class Topic:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Markup:
|
||||
header: Optional[Header] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
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(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Project:
|
||||
name: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -21,7 +24,7 @@ class Project:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ProjectExtension:
|
||||
project: Optional[Project] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
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(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Version:
|
||||
detailed_version: Optional[str] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import List, Optional
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
|
||||
class BitmapFormat(Enum):
|
||||
PNG = "PNG"
|
||||
JPG = "JPG"
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Component:
|
||||
originating_system: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -35,7 +38,7 @@ class Component:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Direction:
|
||||
x: float = field(
|
||||
metadata={
|
||||
@@ -60,7 +63,7 @@ class Direction:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Point:
|
||||
x: float = field(
|
||||
metadata={
|
||||
@@ -85,7 +88,7 @@ class Point:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ViewSetupHints:
|
||||
spaces_visible: Optional[bool] = field(
|
||||
default=None,
|
||||
@@ -110,7 +113,7 @@ class ViewSetupHints:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ClippingPlane:
|
||||
location: Point = field(
|
||||
metadata={
|
||||
@@ -128,7 +131,7 @@ class ClippingPlane:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentColoringColor:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -151,7 +154,7 @@ class ComponentColoringColor:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentSelection:
|
||||
component: List[Component] = field(
|
||||
default_factory=list,
|
||||
@@ -163,7 +166,7 @@ class ComponentSelection:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentVisibilityExceptions:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -178,7 +181,7 @@ class ComponentVisibilityExceptions:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Line:
|
||||
start_point: Point = field(
|
||||
metadata={
|
||||
@@ -196,7 +199,7 @@ class Line:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class OrthogonalCamera:
|
||||
"""
|
||||
Attributes
|
||||
@@ -236,7 +239,7 @@ class OrthogonalCamera:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class PerspectiveCamera:
|
||||
"""
|
||||
Attributes
|
||||
@@ -281,7 +284,7 @@ class PerspectiveCamera:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfoBitmap:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -330,7 +333,7 @@ class VisualizationInfoBitmap:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentColoring:
|
||||
color: List[ComponentColoringColor] = field(
|
||||
default_factory=list,
|
||||
@@ -342,7 +345,7 @@ class ComponentColoring:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentVisibility:
|
||||
exceptions: Optional[ComponentVisibilityExceptions] = field(
|
||||
default=None,
|
||||
@@ -360,7 +363,7 @@ class ComponentVisibility:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfoClippingPlanes:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -374,7 +377,7 @@ class VisualizationInfoClippingPlanes:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfoLines:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -389,7 +392,7 @@ class VisualizationInfoLines:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Components:
|
||||
view_setup_hints: Optional[ViewSetupHints] = field(
|
||||
default=None,
|
||||
@@ -421,7 +424,7 @@ class Components:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfo:
|
||||
"""
|
||||
VisualizationInfo documentation.
|
||||
|
||||
@@ -21,7 +21,7 @@ import http.server
|
||||
import os
|
||||
import tempfile
|
||||
import time
|
||||
import urllib
|
||||
import urllib.parse
|
||||
import uuid
|
||||
import webbrowser
|
||||
from re import A
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Document:
|
||||
filename: str = field(
|
||||
metadata={
|
||||
@@ -34,7 +37,7 @@ class Document:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class DocumentInfoDocuments:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -49,7 +52,7 @@ class DocumentInfoDocuments:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class DocumentInfo:
|
||||
documents: Optional[DocumentInfoDocuments] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsPriorities:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -19,7 +22,7 @@ class ExtensionsPriorities:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsSnippetTypes:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -36,7 +39,7 @@ class ExtensionsSnippetTypes:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsStages:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -53,7 +56,7 @@ class ExtensionsStages:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsTopicLabels:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -70,7 +73,7 @@ class ExtensionsTopicLabels:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsTopicStatuses:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -87,7 +90,7 @@ class ExtensionsTopicStatuses:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsTopicTypes:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -104,7 +107,7 @@ class ExtensionsTopicTypes:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ExtensionsUsers:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -121,7 +124,7 @@ class ExtensionsUsers:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Extensions:
|
||||
topic_types: Optional[ExtensionsTopicTypes] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional
|
||||
|
||||
from xsdata.models.datatype import XmlDateTime
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class BimSnippet:
|
||||
reference: str = field(
|
||||
metadata={
|
||||
@@ -44,7 +47,7 @@ class BimSnippet:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class CommentViewpoint:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -59,7 +62,7 @@ class CommentViewpoint:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class DocumentReference:
|
||||
document_guid: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -100,7 +103,7 @@ class DocumentReference:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class File:
|
||||
filename: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -157,7 +160,7 @@ class File:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicLabels:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -174,7 +177,7 @@ class TopicLabels:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicReferenceLinks:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -191,7 +194,7 @@ class TopicReferenceLinks:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicRelatedTopicsRelatedTopic:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -206,7 +209,7 @@ class TopicRelatedTopicsRelatedTopic:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ViewPoint:
|
||||
viewpoint: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -246,7 +249,7 @@ class ViewPoint:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Comment:
|
||||
date: XmlDateTime = field(
|
||||
metadata={
|
||||
@@ -312,7 +315,7 @@ class Comment:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class HeaderFiles:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -327,7 +330,7 @@ class HeaderFiles:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicDocumentReferences:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -342,7 +345,7 @@ class TopicDocumentReferences:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicRelatedTopics:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -357,7 +360,7 @@ class TopicRelatedTopics:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicViewpoints:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -372,7 +375,7 @@ class TopicViewpoints:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Header:
|
||||
files: Optional[HeaderFiles] = field(
|
||||
default=None,
|
||||
@@ -384,7 +387,7 @@ class Header:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class TopicComments:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -399,7 +402,7 @@ class TopicComments:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Topic:
|
||||
reference_links: Optional[TopicReferenceLinks] = field(
|
||||
default=None,
|
||||
@@ -596,7 +599,7 @@ class Topic:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Markup:
|
||||
header: Optional[Header] = field(
|
||||
default=None,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
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(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Project:
|
||||
name: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -25,7 +28,7 @@ class Project:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ProjectInfo:
|
||||
project: Project = field(
|
||||
metadata={
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Version:
|
||||
version_id: str = field(
|
||||
metadata={
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
DATACLASS_KWARGS = {} if sys.version_info < (3, 10) else {"slots": True, "kw_only": True}
|
||||
|
||||
|
||||
class BitmapFormat(Enum):
|
||||
PNG = "png"
|
||||
JPG = "jpg"
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Component:
|
||||
originating_system: Optional[str] = field(
|
||||
default=None,
|
||||
@@ -39,7 +43,7 @@ class Component:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Direction:
|
||||
x: float = field(
|
||||
metadata={
|
||||
@@ -64,7 +68,7 @@ class Direction:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Point:
|
||||
x: float = field(
|
||||
metadata={
|
||||
@@ -89,7 +93,7 @@ class Point:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ViewSetupHints:
|
||||
spaces_visible: bool = field(
|
||||
default=False,
|
||||
@@ -114,7 +118,7 @@ class ViewSetupHints:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Bitmap:
|
||||
format: BitmapFormat = field(
|
||||
metadata={
|
||||
@@ -162,7 +166,7 @@ class Bitmap:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ClippingPlane:
|
||||
location: Point = field(
|
||||
metadata={
|
||||
@@ -180,7 +184,7 @@ class ClippingPlane:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentColoringColorComponents:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -195,7 +199,7 @@ class ComponentColoringColorComponents:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentSelection:
|
||||
component: List[Component] = field(
|
||||
default_factory=list,
|
||||
@@ -206,7 +210,7 @@ class ComponentSelection:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentVisibilityExceptions:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -220,7 +224,7 @@ class ComponentVisibilityExceptions:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Line:
|
||||
start_point: Point = field(
|
||||
metadata={
|
||||
@@ -238,7 +242,7 @@ class Line:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class OrthogonalCamera:
|
||||
"""
|
||||
Attributes
|
||||
@@ -288,7 +292,7 @@ class OrthogonalCamera:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class PerspectiveCamera:
|
||||
"""
|
||||
Attributes
|
||||
@@ -344,7 +348,7 @@ class PerspectiveCamera:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentColoringColor:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -366,7 +370,7 @@ class ComponentColoringColor:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentVisibility:
|
||||
view_setup_hints: Optional[ViewSetupHints] = field(
|
||||
default=None,
|
||||
@@ -391,7 +395,7 @@ class ComponentVisibility:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfoBitmaps:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -405,7 +409,7 @@ class VisualizationInfoBitmaps:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfoClippingPlanes:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -419,7 +423,7 @@ class VisualizationInfoClippingPlanes:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfoLines:
|
||||
class Meta:
|
||||
global_type = False
|
||||
@@ -433,7 +437,7 @@ class VisualizationInfoLines:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class ComponentColoring:
|
||||
color: List[ComponentColoringColor] = field(
|
||||
default_factory=list,
|
||||
@@ -444,7 +448,7 @@ class ComponentColoring:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class Components:
|
||||
selection: Optional[ComponentSelection] = field(
|
||||
default=None,
|
||||
@@ -469,7 +473,7 @@ class Components:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, kw_only=True)
|
||||
@dataclass(**DATACLASS_KWARGS)
|
||||
class VisualizationInfo:
|
||||
"""
|
||||
VisualizationInfo documentation.
|
||||
|
||||
@@ -16,6 +16,7 @@ dependencies = [
|
||||
"xsdata>=24.4",
|
||||
"numpy",
|
||||
"ifcopenshell",
|
||||
"requests",
|
||||
]
|
||||
version = "0.0.0"
|
||||
classifiers = [
|
||||
|
||||
+1
-2
@@ -201,8 +201,7 @@ endif
|
||||
cd build/bonsai/bim/data/gantt/ && wget https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.css
|
||||
|
||||
# Provides IFCJSON functionality
|
||||
# TODO: replace with main repo if https://github.com/IFCJSON-Team/IFC2JSON_python/pull/3 is merged.
|
||||
cd build && wget -O ifc2json.zip https://github.com/Moult/IFC2JSON_python/archive/refs/heads/feature-ios-v0.8.0.zip
|
||||
cd build && wget -O ifc2json.zip https://github.com/IFCJSON-Team/IFC2JSON_python/archive/refs/heads/master.zip
|
||||
cd build && unzip ifc2json.zip && rm ifc2json.zip
|
||||
# IFCJSON doesn't have pyproject.toml, so we use python command.
|
||||
cd build && . env/$(VENV_ACTIVATE) && cd IFC2JSON_python-*/file_converters && \
|
||||
|
||||
@@ -350,6 +350,11 @@ def load_post(scene):
|
||||
aggregate_props = tool.Aggregate.get_aggregate_props()
|
||||
nest_props = tool.Nest.get_nest_props()
|
||||
model_props = tool.Model.get_model_props()
|
||||
GeoreferenceDecorator.uninstall()
|
||||
AggregateDecorator.uninstall()
|
||||
NestDecorator.uninstall()
|
||||
WallAxisDecorator.uninstall()
|
||||
SlabDirectionDecorator.uninstall()
|
||||
if georeference_props.should_visualise:
|
||||
GeoreferenceDecorator.install(bpy.context)
|
||||
if aggregate_props.aggregate_decorator:
|
||||
|
||||
@@ -2558,7 +2558,8 @@ class EnableEditingRepresentationItemStyle(bpy.types.Operator, tool.Ifc.Operator
|
||||
ifc_file = tool.Ifc.get()
|
||||
|
||||
# set dropdown to currently active style
|
||||
representation_item_id = props.active_item.ifc_definition_id
|
||||
assert (active_item := props.active_item)
|
||||
representation_item_id = active_item.ifc_definition_id
|
||||
representation_item = ifc_file.by_id(representation_item_id)
|
||||
style = tool.Style.get_representation_item_style(representation_item)
|
||||
if style:
|
||||
@@ -2577,8 +2578,14 @@ class EditRepresentationItemStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
props.is_editing_item_style = False
|
||||
ifc_file = tool.Ifc.get()
|
||||
|
||||
surface_style = ifc_file.by_id(int(props.representation_item_style))
|
||||
representation_item_id = props.active_item.ifc_definition_id
|
||||
surface_style_id = tool.Blender.get_enum_safe(props, "representation_item_style")
|
||||
if surface_style_id in (None, "-"):
|
||||
surface_style = None
|
||||
else:
|
||||
surface_style = ifc_file.by_id(int(props.representation_item_style))
|
||||
|
||||
assert (active_item := props.active_item)
|
||||
representation_item_id = active_item.ifc_definition_id
|
||||
representation_item = ifc_file.by_id(representation_item_id)
|
||||
|
||||
tool.Style.assign_style_to_representation_item(representation_item, surface_style)
|
||||
|
||||
@@ -101,7 +101,9 @@ class MaterialsData:
|
||||
for s in tool.Ifc.get().by_type("IfcPresentationStyle")
|
||||
if (style_name := s.Name) is not None
|
||||
]
|
||||
return natsorted(results, key=lambda i: i[1])
|
||||
results = natsorted(results, key=lambda i: i[1])
|
||||
results.insert(0, ("-", "No Surface Style", ""))
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def material_styles_data(cls) -> dict[int, list[dict[str, Any]]]:
|
||||
|
||||
@@ -22,9 +22,9 @@ import numpy as np
|
||||
from math import sin
|
||||
from mathutils import Vector
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.attribute
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.unit as ifcunit
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.structural.shader import DecorationShader
|
||||
|
||||
@@ -21,7 +21,9 @@ import bpy
|
||||
import bonsai.core.tool
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.helper
|
||||
import bonsai.core.geometry
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.representation
|
||||
from typing import Iterable, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
"""Setup Bonsai Development Environment.
|
||||
|
||||
Script links existing Bonsai installation to the provided IfcOpenShell repository.
|
||||
|
||||
If you're on Windows, using Blender 4.4, Bonsai is installed from unstable repo (raw_githubusercontent_com)
|
||||
and this script is already part of IfcOpenShell repo you want to link, then you can just run it and it will just work.
|
||||
|
||||
Otherwise, see the SETTINGS section below to validate script settings to ensure it fits your evnironment.
|
||||
|
||||
Example usage:
|
||||
|
||||
python /xxx/yyy/dev_environment.py
|
||||
python dev_environment.py
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
if sys.platform != "win32":
|
||||
print("Currently only available on Windows.")
|
||||
exit(1)
|
||||
|
||||
# ---------------------------
|
||||
# SETTINGS.
|
||||
# ---------------------------
|
||||
# REPO_PATH: Path to your local IfcOpenShell repository.
|
||||
# By default, this script will automatically detect the repository path based on its own location,
|
||||
# so you usually do NOT need to set this manually.
|
||||
# If you want to specify it explicitly, set it to the full absolute path, e.g.:
|
||||
# > REPO_PATH = r"C:\Path\To\Your\IfcOpenShell\Repository"
|
||||
REPO_PATH = r""
|
||||
|
||||
# BLENDER_PATH: Path to Blender's configuration folder.
|
||||
# Usually don't need to change, just ensure Blender version matches.
|
||||
BLENDER_PATH = Path.home() / r"AppData/Roaming/Blender Foundation/Blender/4.4"
|
||||
|
||||
# BONSAI_PATH: Path to 'bonsai' extension folder inside BLENDER_PATH.
|
||||
# Need to ensure extensions repo folder in the path below ('raw_githubusercontent_com') matches yours.
|
||||
#
|
||||
# Typical scenarios:
|
||||
# - Bonsai is installed from Bonsai Unstalble Repo - use 'raw_githubusercontent_com' (as it is by default)
|
||||
# - Bonsai is installed via offline installation - use 'user_default'
|
||||
# - Bonsai is installed from Blender's official extensions platform - use 'blender_org'
|
||||
BONSAI_PATH = BLENDER_PATH / r"extensions/raw_githubusercontent_com/bonsai"
|
||||
|
||||
# ---------------------------
|
||||
|
||||
# Never changed by user.
|
||||
PACKAGE_PATH = BLENDER_PATH / r"extensions/.local/lib/python3.11/site-packages"
|
||||
|
||||
|
||||
def main():
|
||||
global REPO_PATH
|
||||
|
||||
if not REPO_PATH:
|
||||
script_path = Path(__file__)
|
||||
print(f"REPO_PATH is not set, deducing it from {script_path.name} location...")
|
||||
repo_bonsai_path = script_path.parent.parent.parent
|
||||
assert repo_bonsai_path.name == "bonsai"
|
||||
REPO_PATH = repo_bonsai_path.parent.parent
|
||||
|
||||
print("-" * 10)
|
||||
print("Script settings:")
|
||||
print(f"REPO_PATH={REPO_PATH}")
|
||||
print(f"BLENDER_PATH={BLENDER_PATH}")
|
||||
print(f"BONSAI_PATH={BONSAI_PATH}")
|
||||
print("-" * 10)
|
||||
|
||||
assert REPO_PATH.exists(), f"Path '{REPO_PATH=!s}' doesn't exist, ensure variable is set correctly."
|
||||
assert BLENDER_PATH.exists(), f"Path '{BLENDER_PATH=!s}' doesn't exist, ensure variable is set correctly."
|
||||
assert PACKAGE_PATH.exists(), f"Path '{PACKAGE_PATH=!s}' doesn't exist, ensure variable is set correctly."
|
||||
assert BONSAI_PATH.exists(), f"Path '{BONSAI_PATH=!s}' doesn't exist, ensure variable is set correctly."
|
||||
|
||||
input("Confirm the settings above and press Enter to continue or Ctrl-C to cancel...")
|
||||
|
||||
# Handle symlinks
|
||||
# (they could be disabled by default on Windows).
|
||||
subprocess.run("git config --local core.symlinks true", cwd=REPO_PATH)
|
||||
symlinks_glob = "src/bonsai/bonsai/bim/data/templates/projects/*.ifc"
|
||||
# Delete and checkout is the only way to ensure files are added as symlinks.
|
||||
for path in REPO_PATH.glob(symlinks_glob):
|
||||
path.unlink()
|
||||
subprocess.run((f"git checkout -- {symlinks_glob}"), cwd=REPO_PATH)
|
||||
|
||||
print("Copying compiled dependencies to the repo...")
|
||||
dest = REPO_PATH / "src" / "ifcopenshell-python" / "ifcopenshell"
|
||||
for path in PACKAGE_PATH.glob("ifcopenshell/*_wrapper*"):
|
||||
if path.suffix.lower() == ".pyi":
|
||||
continue
|
||||
dest_ = dest / path.name
|
||||
print(f"Copying {path} -> {dest_}")
|
||||
try:
|
||||
shutil.copy(path, dest_)
|
||||
except shutil.SameFileError:
|
||||
pass
|
||||
|
||||
print("Symlinking extension to the git repo...")
|
||||
# fmt: off
|
||||
symlinks = (
|
||||
(BONSAI_PATH / "__init__.py", REPO_PATH / "src/bonsai/bonsai/__init__.py"),
|
||||
(PACKAGE_PATH / "bonsai", REPO_PATH / "src/bonsai/bonsai"),
|
||||
(PACKAGE_PATH / "ifcopenshell", REPO_PATH / "src/ifcopenshell-python/ifcopenshell"),
|
||||
(PACKAGE_PATH / "ifccsv.py", REPO_PATH / "src/ifccsv/ifccsv.py"),
|
||||
(PACKAGE_PATH / "ifcdiff.py", REPO_PATH / "src/ifcdiff/ifcdiff.py"),
|
||||
(PACKAGE_PATH / "bsdd.py", REPO_PATH / "src/bsdd/bsdd.py"),
|
||||
(PACKAGE_PATH / "bcf", REPO_PATH / "src/bcf/bcf"),
|
||||
(PACKAGE_PATH / "ifc4d", REPO_PATH / "src/ifc4d/ifc4d"),
|
||||
(PACKAGE_PATH / "ifc5d", REPO_PATH / "src/ifc5d/ifc5d"),
|
||||
(PACKAGE_PATH / "ifccityjson", REPO_PATH / "src/ifccityjson/ifccityjson"),
|
||||
(PACKAGE_PATH / "ifcclash", REPO_PATH / "src/ifcclash/ifcclash"),
|
||||
(PACKAGE_PATH / "ifcpatch", REPO_PATH / "src/ifcpatch/ifcpatch"),
|
||||
(PACKAGE_PATH / "ifctester", REPO_PATH / "src/ifctester/ifctester"),
|
||||
(PACKAGE_PATH / "ifcfm", REPO_PATH / "src/ifcfm/ifcfm"),
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
for path, dest in symlinks:
|
||||
print(f"Linking {path} -> {dest}.")
|
||||
if path.is_dir():
|
||||
if path.is_symlink():
|
||||
path.unlink()
|
||||
else:
|
||||
shutil.rmtree(path)
|
||||
elif path.is_file():
|
||||
path.unlink()
|
||||
else:
|
||||
pass
|
||||
path.symlink_to(dest, dest.is_dir())
|
||||
|
||||
print("Download third party dependencies...")
|
||||
BONSAI_DATA = PACKAGE_PATH / "bonsai" / "bim" / "data"
|
||||
downloads = (
|
||||
(
|
||||
"https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.js",
|
||||
BONSAI_DATA / "gantt" / "jsgantt.js",
|
||||
),
|
||||
(
|
||||
"https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.css",
|
||||
BONSAI_DATA / "gantt" / "jsgantt.css",
|
||||
),
|
||||
(
|
||||
"https://github.com/BrickSchema/Brick/releases/download/nightly/Brick.ttl",
|
||||
BONSAI_DATA / "brick" / "Brick.ttl",
|
||||
),
|
||||
(
|
||||
"https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js",
|
||||
BONSAI_DATA / "webui" / "static" / "js" / "jquery.min.js",
|
||||
),
|
||||
)
|
||||
|
||||
for url, filepath in downloads:
|
||||
print(f"Downloading {url} -> {filepath}")
|
||||
urllib.request.urlretrieve(url, filepath)
|
||||
|
||||
input("Dev environment is all set. 🎉🎉\nPress Enter to continue..." "")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+1
-1
@@ -19,7 +19,7 @@ from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
import time
|
||||
import urllib
|
||||
import urllib.parse
|
||||
import requests
|
||||
import webbrowser
|
||||
import http.server
|
||||
|
||||
@@ -40,6 +40,8 @@ from .scriptCodeAster import CommandFileConstructor
|
||||
|
||||
|
||||
class Ifc2CA:
|
||||
file: ifcopenshell.file
|
||||
|
||||
folder_path = None
|
||||
salome_path = None
|
||||
model_keys = ["id", "type", "GlobalId", "Name", "LoadedBy", "HasResults"]
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import csv
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.date
|
||||
import locale
|
||||
import re
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import uuid
|
||||
import datetime
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.sequence
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import uuid
|
||||
import datetime
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.sequence
|
||||
import xml.etree.ElementTree as ET
|
||||
from .common import ScheduleIfcGenerator
|
||||
|
||||
|
||||
@@ -6,11 +6,14 @@ for each day as a key there is a list of working times with the format
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import re
|
||||
from datetime import time, datetime
|
||||
from typing import Any
|
||||
from ifc4d.common import WorkSlot
|
||||
|
||||
ZIP_STRICT = {} if sys.version_info < (3, 10) else {"strict": True}
|
||||
|
||||
|
||||
class AstaCalendarWorkPattern:
|
||||
def get_keys(self, s: str) -> list[str]:
|
||||
@@ -120,7 +123,7 @@ class AstaCalendarWorkPattern:
|
||||
self.values = self.get_values(string)
|
||||
self.dict_wp: list[WorkSlot] = []
|
||||
|
||||
for value, day_name in zip(self.values[1:], self.day_names, strict=True):
|
||||
for value, day_name in zip(self.values[1:], self.day_names, **ZIP_STRICT):
|
||||
splt_data = value.strip().split(",")
|
||||
workhours: list[dict[str, Any]] = []
|
||||
if len(splt_data) >= 7:
|
||||
|
||||
@@ -27,7 +27,8 @@ import ifcopenshell.util.selector
|
||||
import ifcopenshell.util.element
|
||||
import locale
|
||||
from pathlib import Path
|
||||
from typing import Any, Union, Optional, TypedDict, NotRequired
|
||||
from typing import Union, Optional, TypedDict
|
||||
from typing_extensions import NotRequired
|
||||
|
||||
|
||||
class CsvHeader(TypedDict):
|
||||
|
||||
@@ -29,7 +29,7 @@ import ifcopenshell.util.cost
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.unit
|
||||
from collections import Counter
|
||||
from typing import Union, Optional, Any, TypedDict, NotRequired
|
||||
from typing import Union, Optional, Any, TypedDict
|
||||
|
||||
|
||||
class CostItem(TypedDict):
|
||||
|
||||
@@ -258,6 +258,7 @@ class Cityjson2ifc:
|
||||
# TODO but maybe there is a better method.
|
||||
file = self.properties["file_destination"] + lod + self.properties["file_extension"]
|
||||
self.IFC_model.write(file)
|
||||
IFC_copied_model: ifcopenshell.file
|
||||
IFC_copied_model = ifcopenshell.open(file)
|
||||
IFC_copied_model_sub_contexts = IFC_copied_model.by_type("IfcGeometricRepresentationSubContext")
|
||||
for sub_context in IFC_copied_model_sub_contexts:
|
||||
|
||||
@@ -18,7 +18,7 @@ classifiers = [
|
||||
]
|
||||
dependencies = [
|
||||
"ifcopenshell",
|
||||
"cjio>=0.8"
|
||||
"cjio >=0.8, <0.10"
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
||||
@@ -559,6 +559,7 @@ if __name__ == "__main__":
|
||||
)
|
||||
elif getattr(args, "import"):
|
||||
ifc_csv = IfcCsv()
|
||||
ifc_file: ifcopenshell.file
|
||||
ifc_file = ifcopenshell.open(args.ifc)
|
||||
ifc_csv.Import(
|
||||
ifc_file,
|
||||
|
||||
@@ -60,7 +60,11 @@ IFCCONVERT_URL:=https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.8.3-e
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
pytest -p no:pytest-blender test
|
||||
pytest -p no:pytest-blender test --ignore=test/util/test_shape_builder.py
|
||||
|
||||
.PHONY: test-mathutils
|
||||
test-mathutils:
|
||||
pytest -p no:pytest-blender test/util/test_shape_builder.py
|
||||
|
||||
.PHONY: build-ids-docs
|
||||
build-ids-docs:
|
||||
|
||||
@@ -65,7 +65,7 @@ if TYPE_CHECKING:
|
||||
import ifcopenshell.express.schema_class
|
||||
|
||||
|
||||
if hasattr(os, "uname"):
|
||||
if sys.platform != "win32":
|
||||
platform_system = os.uname()[0].lower()
|
||||
else:
|
||||
platform_system = "windows"
|
||||
|
||||
@@ -43,9 +43,11 @@ import numpy
|
||||
import inspect
|
||||
import importlib
|
||||
import ifcopenshell
|
||||
from typing import Callable, Any, Optional
|
||||
from typing import Callable, Any, Optional, TYPE_CHECKING
|
||||
from functools import partial
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import ifcopenshell.api
|
||||
|
||||
pre_listeners: dict[str, dict] = {}
|
||||
post_listeners: dict[str, dict] = {}
|
||||
@@ -185,7 +187,7 @@ def extract_docs(module: str, usecase: str) -> dict[str, Any]:
|
||||
type_hints = typing.get_type_hints(function_init)
|
||||
for name, socket_data in inputs.items():
|
||||
type_hint = type_hints[name]
|
||||
if isinstance(type_hint, typing._UnionGenericAlias):
|
||||
if isinstance(type_hint, typing._UnionGenericAlias): # pyright: ignore[reportAttributeAccessIssue]
|
||||
inputs[name]["type"] = [t.__name__ for t in typing.get_args(type_hint)]
|
||||
else:
|
||||
inputs[name]["type"] = type_hint.__name__
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.nest
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.util.stationing
|
||||
import ifcopenshell.guid
|
||||
from ifcopenshell import entity_instance
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.nest
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.representation
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.nest
|
||||
from ifcopenshell import entity_instance
|
||||
from typing import Sequence
|
||||
|
||||
|
||||
+2
-3
@@ -17,11 +17,10 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.api.alignment
|
||||
from ifcopenshell import entity_instance
|
||||
from ifcopenshell import ifcopenshell_wrapper
|
||||
import math
|
||||
from typing import Sequence
|
||||
|
||||
|
||||
def create_segment_representations(
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.nest
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.element
|
||||
from ifcopenshell import entity_instance
|
||||
|
||||
|
||||
|
||||
@@ -49,8 +49,6 @@ def map_alignment_segments(
|
||||
elif alignment.is_a("IfcAlignmentCant") and not composite_curve.is_a("IfcSegmentedReferenceCurve"):
|
||||
raise TypeError(f"Expected to see IfcSegmentedReferenceCurve, instead received '{composite_curve.is_a()}'.")
|
||||
|
||||
settings = ifcopenshell.geom.settings()
|
||||
|
||||
composite_curve.SelfIntersect = False
|
||||
|
||||
for rel_nests in alignment.IsNestedBy:
|
||||
@@ -64,6 +62,8 @@ def map_alignment_segments(
|
||||
mapped_segments = ifcopenshell.api.alignment.map_alignment_cant_segment(
|
||||
file, layout, alignment.RailHeadDistance
|
||||
)
|
||||
else:
|
||||
assert False
|
||||
for mapped_segment in mapped_segments:
|
||||
if mapped_segment:
|
||||
ifcopenshell.api.alignment.add_segment_to_curve(file, mapped_segment, composite_curve)
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import ifcopenshell.api.owner
|
||||
import ifcopenshell.util.element
|
||||
from typing import Any, Union
|
||||
from types import EllipsisType
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
from types import EllipsisType
|
||||
else:
|
||||
EllipsisType = type(...)
|
||||
|
||||
|
||||
def edit_attributes(file: ifcopenshell.file, product: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
|
||||
@@ -51,7 +51,7 @@ def copy_cost_item_values(
|
||||
ifcopenshell.api.cost.copy_cost_item_values(model, source=item1, destination=item2)
|
||||
"""
|
||||
for cost_value in destination.CostValues or []:
|
||||
ifcopenshell.api.cost.remove_cost_item_value(file, cost_value=cost_value)
|
||||
ifcopenshell.api.cost.remove_cost_value(file, source, cost_value=cost_value)
|
||||
copied_cost_values = []
|
||||
for cost_value in source.CostValues or []:
|
||||
copied_cost_values.append(ifcopenshell.util.element.copy_deep(file, cost_value))
|
||||
|
||||
@@ -34,7 +34,8 @@ from .add_railing_representation import add_railing_representation
|
||||
|
||||
try:
|
||||
from .add_representation import add_representation
|
||||
except ModuleNotFoundError:
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
# ImportError - in case if user has fake-bpy modules.
|
||||
pass # Silently fail. This is Blender / Bonsai specific and on its way out.
|
||||
from .add_shape_aspect import add_shape_aspect
|
||||
from .add_slab_representation import add_slab_representation
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import sys
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.api.geometry
|
||||
import dataclasses
|
||||
@@ -26,6 +27,8 @@ from ifcopenshell.api.geometry.add_window_representation import create_ifc_windo
|
||||
from math import cos, radians
|
||||
from typing import Any, Optional, Literal, Union, get_args, overload
|
||||
|
||||
DATACLASS_SLOTS = {} if sys.version_info < (3, 10) else {"slots": True}
|
||||
|
||||
|
||||
DOOR_TYPE = Literal[
|
||||
"SINGLE_SWING_LEFT",
|
||||
@@ -96,7 +99,7 @@ def create_ifc_box(
|
||||
|
||||
# we use dataclass as we need default values for arguments
|
||||
# it's okay to use slots since we don't need dynamic attributes
|
||||
@dataclasses.dataclass(slots=True)
|
||||
@dataclasses.dataclass(**DATACLASS_SLOTS)
|
||||
class DoorLiningProperties:
|
||||
LiningDepth: Optional[float] = None
|
||||
"""Optional, defaults to 50mm."""
|
||||
@@ -170,7 +173,7 @@ class DoorLiningProperties:
|
||||
setattr(self, attr, default_value * si_conversion)
|
||||
|
||||
|
||||
@dataclasses.dataclass(slots=True)
|
||||
@dataclasses.dataclass(**DATACLASS_SLOTS)
|
||||
class DoorPanelProperties:
|
||||
PanelDepth: Optional[float] = None
|
||||
"""Frame thickness by Y axis. Optional, defaults to 35 mm."""
|
||||
|
||||
@@ -17,13 +17,17 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import sys
|
||||
import numpy as np
|
||||
import dataclasses
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.unit
|
||||
from itertools import chain
|
||||
from ifcopenshell.util.shape_builder import ShapeBuilder, V
|
||||
from typing import Any, Optional, Literal, Union, overload
|
||||
|
||||
DATACLASS_SLOTS = {} if sys.version_info < (3, 10) else {"slots": True}
|
||||
ZIP_STRICT = {} if sys.version_info < (3, 10) else {"strict": True}
|
||||
|
||||
# SCHEMAS describe panels setup
|
||||
# where:
|
||||
@@ -165,7 +169,7 @@ def window_l_shape_check(
|
||||
"""`lining_thickness` and `lining_to_panel_offset_x` expected to be defined as a list,
|
||||
similarly to `create_ifc_window_frame_simple` `thickness` argument"""
|
||||
l_shape_check = lining_to_panel_offset_y_full < lining_depth and any(
|
||||
x_offset < th for th, x_offset in zip(lining_thickness, lining_to_panel_offset_x, strict=True)
|
||||
x_offset < th for th, x_offset in zip(lining_thickness, lining_to_panel_offset_x, **ZIP_STRICT)
|
||||
)
|
||||
return l_shape_check
|
||||
|
||||
@@ -207,7 +211,7 @@ def create_ifc_window(
|
||||
second_lining_size = lining_size.copy()
|
||||
second_lining_size[np_Y] = lining_size[np_Y] - lining_to_panel_offset_y_full
|
||||
second_lining_position = V(0, lining_to_panel_offset_y_full, 0)
|
||||
second_lining_thickness = [min(th, x_offset) for th, x_offset in zip(lining_thickness, x_offsets, strict=True)]
|
||||
second_lining_thickness = [min(th, x_offset) for th, x_offset in zip(lining_thickness, x_offsets, **ZIP_STRICT)]
|
||||
|
||||
second_lining_items = create_ifc_window_frame_simple(
|
||||
builder, second_lining_size, second_lining_thickness, second_lining_position
|
||||
@@ -237,7 +241,7 @@ def create_ifc_window(
|
||||
|
||||
# we use dataclass as we need default values for arguments
|
||||
# it's okay to use slots since we don't need dynamic attributes
|
||||
@dataclasses.dataclass(slots=True)
|
||||
@dataclasses.dataclass(**DATACLASS_SLOTS)
|
||||
class WindowLiningProperties:
|
||||
LiningDepth: Optional[float] = None
|
||||
"""Optional, defaults to 50mm."""
|
||||
@@ -320,7 +324,7 @@ class WindowLiningProperties:
|
||||
setattr(self, attr, default_value * si_conversion)
|
||||
|
||||
|
||||
@dataclasses.dataclass(slots=True)
|
||||
@dataclasses.dataclass(**DATACLASS_SLOTS)
|
||||
class WindowPanelProperties:
|
||||
FrameDepth: Optional[float] = None
|
||||
"""Frame thickness by Y axis. Optional, defaults to 35 mm."""
|
||||
|
||||
@@ -18,11 +18,10 @@
|
||||
|
||||
import numpy as np
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.owner
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.shape_builder
|
||||
from typing import Optional
|
||||
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
import json
|
||||
import numpy as np
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.shape_builder
|
||||
import ifcopenshell.util.unit
|
||||
from collections import namedtuple
|
||||
from math import sin, cos
|
||||
from typing import Optional
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.geolocation
|
||||
import ifcopenshell.util.unit
|
||||
import numpy as np
|
||||
from math import sin, cos, radians
|
||||
|
||||
|
||||
@@ -18,6 +18,75 @@
|
||||
|
||||
from typing import Any
|
||||
|
||||
# `std::vector<xxx>` usually translated to `tuple[xxx, ...]`.
|
||||
|
||||
ON_SLABS_AND_WALLS: Any
|
||||
ON_SLABS_AT_FLOORPLANS: Any
|
||||
ALWAYS: Any
|
||||
|
||||
ATPATH: Any
|
||||
ATSTART: Any
|
||||
ATEND: Any
|
||||
NOTDEFINED: Any
|
||||
|
||||
MATRIX4: Any
|
||||
POINT3: Any
|
||||
DIRECTION3: Any
|
||||
LINE: Any
|
||||
CIRCLE: Any
|
||||
ELLIPSE: Any
|
||||
BSPLINE_CURVE: Any
|
||||
OFFSET_CURVE: Any
|
||||
PLANE: Any
|
||||
CYLINDER: Any
|
||||
SPHERE: Any
|
||||
TORUS: Any
|
||||
BSPLINE_SURFACE: Any
|
||||
EDGE: Any
|
||||
LOOP: Any
|
||||
FACE: Any
|
||||
SHELL: Any
|
||||
SOLID: Any
|
||||
LOFT: Any
|
||||
EXTRUSION: Any
|
||||
REVOLVE: Any
|
||||
SWEEP_ALONG_CURVE: Any
|
||||
NODE: Any
|
||||
COLLECTION: Any
|
||||
BOOLEAN_RESULT: Any
|
||||
FUNCTION_ITEM: Any
|
||||
FUNCTOR_ITEM: Any
|
||||
PIECEWISE_FUNCTION: Any
|
||||
GRADIENT_FUNCTION: Any
|
||||
CANT_FUNCTION: Any
|
||||
OFFSET_FUNCTION: Any
|
||||
COLOUR: Any
|
||||
STYLE: Any
|
||||
|
||||
CARTESIAN_DOUBLE: Any
|
||||
CARTESIAN_QUOTIENT: Any
|
||||
FILTERED_CARTESIAN_QUOTIENT: Any
|
||||
EXACT_PREDICATES: Any
|
||||
EXACT_CONSTRUCTIONS: Any
|
||||
|
||||
CURVES: Any
|
||||
SURFACES_AND_SOLIDS: Any
|
||||
CURVES_SURFACES_AND_SOLIDS: Any
|
||||
TRIANGULATED: Any
|
||||
NATIVE: Any
|
||||
SERIALIZED: Any
|
||||
|
||||
MAXSTEPSIZE: Any
|
||||
MINSTEPS: Any
|
||||
|
||||
TRIANGLE_MESH: Any
|
||||
POLYHEDRON_WITHOUT_HOLES: Any
|
||||
POLYHEDRON_WITH_HOLES: Any
|
||||
|
||||
SHARED_PTR_DISOWN: Any
|
||||
|
||||
cvar: Any
|
||||
|
||||
class FileDescription(HeaderEntity):
|
||||
description: tuple[str, ...]
|
||||
implementation_level: str
|
||||
@@ -65,11 +134,6 @@ class BRepElement(Element):
|
||||
@property
|
||||
def volume(self): ...
|
||||
|
||||
class CacheShapes:
|
||||
name: Any
|
||||
description: Any
|
||||
defaultvalue: Any
|
||||
|
||||
class CgalEmitOriginalEdges:
|
||||
name: Any
|
||||
description: Any
|
||||
@@ -195,6 +259,15 @@ class GeometrySerializer:
|
||||
def settings(self, *args): ...
|
||||
def write(self, *args): ...
|
||||
|
||||
class GltfSerializer(WriteOnlyGeometrySerializer):
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
def ready(self): ...
|
||||
def setFile(self, arg2): ...
|
||||
def setUnitNameAndMagnitude(self, arg2, arg3): ...
|
||||
def write(self, *args): ...
|
||||
def writeHeader(self): ...
|
||||
|
||||
class HdfSerializer(GeometrySerializer):
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
@@ -226,9 +299,13 @@ class IfcEntityInstanceData: ...
|
||||
class IfcLateBoundEntity(IfcBaseEntity):
|
||||
def declaration(self): ...
|
||||
|
||||
class InstanceReference: ...
|
||||
class InstanceReference:
|
||||
file_offset: Any
|
||||
v: Any
|
||||
|
||||
class Iterator:
|
||||
initialization_outcome_: Any
|
||||
processed_: Any
|
||||
def bounds_max(self): ...
|
||||
def bounds_min(self): ...
|
||||
def compute_bounds(self, with_geometry): ...
|
||||
@@ -249,11 +326,6 @@ class Iterator:
|
||||
def unit_magnitude(self): ...
|
||||
def unit_name(self): ...
|
||||
|
||||
class OcctNoCleanTriangulation:
|
||||
name: Any
|
||||
description: Any
|
||||
defaultvalue: Any
|
||||
|
||||
class OpaqueCoordinate_3:
|
||||
def get(self, i): ...
|
||||
def set(self, i, n): ...
|
||||
@@ -267,11 +339,6 @@ class OpaqueNumber:
|
||||
def to_double(self): ...
|
||||
def to_string(self): ...
|
||||
|
||||
class PermissiveShapeReuse:
|
||||
name: Any
|
||||
description: Any
|
||||
defaultvalue: Any
|
||||
|
||||
class Representation:
|
||||
def entity(self): ...
|
||||
@property
|
||||
@@ -477,6 +544,8 @@ class XmlSerializerFactory:
|
||||
@staticmethod
|
||||
def implementations(): ...
|
||||
|
||||
class _SwigNonDynamicMeta(type): ...
|
||||
|
||||
class abstract_arrangement:
|
||||
def get_face_pairs(self): ...
|
||||
def merge(self, edge_indices): ...
|
||||
@@ -497,9 +566,9 @@ class aggregation_type(parameter_type):
|
||||
def type_of_element(self): ...
|
||||
|
||||
class attribute:
|
||||
def name(self): ...
|
||||
def optional(self): ...
|
||||
def type_of_attribute(self): ...
|
||||
def name(self) -> str: ...
|
||||
def optional(self) -> bool: ...
|
||||
def type_of_attribute(self) -> parameter_type: ...
|
||||
|
||||
class attribute_value_derived: ...
|
||||
|
||||
@@ -507,6 +576,7 @@ class boolean_result:
|
||||
INTERSECTION: Any
|
||||
SUBTRACTION: Any
|
||||
UNION: Any
|
||||
operation: Any
|
||||
def calc_hash(self): ...
|
||||
@property
|
||||
def children(self): ...
|
||||
@@ -516,11 +586,21 @@ class boolean_result:
|
||||
def operation_str(op): ...
|
||||
|
||||
class bspline_curve(curve):
|
||||
control_points: Any
|
||||
degree: Any
|
||||
knots: Any
|
||||
multiplicities: Any
|
||||
weights: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
|
||||
class bspline_surface(surface):
|
||||
control_points: Any
|
||||
degree: Any
|
||||
knots: Any
|
||||
multiplicities: Any
|
||||
weights: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -540,6 +620,7 @@ class cant_function(function_item):
|
||||
def start(self): ...
|
||||
|
||||
class circle(curve):
|
||||
radius: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
@staticmethod
|
||||
@@ -548,7 +629,13 @@ class circle(curve):
|
||||
@property
|
||||
def matrix(self): ...
|
||||
|
||||
class clash: ...
|
||||
class clash:
|
||||
a: Any
|
||||
b: Any
|
||||
clash_type: Any
|
||||
distance: Any
|
||||
p1: Any
|
||||
p2: Any
|
||||
|
||||
class clashes:
|
||||
def append(self, x): ...
|
||||
@@ -606,6 +693,7 @@ class curve(geom_item):
|
||||
def print_impl(self, o, classname, indent): ...
|
||||
|
||||
class cylinder(surface):
|
||||
radius: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -613,12 +701,13 @@ class cylinder(surface):
|
||||
def matrix(self): ...
|
||||
|
||||
class declaration:
|
||||
def _is(self, *args: str) -> bool: ...
|
||||
def as_entity(self): ...
|
||||
def as_enumeration_type(self): ...
|
||||
def as_select_type(self): ...
|
||||
def as_type_declaration(self): ...
|
||||
def index_in_schema(self): ...
|
||||
def name(self): ...
|
||||
def name(self) -> str: ...
|
||||
def name_uc(self): ...
|
||||
def schema(self): ...
|
||||
def type(self): ...
|
||||
@@ -630,7 +719,9 @@ class direction3:
|
||||
def components(self): ...
|
||||
def kind(self): ...
|
||||
|
||||
class drawing_meta: ...
|
||||
class drawing_meta:
|
||||
matrix_3: Any
|
||||
pln_3d: Any
|
||||
|
||||
class edge(trimmed_curve):
|
||||
def calc_hash(self): ...
|
||||
@@ -638,6 +729,8 @@ class edge(trimmed_curve):
|
||||
def kind(self): ...
|
||||
|
||||
class ellipse(curve):
|
||||
radius: Any
|
||||
radius2: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -649,11 +742,14 @@ class entity(declaration):
|
||||
def all_inverse_attributes(self): ...
|
||||
def argument_types(self): ...
|
||||
def as_entity(self): ...
|
||||
def attribute_by_index(self, index): ...
|
||||
def attribute_count(self): ...
|
||||
def attribute_by_index(self, index: int) -> attribute: ...
|
||||
def attribute_count(self) -> int: ...
|
||||
def attribute_index(self, *args): ...
|
||||
def attributes(self): ...
|
||||
def derived(self): ...
|
||||
def derived(self) -> tuple[bool, ...]:
|
||||
"""Return a tuple of booleans indicating whether each direct attribute is derived."""
|
||||
...
|
||||
|
||||
def is_abstract(self): ...
|
||||
def set_attributes(self, attributes, derived): ...
|
||||
def set_inverse_attributes(self, inverse_attributes): ...
|
||||
@@ -662,6 +758,8 @@ class entity(declaration):
|
||||
def supertype(self): ...
|
||||
|
||||
class entity_instance:
|
||||
file_: Any
|
||||
id_: Any
|
||||
def data(self, *args): ...
|
||||
def declaration(self): ...
|
||||
def file_pointer(self): ...
|
||||
@@ -701,9 +799,9 @@ class enumeration_type(declaration):
|
||||
def lookup_enum_offset(self, string): ...
|
||||
def lookup_enum_value(self, i): ...
|
||||
|
||||
class equal_functor: ...
|
||||
|
||||
class extrusion(sweep):
|
||||
depth: Any
|
||||
direction: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -711,6 +809,7 @@ class extrusion(sweep):
|
||||
def matrix(self): ...
|
||||
|
||||
class face:
|
||||
basis: Any
|
||||
def calc_hash(self): ...
|
||||
@property
|
||||
def children(self): ...
|
||||
@@ -724,6 +823,8 @@ class file:
|
||||
INSTANCE_ID: Any
|
||||
INSTANCE_TYPE: Any
|
||||
ATTRIBUTE_INDEX: Any
|
||||
guid_map_: Any
|
||||
stream: Any
|
||||
def FreshId(self): ...
|
||||
def add(self, entity, id): ...
|
||||
def addEntities(self, entities): ...
|
||||
@@ -764,7 +865,13 @@ class file:
|
||||
@staticmethod
|
||||
def traverse_breadth_first(instance, max_level): ...
|
||||
def try_read_semicolon(self): ...
|
||||
def types(self): ...
|
||||
def types(self) -> tuple[str, ...]:
|
||||
"""Return a tuple of classes present in the file.
|
||||
|
||||
E.g. `("IfcWallType", "IfcWall", "IfcArbitraryClosedProfileDef", ...)`.
|
||||
"""
|
||||
...
|
||||
|
||||
def types_begin(self): ...
|
||||
def types_end(self): ...
|
||||
def unbatch(self): ...
|
||||
@@ -779,6 +886,7 @@ class file_open_status:
|
||||
def value(self): ...
|
||||
|
||||
class fn_evaluator:
|
||||
settings_: Any
|
||||
def clone(self): ...
|
||||
def end(self): ...
|
||||
def evaluate(self, u): ...
|
||||
@@ -803,7 +911,9 @@ class functor_item(function_item):
|
||||
def kind(self): ...
|
||||
def start(self): ...
|
||||
|
||||
class geom_item(item): ...
|
||||
class geom_item(item):
|
||||
matrix: Any
|
||||
surface_style: Any
|
||||
|
||||
class geometry_exception:
|
||||
def what(self): ...
|
||||
@@ -817,7 +927,6 @@ class gradient_function(function_item):
|
||||
def kind(self): ...
|
||||
def start(self): ...
|
||||
|
||||
class hash_functor: ...
|
||||
class horizontal_plan_at_element: ...
|
||||
class implicit_item(geom_item): ...
|
||||
|
||||
@@ -834,6 +943,8 @@ class inverse_attribute:
|
||||
def type_of_aggregation_string(self): ...
|
||||
|
||||
class item:
|
||||
instance: Any
|
||||
orientation: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def hash(self): ...
|
||||
@@ -864,6 +975,7 @@ class line_segment:
|
||||
def swap(self, v): ...
|
||||
|
||||
class loft:
|
||||
axis: Any
|
||||
def calc_hash(self): ...
|
||||
@property
|
||||
def children(self): ...
|
||||
@@ -872,6 +984,9 @@ class loft:
|
||||
def print_impl(self, o, indent): ...
|
||||
|
||||
class loop:
|
||||
closed: Any
|
||||
external: Any
|
||||
fi: Any
|
||||
def calc_hash(self): ...
|
||||
def calculate_linear_edge_curves(self): ...
|
||||
@property
|
||||
@@ -887,6 +1002,7 @@ class matrix4(item):
|
||||
AFFINE_W_UNIFORM_SCALE: Any
|
||||
AFFINE_W_NONUNIFORM_SCALE: Any
|
||||
OTHER: Any
|
||||
tag: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
@property
|
||||
@@ -896,6 +1012,7 @@ class matrix4(item):
|
||||
def translation_part(self): ...
|
||||
|
||||
class named_type(parameter_type):
|
||||
def _is(self, *args): ...
|
||||
def as_named_type(self): ...
|
||||
def declared_type(self): ...
|
||||
|
||||
@@ -905,6 +1022,9 @@ class node(item):
|
||||
def kind(self): ...
|
||||
|
||||
class offset_curve(curve):
|
||||
basis: Any
|
||||
offset: Any
|
||||
reference: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -919,6 +1039,7 @@ class offset_function(function_item):
|
||||
def start(self): ...
|
||||
|
||||
class parameter_type:
|
||||
def _is(self, *args): ...
|
||||
def as_aggregation_type(self): ...
|
||||
def as_named_type(self): ...
|
||||
def as_simple_type(self): ...
|
||||
@@ -949,8 +1070,19 @@ class point3:
|
||||
def components(self): ...
|
||||
def kind(self): ...
|
||||
|
||||
class polygon_2: ...
|
||||
class ray_intersection_result: ...
|
||||
class polygon_2:
|
||||
boundary: Any
|
||||
inner_boundaries: Any
|
||||
point_inside: Any
|
||||
|
||||
class ray_intersection_result:
|
||||
distance: Any
|
||||
dot_product: Any
|
||||
instance: Any
|
||||
normal: Any
|
||||
position: Any
|
||||
ray_distance: Any
|
||||
style_index: Any
|
||||
|
||||
class ray_intersection_results:
|
||||
def append(self, x): ...
|
||||
@@ -977,6 +1109,9 @@ class ray_intersection_results:
|
||||
def swap(self, v): ...
|
||||
|
||||
class revolve(sweep):
|
||||
angle: Any
|
||||
axis_origin: Any
|
||||
direction: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -984,8 +1119,8 @@ class revolve(sweep):
|
||||
def matrix(self): ...
|
||||
|
||||
class schema_definition:
|
||||
def declaration_by_name(self, *args): ...
|
||||
def declarations(self): ...
|
||||
def declaration_by_name(self, *args: str) -> declaration: ...
|
||||
def declarations(self) -> tuple[declaration, ...]: ...
|
||||
def entities(self): ...
|
||||
def enumeration_types(self): ...
|
||||
def instantiate(self, decl, data): ...
|
||||
@@ -998,6 +1133,7 @@ class select_type(declaration):
|
||||
def select_list(self): ...
|
||||
|
||||
class shell:
|
||||
closed: Any
|
||||
def calc_hash(self): ...
|
||||
@property
|
||||
def children(self): ...
|
||||
@@ -1027,6 +1163,7 @@ class solid:
|
||||
def matrix(self): ...
|
||||
|
||||
class sphere(surface):
|
||||
radius: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -1034,6 +1171,13 @@ class sphere(surface):
|
||||
def matrix(self): ...
|
||||
|
||||
class style(item):
|
||||
diffuse: Any
|
||||
name: Any
|
||||
specular: Any
|
||||
specularity: Any
|
||||
surface: Any
|
||||
transparency: Any
|
||||
use_surface_color: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def get_color(self): ...
|
||||
@@ -1201,9 +1345,12 @@ class svg_polygons:
|
||||
def size(self): ...
|
||||
def swap(self, v): ...
|
||||
|
||||
class sweep(geom_item): ...
|
||||
class sweep(geom_item):
|
||||
basis: Any
|
||||
|
||||
class sweep_along_curve(sweep):
|
||||
curve: Any
|
||||
surface: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -1212,6 +1359,8 @@ class too_many_faces_exception(geometry_exception): ...
|
||||
class topology_error: ...
|
||||
|
||||
class torus(surface):
|
||||
radius1: Any
|
||||
radius2: Any
|
||||
def calc_hash(self): ...
|
||||
def clone_(self): ...
|
||||
def kind(self): ...
|
||||
@@ -1239,6 +1388,11 @@ class tree:
|
||||
def write_h5(self): ...
|
||||
|
||||
class trimmed_curve(geom_item):
|
||||
basis: Any
|
||||
curve_sense: Any
|
||||
start: Any
|
||||
end: Any
|
||||
|
||||
def reverse(self): ...
|
||||
|
||||
class type_by_kind:
|
||||
@@ -1249,12 +1403,7 @@ class type_declaration(declaration):
|
||||
def as_type_declaration(self): ...
|
||||
def declared_type(self): ...
|
||||
|
||||
def Triangulation_box_project_uvs(vertices, normals): ...
|
||||
def Triangulation_empty(settings): ...
|
||||
def XmlSerializerFactory_implementations(): ...
|
||||
def arrange_polygons(polygons): ...
|
||||
def boolean_result_operation_str(op): ...
|
||||
def circle_from_3_points(p1, p2, p3): ...
|
||||
def clear_schemas(): ...
|
||||
def construct_iterator_with_include_exclude(geometry_library, settings, file, elems, include, num_threads): ...
|
||||
def construct_iterator_with_include_exclude_globalid(geometry_library, settings, file, elems, include, num_threads): ...
|
||||
@@ -1262,10 +1411,6 @@ def construct_iterator_with_include_exclude_id(geometry_library, settings, file,
|
||||
def create_box(*args): ...
|
||||
def create_epeck(*args): ...
|
||||
def create_shape(*args): ...
|
||||
def file_createTimestamp(): ...
|
||||
def file_guid_map(*args): ...
|
||||
def file_traverse(instance, max_level): ...
|
||||
def file_traverse_breadth_first(instance, max_level): ...
|
||||
def flatten(deep): ...
|
||||
def get_feature(x): ...
|
||||
def get_info_cpp(v, include_identifier): ...
|
||||
@@ -1282,7 +1427,7 @@ def parse_ifcxml(filename): ...
|
||||
def polygons_to_svg(*args): ...
|
||||
def read(data): ...
|
||||
def register_schema(arg1): ...
|
||||
def schema_by_name(arg1): ...
|
||||
def schema_by_name(arg1: str) -> schema_definition: ...
|
||||
def schema_names(): ...
|
||||
def serialise(schema_name, shape_str, advanced): ...
|
||||
def set_feature(x, v): ...
|
||||
@@ -1292,8 +1437,6 @@ def svg_to_line_segments(data, class_name): ...
|
||||
def svg_to_polygons(data, class_name): ...
|
||||
def taxonomy_item_repr(i): ...
|
||||
def tesselate(schema_name, shape_str, d): ...
|
||||
def tree_is_manifold(fs): ...
|
||||
def tree_vector_to_list(ps): ...
|
||||
def turn_off_detailed_logging(): ...
|
||||
def turn_on_detailed_logging(): ...
|
||||
def version(): ...
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
import os
|
||||
import json
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.classification
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.system
|
||||
from typing import Union
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
import numpy as np
|
||||
import numpy.typing as npt
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.shape
|
||||
from typing import Optional, Union, TypedDict, Literal, Generator, Sequence
|
||||
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ def get_declaration(element: ifcopenshell.entity_instance):
|
||||
return element.wrapped_data.declaration().as_entity()
|
||||
|
||||
|
||||
def is_a(declaration: ifcopenshell.ifcopenshell_wrapper.entity, ifc_class: str) -> bool:
|
||||
def is_a(declaration: ifcopenshell.ifcopenshell_wrapper.declaration, ifc_class: str) -> bool:
|
||||
"""Checks if a schema declaration is a class
|
||||
|
||||
:param declaration: The declaration from the schema.
|
||||
|
||||
@@ -57,7 +57,7 @@ def get_function_node_name(node: ast.FunctionDef) -> Union[SubnameType, None]:
|
||||
:return: Function node name as ``SubnameType`` or ``None``, if function wasn't processed and can be skipped.
|
||||
"""
|
||||
node_name = node.name
|
||||
if node_name.startswith("_"):
|
||||
if node_name.startswith("_") and node_name not in ("_is",):
|
||||
return None
|
||||
args = [a.arg for a in node.args.args]
|
||||
if node.args.vararg:
|
||||
@@ -81,7 +81,7 @@ def get_names_tree_lines(tree: ast.Module) -> list[str]:
|
||||
if isinstance(node, ast.ClassDef):
|
||||
# Skip `object_` as it's just a reference to `object`,
|
||||
# which is implied by default.
|
||||
bases = [b.id for b in node.bases if isinstance(b, ast.Name) and b.id != "_object"]
|
||||
bases = [b.id for b in node.bases if isinstance(b, ast.Name) and b.id not in ("_object", "object")]
|
||||
bases_str = f"({', '.join(bases)})" if bases else ""
|
||||
node_name = f"class {node.name}{bases_str}:"
|
||||
|
||||
@@ -102,63 +102,73 @@ def get_names_tree_lines(tree: ast.Module) -> list[str]:
|
||||
continue
|
||||
subname_ = target.id
|
||||
|
||||
if subname_.startswith("_"):
|
||||
if subname_.startswith(("_", "thisown")):
|
||||
continue
|
||||
|
||||
value = subnode.value
|
||||
# Catching wrappers like:
|
||||
# - `matrix = property(matrix_getter)`
|
||||
# - `matrix = property(matrix_getter, matrix_setter)`
|
||||
# - `operation_str = staticmethod(operation_str)`
|
||||
if isinstance(value, ast.Call):
|
||||
if not isinstance(value, ast.Call):
|
||||
subname = subname_
|
||||
else:
|
||||
# Catching wrappers like:
|
||||
# - `matrix = property(matrix_getter)`
|
||||
# - `matrix = property(matrix_getter, matrix_setter)`
|
||||
# - `operation_str = staticmethod(operation_str)`
|
||||
func = value.func
|
||||
if not isinstance(func, ast.Name) or ((func_id := func.id) not in ("property", "staticmethod")):
|
||||
continue
|
||||
args = [arg.id for arg in value.args if isinstance(arg, ast.Name)]
|
||||
len_args = len(args)
|
||||
assert len_args in (1, 2)
|
||||
if len_args in (1, 2):
|
||||
|
||||
def find_method_by_name(name: str) -> Union[str, None]:
|
||||
function_def = f"def {name}("
|
||||
return next(
|
||||
(
|
||||
func_
|
||||
for func_ in subnames
|
||||
if isinstance(func_, str) and func_.startswith(function_def)
|
||||
),
|
||||
None,
|
||||
)
|
||||
def find_method_by_name(name: str) -> Union[str, None]:
|
||||
function_def = f"def {name}("
|
||||
return next(
|
||||
(
|
||||
func_
|
||||
for func_ in subnames
|
||||
if isinstance(func_, str) and func_.startswith(function_def)
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
# Use `set` for cases like `description = property(description, description)`.
|
||||
wrapped_function = None
|
||||
for arg in set(args):
|
||||
assert (wrapped_function := find_method_by_name(arg))
|
||||
subnames.remove(wrapped_function)
|
||||
# Use `set` for cases like `description = property(description, description)`.
|
||||
wrapped_function = None
|
||||
for arg in set(args):
|
||||
assert (wrapped_function := find_method_by_name(arg))
|
||||
subnames.remove(wrapped_function)
|
||||
|
||||
# TODO: sort it out in wrapper.py
|
||||
# There's one annoying case in Element.product
|
||||
# when property is overriding existing function, without using it.
|
||||
# We should probably just exclude that function from the wrapper.
|
||||
overridden_name = find_method_by_name(subname_)
|
||||
if overridden_name:
|
||||
subnames.remove(overridden_name)
|
||||
# TODO: sort it out in wrapper.py
|
||||
# There's one annoying case in Element.product
|
||||
# when property is overriding existing function, without using it.
|
||||
# We should probably just exclude that function from the wrapper.
|
||||
overridden_name = find_method_by_name(subname_)
|
||||
if overridden_name:
|
||||
subnames.remove(overridden_name)
|
||||
|
||||
if len_args == 2:
|
||||
# Has both getter and setter, can be defined as a simple attribute.
|
||||
subname = subname_
|
||||
elif len_args == 1:
|
||||
if func_id == "property":
|
||||
# Has just getter, read-only, need to define it using a wrapper.
|
||||
subname = (f"@{func_id}", f"def {subname_}(self): ...")
|
||||
elif func_id == "staticmethod":
|
||||
assert wrapped_function is not None
|
||||
subname = (f"@{func_id}", f"def {subname_}({wrapped_function.split('(')[1]}")
|
||||
if len_args == 2:
|
||||
# Has both getter and setter, can be defined as a simple attribute.
|
||||
subname = subname_
|
||||
elif len_args == 1:
|
||||
if func_id == "property":
|
||||
# Has just getter, read-only, need to define it using a wrapper.
|
||||
subname = (f"@{func_id}", f"def {subname_}(self): ...")
|
||||
elif func_id == "staticmethod":
|
||||
assert wrapped_function is not None
|
||||
subname = (f"@{func_id}", f"def {subname_}({wrapped_function.split('(')[1]}")
|
||||
else:
|
||||
assert_never(func_id)
|
||||
else:
|
||||
assert_never(func_id)
|
||||
assert_never(len_args)
|
||||
else:
|
||||
assert_never(len_args)
|
||||
else:
|
||||
subname = subname_
|
||||
attr_args = [
|
||||
arg
|
||||
for arg in value.args
|
||||
if isinstance(arg, ast.Attribute)
|
||||
and isinstance(arg.value, ast.Name)
|
||||
and arg.value.id == "_ifcopenshell_wrapper"
|
||||
]
|
||||
assert len(attr_args) == 2
|
||||
subname = subname_
|
||||
|
||||
if subname is not None:
|
||||
subnames.add(subname)
|
||||
@@ -171,6 +181,17 @@ def get_names_tree_lines(tree: ast.Module) -> list[str]:
|
||||
node_name = get_function_node_name(node)
|
||||
assert isinstance(node_name, str)
|
||||
|
||||
elif isinstance(node, ast.Assign):
|
||||
targets = node.targets
|
||||
if not len(targets) == 1 or not isinstance(target := targets[0], ast.Name):
|
||||
continue
|
||||
node_name = target.id
|
||||
|
||||
elif isinstance(node, ast.AnnAssign):
|
||||
target = node.target
|
||||
assert isinstance(target, ast.Name)
|
||||
node_name = target.id
|
||||
|
||||
if node_name is not None:
|
||||
names_tree[node_name] = subnames
|
||||
|
||||
@@ -215,6 +236,7 @@ def main() -> None:
|
||||
fromfile="stub.pyi classes",
|
||||
tofile="wrapper.py classes",
|
||||
lineterm="",
|
||||
n=10,
|
||||
)
|
||||
diff = list(diff)
|
||||
|
||||
|
||||
@@ -53,6 +53,11 @@ from collections import namedtuple
|
||||
from typing import Union, Iterator, Any, Optional
|
||||
from logging import Logger, Handler
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
from types import EllipsisType
|
||||
else:
|
||||
EllipsisType = type(...)
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.simple_spf
|
||||
import ifcopenshell.ifcopenshell_wrapper
|
||||
@@ -439,7 +444,7 @@ def validate(f: Union[ifcopenshell.file, str], logger: Logger, express_rules=Fal
|
||||
if hasattr(logger, "set_state"):
|
||||
logger.set_state("instance", inst)
|
||||
|
||||
guid: Union[str, None, types.EllipsisType]
|
||||
guid: Union[str, None, EllipsisType]
|
||||
if (guid := getattr(inst, "GlobalId", ...)) is not ...:
|
||||
if guid is not None and guid in used_guids:
|
||||
rule = "Rule IfcRoot.UR1:\n The attribute GlobalId should be unique"
|
||||
|
||||
@@ -25,7 +25,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = ["pytest"]
|
||||
advanced = [
|
||||
"networkx",
|
||||
]
|
||||
dev = [
|
||||
"pytest",
|
||||
"tabulate",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
"Homepage" = "http://ifcopenshell.org"
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_add_segment_to_curve():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_add_segment_to_layout():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_add_stationing_to_alignment():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_add_vertical_by_pi_method():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_add_stationing_to_alignment():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -25,7 +25,7 @@ import ifcopenshell.api.context
|
||||
|
||||
# class TestGetBasisCurve(test.bootstrap.IFC4X3):
|
||||
def test_horizontal():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
@@ -46,7 +46,7 @@ def test_horizontal():
|
||||
|
||||
|
||||
def test_horizontal_and_vertical():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -25,7 +25,7 @@ import ifcopenshell.api.context
|
||||
|
||||
# class TestGetCurve(test.bootstrap.IFC4X3):
|
||||
def test_horizontal():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
@@ -46,7 +46,7 @@ def test_horizontal():
|
||||
|
||||
|
||||
def test_horizontal_and_vertical():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -26,7 +26,7 @@ import ifcopenshell.api.nest
|
||||
|
||||
|
||||
def _test_business_definition():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
@@ -70,7 +70,7 @@ def _test_business_definition():
|
||||
|
||||
|
||||
def _test_geometric_definition():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -1606,7 +1606,7 @@ def _SineCurve_100_0__inf__300_1_Meter(file):
|
||||
|
||||
|
||||
def test_map_alignment_cant_segment():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
_BlossCurve_100_0_300_1000_1_Meter(file)
|
||||
_BlossCurve_100_0__300__1000_1_Meter(file)
|
||||
_BlossCurve_100_0_300_inf_1_Meter(file)
|
||||
|
||||
@@ -2032,7 +2032,7 @@ def _SineCurve_100_0__inf__300_1_Meter(file):
|
||||
|
||||
|
||||
def test_map_alignment_horizontal_segment():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
_BlossCurve_100_0_300_1000_1_Meter(file)
|
||||
_BlossCurve_100_0__300__1000_1_Meter(file)
|
||||
_BlossCurve_100_0_300_inf_1_Meter(file)
|
||||
|
||||
@@ -766,7 +766,7 @@ def _ParabolicArc_100_0_10_0__1_0__0_5_1_Meter(file):
|
||||
|
||||
|
||||
def test_map_alignment_vertical_segment():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
_CircularArc_100_0_10_0_0_0_0_5_1_Meter(file)
|
||||
_CircularArc_100_0_10_0_0_0__0_5_1_Meter(file)
|
||||
_CircularArc_100_0_10_0_0_5_0_0_1_Meter(file)
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_name_segments():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import ifcopenshell.api.context
|
||||
|
||||
|
||||
def _test1():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
@@ -84,7 +84,7 @@ def _test1():
|
||||
|
||||
|
||||
def _test2():
|
||||
file = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||
file = ifcopenshell.file(schema="IFC4X3")
|
||||
project = file.createIfcProject(Name="Test")
|
||||
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
|
||||
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.schema
|
||||
import ifcopenshell.util.shape_builder
|
||||
import ifcopenshell.util.unit
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import time
|
||||
import tempfile
|
||||
import typing
|
||||
import itertools
|
||||
import logging
|
||||
import numpy as np
|
||||
import multiprocessing
|
||||
import ifcopenshell
|
||||
@@ -62,8 +63,8 @@ DEFAULT_DATABASE_NAME = "database"
|
||||
class Patcher:
|
||||
def __init__(
|
||||
self,
|
||||
file,
|
||||
logger,
|
||||
file: ifcopenshell.file,
|
||||
logger: logging.Logger,
|
||||
sql_type: SQLTypes = "SQLite",
|
||||
host: str = "localhost",
|
||||
username: str = "root",
|
||||
@@ -93,6 +94,8 @@ class Patcher:
|
||||
entities will be separated into multiple rows. This means the ifc_id
|
||||
is no longer a unique primary key. If False, lists will be stored as
|
||||
JSON.
|
||||
:param should_get_inverses: if True, a list of entity inverses ids will be stored
|
||||
in a separate column as a json string.
|
||||
:param should_get_psets: if True, a separate psets table will be created to
|
||||
make it easy to query properties. This is in addition to regular IFC
|
||||
tables like IfcPropertySet.
|
||||
@@ -140,7 +143,7 @@ class Patcher:
|
||||
# Assume it's a filepath - existing or not.
|
||||
pass
|
||||
|
||||
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(self.file.schema_identifier)
|
||||
self.schema = ifcopenshell.schema_by_name(self.file.schema_identifier)
|
||||
|
||||
if self.sql_type == "sqlite":
|
||||
self.db = sqlite3.connect(database)
|
||||
@@ -278,6 +281,8 @@ class Patcher:
|
||||
PRIMARY KEY (`ifc_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
|
||||
"""
|
||||
else:
|
||||
assert False
|
||||
self.c.execute(statement)
|
||||
|
||||
def create_metadata(self) -> None:
|
||||
@@ -353,6 +358,7 @@ class Patcher:
|
||||
else:
|
||||
statement += "ifc_id INTEGER PRIMARY KEY NOT NULL UNIQUE"
|
||||
|
||||
assert isinstance(declaration, ifcopenshell.ifcopenshell_wrapper.entity)
|
||||
total_attributes = declaration.attribute_count()
|
||||
|
||||
if total_attributes:
|
||||
@@ -393,6 +399,7 @@ class Patcher:
|
||||
statement = f"CREATE TABLE IF NOT EXISTS {ifc_class} ("
|
||||
statement += "`ifc_id` int(10) unsigned NOT NULL,"
|
||||
|
||||
assert isinstance(declaration, ifcopenshell.ifcopenshell_wrapper.entity)
|
||||
derived = declaration.derived()
|
||||
for attribute in declaration.all_attributes():
|
||||
primitive = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
||||
@@ -434,13 +441,13 @@ class Patcher:
|
||||
def insert_data(self, ifc_class: str) -> None:
|
||||
elements = self.file.by_type(ifc_class, include_subtypes=False)
|
||||
|
||||
rows = []
|
||||
id_map_rows = []
|
||||
pset_rows = []
|
||||
rows: list[Any] = []
|
||||
id_map_rows: list[tuple[int, str]] = []
|
||||
pset_rows: list[tuple[int, str, str, Any]] = []
|
||||
|
||||
for element in elements:
|
||||
nested_indices = []
|
||||
values = [element.id()]
|
||||
nested_indices: list[int] = []
|
||||
values: list[Any] = [element.id()]
|
||||
for i, attribute in enumerate(element):
|
||||
if isinstance(attribute, ifcopenshell.entity_instance):
|
||||
if attribute.id():
|
||||
@@ -473,7 +480,7 @@ class Patcher:
|
||||
else:
|
||||
rows.append(values)
|
||||
|
||||
id_map_rows.append([element.id(), ifc_class])
|
||||
id_map_rows.append((element.id(), ifc_class))
|
||||
|
||||
if self.should_get_psets:
|
||||
psets = ifcopenshell.util.element.get_psets(element)
|
||||
@@ -483,7 +490,7 @@ class Patcher:
|
||||
continue
|
||||
if isinstance(value, list):
|
||||
value = json.dumps(value)
|
||||
pset_rows.append([element.id(), pset_name, prop_name, value])
|
||||
pset_rows.append((element.id(), pset_name, prop_name, value))
|
||||
|
||||
if self.should_get_geometry:
|
||||
if element.id() not in self.shape_rows and (placement := getattr(element, "ObjectPlacement", None)):
|
||||
@@ -512,6 +519,20 @@ class Patcher:
|
||||
)
|
||||
|
||||
def get_permutations(self, lst: list[Any], indexes: list[int]) -> list[Any]:
|
||||
"""
|
||||
Original row (`lst`):
|
||||
```
|
||||
ifc_id, x, (a, b), (c,d)
|
||||
```
|
||||
|
||||
Resulting permutations:
|
||||
```
|
||||
ifc_id, x, a, c
|
||||
ifc_id, x, a, d
|
||||
ifc_id, x, b, c
|
||||
ifc_id, x, b, d
|
||||
```
|
||||
"""
|
||||
nested_lists = [lst[i] for i in indexes]
|
||||
|
||||
# Generate the Cartesian product of the nested lists
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
class Patcher:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.georeference
|
||||
import ifcopenshell.util.geolocation
|
||||
from ifcpatch.recipes import OffsetObjectPlacements, SetWorldCoordinateSystem
|
||||
import typing
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@ import sys
|
||||
import math
|
||||
import datetime
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.unit
|
||||
from .ids import Specification, Ids
|
||||
from .facet import Facet, FacetFailure
|
||||
from typing import TypedDict, Union, Literal, Optional
|
||||
@@ -766,7 +767,6 @@ class Bcf(Json):
|
||||
|
||||
def to_file(self, filepath: str) -> None:
|
||||
import numpy as np
|
||||
import ifcopenshell.util.placement
|
||||
from bcf.v2.bcfxml import BcfXml
|
||||
|
||||
unit_scale = None
|
||||
|
||||
Reference in New Issue
Block a user