stbkit 0.1.0a9.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. stbkit/__main__.py +10 -0
  2. stbkit/api/__init__.py +48 -0
  3. stbkit/api/experimental/__init__.py +19 -0
  4. stbkit/api/experimental/repository/__init__.py +30 -0
  5. stbkit/api/py.typed +0 -0
  6. stbkit/api/stb_latest.py +7 -0
  7. stbkit/api/stb_v2_0_2.py +11 -0
  8. stbkit/api/stb_v2_1_1.py +9 -0
  9. stbkit/cli/__init__.py +17 -0
  10. stbkit/cli/_internal/cli_main.py +114 -0
  11. stbkit/cli/_internal/common.py +126 -0
  12. stbkit/cli/_internal/constants_exit_code.py +59 -0
  13. stbkit/cli/_internal/converter.py +693 -0
  14. stbkit/cli/_internal/diff.py +213 -0
  15. stbkit/cli/_internal/entry_points.py +25 -0
  16. stbkit/cli/_internal/global_parent.py +70 -0
  17. stbkit/cli/_internal/show_versions.py +36 -0
  18. stbkit/cli/_internal/validate.py +310 -0
  19. stbkit/cli/commands/convert.py +16 -0
  20. stbkit/cli/commands/diff.py +16 -0
  21. stbkit/cli/commands/validate.py +16 -0
  22. stbkit/cli/py.typed +0 -0
  23. stbkit/tools/__init__.py +12 -0
  24. stbkit/tools/_internal/__init__.py +5 -0
  25. stbkit/tools/_internal/constants.py +21 -0
  26. stbkit/tools/_internal/data_model/building_geometry.py +1208 -0
  27. stbkit/tools/_internal/data_model/building_geometry_web.py +106 -0
  28. stbkit/tools/_internal/data_model/element_data.py +93 -0
  29. stbkit/tools/_internal/data_model/ifc_data/entity_data.py +67 -0
  30. stbkit/tools/_internal/data_model/ifc_data/entity_names.py +32 -0
  31. stbkit/tools/_internal/data_model/shape_data.py +1089 -0
  32. stbkit/tools/_internal/diff/__init__.py +5 -0
  33. stbkit/tools/_internal/diff/common.py +50 -0
  34. stbkit/tools/_internal/diff/diff_xml.py +796 -0
  35. stbkit/tools/_internal/matrix.py +51 -0
  36. stbkit/tools/_internal/optional_dependencies/__init__.py +5 -0
  37. stbkit/tools/_internal/optional_dependencies/ifc_common.py +28 -0
  38. stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_entity_exporter.py +473 -0
  39. stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_profile_exporter.py +267 -0
  40. stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_representation_exporter.py +178 -0
  41. stbkit/tools/_internal/optional_dependencies/ifc_pipeline.py +133 -0
  42. stbkit/tools/_internal/optional_dependencies/ifc_to_building_geometry.py +64 -0
  43. stbkit/tools/_internal/stb_io.py +116 -0
  44. stbkit/tools/_internal/stb_repair/_common.py +24 -0
  45. stbkit/tools/_internal/stb_repair/_stb_repair.py +197 -0
  46. stbkit/tools/_internal/stb_repair/_stb_v2_0_2_repair.py +53 -0
  47. stbkit/tools/_internal/stb_repair/_stb_v2_1_0_repair.py +109 -0
  48. stbkit/tools/_internal/stb_repair/_stb_v2_1_1_repair.py +109 -0
  49. stbkit/tools/_internal/studio_report.py +49 -0
  50. stbkit/tools/_internal/utils/atomic_writer.py +57 -0
  51. stbkit/tools/_internal/utils/float_rounding.py +49 -0
  52. stbkit/tools/_internal/utils/girder_utils.py +91 -0
  53. stbkit/tools/_internal/utils/guid_utils.py +30 -0
  54. stbkit/tools/_internal/utils/mesh_utils.py +1305 -0
  55. stbkit/tools/_internal/utils/node_utils.py +50 -0
  56. stbkit/tools/_internal/utils/unit_utils.py +23 -0
  57. stbkit/tools/_internal/vectors.py +222 -0
  58. stbkit/tools/converters/__init__.py +39 -0
  59. stbkit/tools/converters/_internal/__init__.py +5 -0
  60. stbkit/tools/converters/_internal/building_geometry_to_ply_text.py +32 -0
  61. stbkit/tools/converters/_internal/coord_converter.py +151 -0
  62. stbkit/tools/converters/_internal/element_data_to_building_geometry.py +549 -0
  63. stbkit/tools/converters/_internal/ifc_to_ply_text.py +21 -0
  64. stbkit/tools/converters/_internal/name_converter.py +23 -0
  65. stbkit/tools/converters/_internal/pipeline/__init__.py +5 -0
  66. stbkit/tools/converters/_internal/pipeline/data.py +188 -0
  67. stbkit/tools/converters/_internal/pipeline/execution.py +569 -0
  68. stbkit/tools/converters/_internal/pipeline/ply_pipeline.py +52 -0
  69. stbkit/tools/converters/_internal/pipeline/stb_pipeline.py +226 -0
  70. stbkit/tools/converters/_internal/pipeline/stb_pipeline_latest.py +39 -0
  71. stbkit/tools/converters/_internal/pipeline/step.py +139 -0
  72. stbkit/tools/converters/_internal/stb_latest_to_element_data/__init__.py +17 -0
  73. stbkit/tools/converters/_internal/stb_latest_to_element_data/_stb_latest_to_element_data.py +186 -0
  74. stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_footing.py +49 -0
  75. stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_line.py +533 -0
  76. stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_pile.py +100 -0
  77. stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_plane.py +103 -0
  78. stbkit/tools/converters/_internal/stb_latest_to_element_data/open.py +70 -0
  79. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec.py +214 -0
  80. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_rc.py +67 -0
  81. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_s.py +97 -0
  82. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_src.py +28 -0
  83. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_brace_s.py +49 -0
  84. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_cft.py +217 -0
  85. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_rc.py +41 -0
  86. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_s.py +127 -0
  87. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_src.py +173 -0
  88. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_foundation.py +225 -0
  89. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_parapet_rc.py +53 -0
  90. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_pile_rc.py +106 -0
  91. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_pile_s.py +100 -0
  92. stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_steel.py +432 -0
  93. stbkit/tools/converters/_internal/stb_to_building_geometry.py +44 -0
  94. stbkit/tools/converters/_internal/stb_to_ifc_data/__init__.py +5 -0
  95. stbkit/tools/converters/_internal/stb_to_ifc_data/_stb_to_ifc_data.py +59 -0
  96. stbkit/tools/converters/_internal/stb_to_ifc_data/convert_option.py +22 -0
  97. stbkit/tools/converters/_internal/stb_to_ply_text.py +22 -0
  98. stbkit/tools/py.typed +0 -0
  99. stbkit/tools/upgrade/__init__.py +13 -0
  100. stbkit/tools/upgrade/_internal/__init__.py +5 -0
  101. stbkit/tools/upgrade/_internal/common.py +205 -0
  102. stbkit/tools/upgrade/_internal/upgrade.py +228 -0
  103. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/__init__.py +60 -0
  104. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_common.py +62 -0
  105. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_joint_beam_shape_h.py +44 -0
  106. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_pile_rc.py +101 -0
  107. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_pile_s.py +78 -0
  108. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_slab_deck.py +56 -0
  109. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_slab_rc.py +128 -0
  110. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_girder.py +126 -0
  111. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_open.py +110 -0
  112. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_sec_beam_rc.py +227 -0
  113. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_sec_beam_s.py +1153 -0
  114. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hooks.py +22 -0
  115. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/post.py +42 -0
  116. stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/tables.py +99 -0
  117. stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/__init__.py +58 -0
  118. stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/hooks.py +32 -0
  119. stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/tables.py +56 -0
  120. stbkit-0.1.0a9.dev1.dist-info/METADATA +196 -0
  121. stbkit-0.1.0a9.dev1.dist-info/RECORD +125 -0
  122. stbkit-0.1.0a9.dev1.dist-info/WHEEL +5 -0
  123. stbkit-0.1.0a9.dev1.dist-info/entry_points.txt +2 -0
  124. stbkit-0.1.0a9.dev1.dist-info/licenses/LICENSE +373 -0
  125. stbkit-0.1.0a9.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,50 @@
1
+ # Copyright 2025-2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ from typing import Protocol
8
+
9
+ from stbkit.core.data_model import (
10
+ stb_v2_0_0,
11
+ stb_v2_0_1,
12
+ stb_v2_0_2,
13
+ stb_v2_1_0,
14
+ stb_v2_1_1,
15
+ )
16
+ from stbkit.core.data_model.common import StBridgeRoot
17
+ from stbkit.core.stb_exceptions import (
18
+ ReferenceElementNotFoundError,
19
+ UnsupportedStbVersionError,
20
+ )
21
+
22
+ from ..vectors import Vector3d
23
+
24
+
25
+ class HasXyz(Protocol):
26
+ @property
27
+ def x(self) -> float: ...
28
+ @property
29
+ def y(self) -> float: ...
30
+ @property
31
+ def z(self) -> float: ...
32
+
33
+
34
+ def get_node_coordinate(stb: StBridgeRoot, id: int) -> Vector3d:
35
+ if not isinstance(
36
+ stb,
37
+ (
38
+ stb_v2_0_0.StBridge,
39
+ stb_v2_0_1.StBridge,
40
+ stb_v2_0_2.StBridge,
41
+ stb_v2_1_0.StBridge,
42
+ stb_v2_1_1.StBridge,
43
+ ),
44
+ ):
45
+ raise UnsupportedStbVersionError(stb.version)
46
+
47
+ for node in stb.stb_model.stb_nodes.stb_node:
48
+ if node.id == id:
49
+ return Vector3d.from_stb_node(node)
50
+ raise ReferenceElementNotFoundError(f"StbNode id={id}が見つかりません")
@@ -0,0 +1,23 @@
1
+ # Copyright 2025-2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ import math
8
+
9
+
10
+ def mm_to_m(value: float) -> float:
11
+ return value / 1000.0
12
+
13
+
14
+ def m_to_mm(value: float) -> float:
15
+ return value * 1000.0
16
+
17
+
18
+ def radian_to_degree(value: float) -> float:
19
+ return math.degrees(value)
20
+
21
+
22
+ def degree_to_radian(value: float) -> float:
23
+ return math.radians(value)
@@ -0,0 +1,222 @@
1
+ # Copyright 2025-2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ from __future__ import annotations
8
+
9
+ import math
10
+ from collections.abc import Iterator, Sequence
11
+ from dataclasses import dataclass
12
+ from math import sqrt
13
+ from typing import TYPE_CHECKING, overload
14
+
15
+ from stbkit.core.stb_exceptions import SchemaError
16
+
17
+ from .utils.unit_utils import degree_to_radian, mm_to_m
18
+
19
+ if TYPE_CHECKING:
20
+ from .utils.node_utils import HasXyz
21
+
22
+
23
+ @dataclass(frozen=True, slots=True)
24
+ class Vector2d(Sequence[float]):
25
+ x: float = 0.0
26
+ y: float = 0.0
27
+
28
+ def mm_to_m(self) -> Vector2d:
29
+ return Vector2d(mm_to_m(self.x), mm_to_m(self.y))
30
+
31
+ def to_vector3d(self, z: float = 0.0) -> Vector3d:
32
+ return Vector3d(self.x, self.y, z)
33
+
34
+ @overload
35
+ def __getitem__(self, index: int) -> float: ...
36
+
37
+ @overload
38
+ def __getitem__(self, index: slice) -> Sequence[float]: ...
39
+
40
+ def __getitem__(self, index: int | slice) -> float | Sequence[float]:
41
+ if isinstance(index, int):
42
+ if index == 0:
43
+ return self.x
44
+ elif index == 1:
45
+ return self.y
46
+ else:
47
+ raise IndexError("インデックスは0から1の範囲で指定してください")
48
+ elif isinstance(index, slice):
49
+ # スライスの場合はリストで返す
50
+ return [self.x, self.y][index]
51
+ else:
52
+ raise TypeError("インデックスは整数またはスライスで指定してください")
53
+
54
+ def __len__(self) -> int:
55
+ return 2
56
+
57
+ def __add__(self, other: Vector2d) -> Vector2d:
58
+ return Vector2d(self.x + other.x, self.y + other.y)
59
+
60
+ def __sub__(self, other: Vector2d) -> Vector2d:
61
+ return Vector2d(self.x - other.x, self.y - other.y)
62
+
63
+ def __neg__(self) -> Vector2d:
64
+ return Vector2d(-self.x, -self.y)
65
+
66
+ def __iter__(self) -> Iterator[float]:
67
+ yield self.x
68
+ yield self.y
69
+
70
+ def clone(self) -> Vector2d:
71
+ return Vector2d(self.x, self.y)
72
+
73
+ def distance_to(self, other: Vector2d) -> float:
74
+ return math.hypot(other.y - self.y, other.x - self.x)
75
+
76
+ def rotate(self, angle_degree: float) -> Vector2d:
77
+ if angle_degree == 0.0:
78
+ return self.clone()
79
+ theta: float = degree_to_radian(angle_degree)
80
+ cos_theta: float = math.cos(theta)
81
+ sin_theta: float = math.sin(theta)
82
+ x_new: float = cos_theta * self.x - sin_theta * self.y
83
+ y_new: float = sin_theta * self.x + cos_theta * self.y
84
+ return Vector2d(x_new, y_new)
85
+
86
+ @staticmethod
87
+ def zero() -> Vector2d:
88
+ return Vector2d(0.0, 0.0)
89
+
90
+
91
+ @dataclass(frozen=True, slots=True)
92
+ class Vector3d(Sequence[float]):
93
+ x: float = 0.0
94
+ y: float = 0.0
95
+ z: float = 0.0
96
+
97
+ def __add__(self, other: Vector3d) -> Vector3d:
98
+ return Vector3d(self.x + other.x, self.y + other.y, self.z + other.z)
99
+
100
+ @overload
101
+ def __getitem__(self, index: int) -> float: ...
102
+
103
+ @overload
104
+ def __getitem__(self, index: slice) -> Sequence[float]: ...
105
+
106
+ def __getitem__(self, index: int | slice) -> float | Sequence[float]:
107
+ if isinstance(index, int):
108
+ if index == 0:
109
+ return self.x
110
+ elif index == 1:
111
+ return self.y
112
+ elif index == 2:
113
+ return self.z
114
+ else:
115
+ raise IndexError("インデックスは0から2の範囲で指定してください")
116
+ elif isinstance(index, slice):
117
+ # スライスの場合はリストで返す
118
+ return [self.x, self.y, self.z][index]
119
+ else:
120
+ raise TypeError("インデックスは整数またはスライスで指定してください")
121
+
122
+ def __len__(self) -> int:
123
+ return 3
124
+
125
+ def __rmul__(self, other: float) -> Vector3d:
126
+ return Vector3d(other * self.x, other * self.y, other * self.z)
127
+
128
+ def __sub__(self, other: Vector3d) -> Vector3d:
129
+ return Vector3d(self.x - other.x, self.y - other.y, self.z - other.z)
130
+
131
+ def __neg__(self) -> Vector3d:
132
+ return Vector3d(-self.x, -self.y, -self.z)
133
+
134
+ def clone(self) -> Vector3d:
135
+ return Vector3d(self.x, self.y, self.z)
136
+
137
+ def cross(self, other: Vector3d) -> Vector3d:
138
+ return Vector3d(
139
+ self.y * other.z - self.z * other.y,
140
+ self.z * other.x - self.x * other.z,
141
+ self.x * other.y - self.y * other.x,
142
+ )
143
+
144
+ def distance_to(self, other: Vector3d) -> float:
145
+ return sqrt(
146
+ (self.x - other.x) ** 2 + (self.y - other.y) ** 2 + (self.z - other.z) ** 2
147
+ )
148
+
149
+ def dot(self, other: Vector3d) -> float:
150
+ return self.x * other.x + self.y * other.y + self.z * other.z
151
+
152
+ def length(self) -> float:
153
+ return sqrt(self.x**2 + self.y**2 + self.z**2)
154
+
155
+ def mm_to_m(self) -> Vector3d:
156
+ return mm_to_m(1.0) * self
157
+
158
+ def normalize(self) -> Vector3d:
159
+ length = self.length()
160
+ if length == 0:
161
+ raise ValueError("零ベクトルは正規化できません")
162
+ return Vector3d(self.x / length, self.y / length, self.z / length)
163
+
164
+ def perpendicular_vector_on_plane(self, def_plane_vec: Vector3d) -> Vector3d:
165
+ # vec1 を正規化
166
+ vec1_normalized: Vector3d = self.normalize()
167
+
168
+ # vec2 の vec1 への射影を計算
169
+ projection_length: float = def_plane_vec.dot(vec1_normalized)
170
+ projection_vector: Vector3d = projection_length * vec1_normalized
171
+
172
+ # vec2 から射影ベクトルを引いて、vec1 に垂直なベクトルを得る
173
+ result: Vector3d = def_plane_vec - projection_vector
174
+ result = result.normalize()
175
+ return result
176
+
177
+ def rotate_around_axis(self, angle_degree: float, axis_vec: Vector3d) -> Vector3d:
178
+ if angle_degree == 0.0:
179
+ return self.clone()
180
+ theta = degree_to_radian(angle_degree)
181
+ a: Vector3d = axis_vec.normalize()
182
+ vec1: Vector3d = math.cos(theta) * self
183
+ vec2: Vector3d = (1.0 - math.cos(theta)) * (self.dot(a)) * a
184
+ vec3: Vector3d = math.sin(theta) * a.cross(self)
185
+ return vec1 + vec2 + vec3
186
+
187
+ def to_tuple(self) -> tuple[float, float, float]:
188
+ return (self.x, self.y, self.z)
189
+
190
+ @staticmethod
191
+ def from_collection(
192
+ collection: Sequence[float],
193
+ ) -> Vector3d:
194
+ if len(collection) != 3:
195
+ raise ValueError("3次元のコレクションとしてください")
196
+ return Vector3d(x=collection[0], y=collection[1], z=collection[2])
197
+
198
+ @staticmethod
199
+ def from_stb_node(
200
+ stb_node: HasXyz,
201
+ ) -> Vector3d:
202
+ if stb_node.x is None or stb_node.y is None or stb_node.z is None:
203
+ raise SchemaError(
204
+ f"{stb_node._name_for_logger()} x,y,zの値が設定されていません"
205
+ )
206
+ return Vector3d(stb_node.x, stb_node.y, stb_node.z)
207
+
208
+ @staticmethod
209
+ def unit_x() -> Vector3d:
210
+ return Vector3d(1.0, 0.0, 0.0)
211
+
212
+ @staticmethod
213
+ def unit_y() -> Vector3d:
214
+ return Vector3d(0.0, 1.0, 0.0)
215
+
216
+ @staticmethod
217
+ def unit_z() -> Vector3d:
218
+ return Vector3d(0.0, 0.0, 1.0)
219
+
220
+ @staticmethod
221
+ def zero() -> Vector3d:
222
+ return Vector3d(0.0, 0.0, 0.0)
@@ -0,0 +1,39 @@
1
+ # Copyright 2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ from logging import Logger
8
+ from typing import TYPE_CHECKING
9
+
10
+ from stbkit.core.data_model.common import StBridgeRoot
11
+ from stbkit.core.stb_reporting import Reporter, get_reporter
12
+
13
+ if TYPE_CHECKING:
14
+ import ifcopenshell.file
15
+
16
+
17
+ def to_ifc(
18
+ stb: StBridgeRoot, *, logger: Logger | None = None, reporter: Reporter | None = None
19
+ ) -> "ifcopenshell.file":
20
+ """ST-BridgeをIFCへ変換します。
21
+
22
+ この関数を利用するためにはifcopenshellが必要です。
23
+
24
+ Args:
25
+ stb: ST-Bridgeモデル
26
+ logger: 出力用のLogger。
27
+ reporter: 出力用のReporter。
28
+
29
+ Returns:
30
+ ifcopenshell.file: 生成されたIFCモデル
31
+ """
32
+ from .._internal.data_model.ifc_data.entity_data import IfcModel
33
+ from ..upgrade import upgrade_to_latest
34
+ from ._internal.stb_to_ifc_data._stb_to_ifc_data import stb_to_ifc_data
35
+
36
+ reporter = get_reporter(logger, reporter)
37
+ stb = upgrade_to_latest(stb, reporter=reporter)
38
+ ifc_model: IfcModel = stb_to_ifc_data(stb, reporter=reporter)
39
+ return ifc_model.to_ifc(reporter=reporter)
@@ -0,0 +1,5 @@
1
+ # Copyright 2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
@@ -0,0 +1,32 @@
1
+ # Copyright 2025-2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ from ..._internal.data_model.building_geometry import BuildingGeometry
8
+
9
+
10
+ def building_geometry_to_ply_text(geom: BuildingGeometry) -> str:
11
+ result: list[str] = []
12
+ result.append("ply")
13
+ result.append("format ascii 1.0")
14
+ result.append(f"element vertex {geom.mesh.vertex_count}")
15
+ result.append("property float x")
16
+ result.append("property float y")
17
+ result.append("property float z")
18
+ result.append(f"element face {geom.mesh.face_count}")
19
+ result.append("property list uchar int vertex_index")
20
+ result.append("end_header")
21
+ positions = geom.mesh.positions
22
+ for i in range(geom.mesh.vertex_count):
23
+ result.append(
24
+ f"{round(positions[i * 3], 5)} {round(positions[i * 3 + 1], 5)} {round(positions[i * 3 + 2], 5)}"
25
+ )
26
+
27
+ face_offsets = geom.mesh.face_offsets
28
+ for i in range(geom.mesh.face_count):
29
+ face = geom.mesh.face_vertex_indices[face_offsets[i] : face_offsets[i + 1]]
30
+ result.append(f"{len(face)} {' '.join(map(str, face))}")
31
+
32
+ return "\n".join(result)
@@ -0,0 +1,151 @@
1
+ # Copyright 2025-2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ from stbkit.core.stb_exceptions import (
8
+ ZeroLengthMemberError,
9
+ )
10
+
11
+ from ..._internal.data_model.element_data import ElementType
12
+ from ..._internal.matrix import RotationMatrix
13
+ from ..._internal.vectors import Vector3d
14
+
15
+
16
+ def rotation_matrix(
17
+ point: Vector3d, vx: Vector3d, vy: Vector3d, vz: Vector3d
18
+ ) -> RotationMatrix:
19
+ return RotationMatrix(point, vx, vy, vz)
20
+
21
+
22
+ def rotation_matrix_by_element_type(
23
+ point_start: Vector3d, point_end: Vector3d, angle: float, element_type: ElementType
24
+ ) -> RotationMatrix:
25
+ match element_type:
26
+ case (
27
+ ElementType.GIRDER
28
+ | ElementType.BEAM
29
+ | ElementType.BRACE
30
+ | ElementType.STRIP_FOOTING
31
+ | ElementType.PARAPET
32
+ ):
33
+ return rotation_matrix_beam(point_start, point_end, angle)
34
+ case (
35
+ ElementType.COLUMN
36
+ | ElementType.POST
37
+ | ElementType.FOOTING
38
+ | ElementType.PILE
39
+ | ElementType.FOUNDATION_COLUMN
40
+ ):
41
+ return rotation_matrix_column(point_start, point_end, angle)
42
+ case _:
43
+ raise NotImplementedError(f"要素タイプ{element_type}の回転行列は未実装です")
44
+
45
+
46
+ def axis_vector_by_element_type(
47
+ point_start: Vector3d, point_end: Vector3d, angle: float, element_type: ElementType
48
+ ) -> tuple[Vector3d, Vector3d, Vector3d]:
49
+ match element_type:
50
+ case (
51
+ ElementType.GIRDER
52
+ | ElementType.BEAM
53
+ | ElementType.BRACE
54
+ | ElementType.STRIP_FOOTING
55
+ | ElementType.PARAPET
56
+ ):
57
+ return axis_vector_beam(point_start, point_end, angle)
58
+ case (
59
+ ElementType.COLUMN
60
+ | ElementType.POST
61
+ | ElementType.FOOTING
62
+ | ElementType.PILE
63
+ | ElementType.FOUNDATION_COLUMN
64
+ ):
65
+ return axis_vector_column(point_start, point_end, angle)
66
+ case _:
67
+ raise NotImplementedError(
68
+ f"要素タイプ{element_type}の軸ベクトルは未実装です"
69
+ )
70
+
71
+
72
+ def axis_vector_beam(
73
+ point_start: Vector3d, point_end: Vector3d, angle: float
74
+ ) -> tuple[Vector3d, Vector3d, Vector3d]:
75
+ vx: Vector3d = (point_end - point_start).normalize()
76
+ pv: Vector3d = vx.perpendicular_vector_on_plane(Vector3d.unit_z())
77
+ vz: Vector3d = pv.rotate_around_axis(angle, vx).normalize()
78
+ vy: Vector3d = vz.cross(vx)
79
+ return (vx, vy, vz)
80
+
81
+
82
+ def rotation_matrix_beam(
83
+ point_start: Vector3d,
84
+ point_end: Vector3d,
85
+ angle: float,
86
+ ) -> RotationMatrix:
87
+ (vx, vy, vz) = axis_vector_beam(point_start, point_end, angle)
88
+ return rotation_matrix(point_start, vy, vz, vx)
89
+
90
+
91
+ def axis_vector_column(
92
+ point_start: Vector3d, point_end: Vector3d, angle: float
93
+ ) -> tuple[Vector3d, Vector3d, Vector3d]:
94
+ vx: Vector3d = point_end - point_start
95
+ if vx.length() == 0:
96
+ raise ZeroLengthMemberError("柱の始点と終点が同じ位置です")
97
+ vx = vx.normalize()
98
+ pv: Vector3d = vx.perpendicular_vector_on_plane(Vector3d.unit_x())
99
+ vy: Vector3d = pv.rotate_around_axis(angle, vx).normalize()
100
+ vz: Vector3d = vx.cross(vy)
101
+ return (vx, vy, vz)
102
+
103
+
104
+ def rotation_matrix_column(
105
+ point_start: Vector3d,
106
+ point_end: Vector3d,
107
+ angle: float,
108
+ ) -> RotationMatrix:
109
+ (vx, vy, vz) = axis_vector_column(point_start, point_end, angle)
110
+ return rotation_matrix(point_start, vy, vz, vx)
111
+
112
+
113
+ def axis_vector_plate(
114
+ points: list[Vector3d],
115
+ ) -> tuple[Vector3d, Vector3d, Vector3d]:
116
+ if len(points) < 3:
117
+ raise AssertionError("pointsの数が3以下です")
118
+ vx: Vector3d = (points[1] - points[0]).normalize()
119
+ vy: Vector3d = vx.perpendicular_vector_on_plane(points[-1] - points[0]).normalize()
120
+ vz = vx.cross(vy)
121
+ return (vx, vy, vz)
122
+
123
+
124
+ def rotation_matrix_plate(points: list[Vector3d]) -> RotationMatrix:
125
+ vx, vy, vz = axis_vector_plate(points)
126
+ return rotation_matrix(points[0], vx, vy, vz)
127
+
128
+
129
+ def to_plate_element_coord(points: list[Vector3d]) -> list[Vector3d]:
130
+ matrix = rotation_matrix_plate(points)
131
+ return [matrix.to_local_point(point) for point in points]
132
+
133
+
134
+ def to_global_coord_plate(
135
+ points: list[Vector3d], out_points: list[Vector3d]
136
+ ) -> list[Vector3d]:
137
+ matrix = rotation_matrix_plate(out_points)
138
+ return [matrix.to_global_point(point) for point in points]
139
+
140
+
141
+ def to_global_coord(
142
+ points: list[Vector3d],
143
+ point_start: Vector3d,
144
+ point_end: Vector3d,
145
+ angle: float,
146
+ element_type: ElementType,
147
+ ) -> list[Vector3d]:
148
+ matrix = rotation_matrix_by_element_type(
149
+ point_start, point_end, angle, element_type
150
+ )
151
+ return [matrix.to_global_point(point) for point in points]