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,533 @@
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 Literal
8
+
9
+ from stbkit.core.stb_exceptions import (
10
+ ReferenceElementNotFoundError,
11
+ SchemaError,
12
+ )
13
+ from stbkit.core.stb_reporting import Code, Phase, Reporter
14
+
15
+ from stbkit.api.experimental.repository import RepositoryLatest
16
+ from stbkit.api.stb_latest import (
17
+ StbBeam,
18
+ StbBeamConcreteSwitch,
19
+ StbBeamSteelSwitch,
20
+ StbBrace,
21
+ StbColumn,
22
+ StbFoundationColumn,
23
+ StbGirder,
24
+ StbGirderConcreteSwitch,
25
+ StbGirderSteelSwitch,
26
+ StbParapet,
27
+ StbPile,
28
+ StbPost,
29
+ StbSecPileS,
30
+ StbStripFooting,
31
+ )
32
+
33
+ from ....._internal.data_model.element_data import (
34
+ ElementLine,
35
+ ElementLineSrc,
36
+ ElementType,
37
+ )
38
+ from ....._internal.data_model.shape_data import ShapePair, ShapePosition
39
+ from ....._internal.utils import girder_utils
40
+ from ....._internal.vectors import Vector3d
41
+ from ... import coord_converter, name_converter
42
+ from ..section import sec, sec_pile_s
43
+ from . import member_pile
44
+
45
+
46
+ def get_axis_position(
47
+ stb_element: StbColumn
48
+ | StbPost
49
+ | StbGirder
50
+ | StbBeam
51
+ | StbBrace
52
+ | StbStripFooting
53
+ | StbPile
54
+ | StbFoundationColumn
55
+ | StbParapet,
56
+ ) -> ShapePosition:
57
+ match stb_element:
58
+ case StbColumn() | StbPost() | StbBrace() | StbPile() | StbFoundationColumn():
59
+ return ShapePosition.CENTER_CENTER
60
+ case StbGirder() | StbBeam():
61
+ return ShapePosition.TOP_CENTER
62
+ case StbStripFooting() | StbParapet():
63
+ return ShapePosition.BOTTOM_CENTER
64
+ case _:
65
+ raise AssertionError(
66
+ type(stb_element).__name__ + "は想定外の部材タイプです"
67
+ )
68
+
69
+
70
+ def get_element_type(
71
+ stb_element: StbColumn
72
+ | StbPost
73
+ | StbGirder
74
+ | StbBeam
75
+ | StbBrace
76
+ | StbStripFooting
77
+ | StbPile
78
+ | StbFoundationColumn
79
+ | StbParapet,
80
+ ) -> ElementType:
81
+ match stb_element:
82
+ case StbColumn():
83
+ return ElementType.COLUMN
84
+ case StbPost():
85
+ return ElementType.POST
86
+ case StbGirder():
87
+ return ElementType.GIRDER
88
+ case StbBeam():
89
+ return ElementType.BEAM
90
+ case StbBrace():
91
+ return ElementType.BRACE
92
+ case StbStripFooting():
93
+ return ElementType.STRIP_FOOTING
94
+ case StbPile():
95
+ return ElementType.PILE
96
+ case StbFoundationColumn():
97
+ return ElementType.FOUNDATION_COLUMN
98
+ case StbParapet():
99
+ return ElementType.PARAPET
100
+ case _:
101
+ raise AssertionError("想定外の部材タイプです")
102
+
103
+
104
+ def get_node_ids(
105
+ stb_element: StbColumn
106
+ | StbPost
107
+ | StbGirder
108
+ | StbBeam
109
+ | StbBrace
110
+ | StbStripFooting
111
+ | StbPile
112
+ | StbFoundationColumn
113
+ | StbParapet,
114
+ ) -> list[int]:
115
+ match stb_element:
116
+ case StbColumn() | StbPost():
117
+ return [stb_element.id_node_bottom, stb_element.id_node_top]
118
+ case StbGirder() | StbBeam() | StbBrace() | StbStripFooting() | StbParapet():
119
+ return [stb_element.id_node_start, stb_element.id_node_end]
120
+ case StbPile() | StbFoundationColumn():
121
+ # 杭と基礎柱は1節点しか参照しないため1件リストにする
122
+ return [stb_element.id_node]
123
+ case _:
124
+ raise AssertionError("想定外の部材タイプです")
125
+
126
+
127
+ def get_points(
128
+ repo: RepositoryLatest,
129
+ stb_element: StbColumn
130
+ | StbPost
131
+ | StbGirder
132
+ | StbBeam
133
+ | StbBrace
134
+ | StbStripFooting
135
+ | StbPile
136
+ | StbFoundationColumn
137
+ | StbParapet,
138
+ node_coords: dict[int, Vector3d],
139
+ reporter: Reporter,
140
+ ) -> tuple[Vector3d, Vector3d]:
141
+ try:
142
+ match stb_element:
143
+ case StbColumn() | StbPost():
144
+ point_start: Vector3d = node_coords[stb_element.id_node_bottom]
145
+ point_end: Vector3d = node_coords[stb_element.id_node_top]
146
+ case (
147
+ StbGirder() | StbBeam() | StbBrace() | StbStripFooting() | StbParapet()
148
+ ):
149
+ point_start = node_coords[stb_element.id_node_start]
150
+ point_end = node_coords[stb_element.id_node_end]
151
+ case StbPile() as pile:
152
+ offset_pile: Vector3d = Vector3d(
153
+ pile.offset_x_or_none or 0.0,
154
+ pile.offset_y_or_none or 0.0,
155
+ pile.level_top_or_none or 0.0,
156
+ )
157
+ point_end = node_coords[pile.id_node] + offset_pile
158
+ length: float = pile.length_all_or_none or 0.0
159
+ if pile.kind_structure_or_none == "S":
160
+ stb_sec_pile_s: StbSecPileS = repo.get(StbSecPileS, pile.id_section)
161
+ _, lengths = sec_pile_s.stb_sec_pile_s_to_shapes_and_length(
162
+ stb_sec_pile_s
163
+ )
164
+ length = sum(lengths)
165
+ point_start = point_end - length * Vector3d.unit_z()
166
+ case StbFoundationColumn() as foundation_column:
167
+ point_base: Vector3d = node_coords[foundation_column.id_node]
168
+
169
+ point_fd_top: Vector3d = point_base
170
+ point_fd_bottom: Vector3d = (
171
+ point_fd_top
172
+ - (foundation_column.length_fd_or_none or 0.0) * Vector3d.unit_z()
173
+ )
174
+ point_start = point_fd_bottom
175
+ point_end = point_fd_top
176
+ case _:
177
+ raise AssertionError("想定外の部材タイプです")
178
+ except KeyError as e:
179
+ reporter.error(
180
+ message=f"節点が見つかりません: {e}",
181
+ code=Code.REFERENCE_NOT_FOUND,
182
+ phase=Phase.CONVERT_IFC,
183
+ stb_element=stb_element,
184
+ value=str(e),
185
+ )
186
+ return Vector3d.zero(), Vector3d.zero()
187
+
188
+ return point_start, point_end
189
+
190
+
191
+ def get_offset(
192
+ stb_element: StbColumn
193
+ | StbPost
194
+ | StbGirder
195
+ | StbBeam
196
+ | StbBrace
197
+ | StbStripFooting
198
+ | StbPile
199
+ | StbFoundationColumn
200
+ | StbParapet,
201
+ point_start: Vector3d,
202
+ point_end: Vector3d,
203
+ ) -> tuple[Vector3d, Vector3d]:
204
+ offset_start: Vector3d
205
+ offset_end: Vector3d
206
+ match stb_element:
207
+ case StbColumn() | StbPost():
208
+ offset_start = Vector3d(
209
+ stb_element.offset_bottom_x_or_none or 0.0,
210
+ stb_element.offset_bottom_y_or_none or 0.0,
211
+ stb_element.offset_bottom_z_or_none or 0.0,
212
+ )
213
+ offset_end = Vector3d(
214
+ stb_element.offset_top_x_or_none or 0.0,
215
+ stb_element.offset_top_y_or_none or 0.0,
216
+ stb_element.offset_top_z_or_none or 0.0,
217
+ )
218
+ case StbGirder() | StbBeam():
219
+ offset_start = girder_utils.girder_offset_start(stb_element)
220
+ offset_end = girder_utils.girder_offset_end(stb_element)
221
+ case StbBrace() as brace:
222
+ offset_start = Vector3d(
223
+ brace.aim_offset_start_x_or_none or 0.0,
224
+ brace.aim_offset_start_y_or_none or 0.0,
225
+ brace.aim_offset_start_z_or_none or 0.0,
226
+ )
227
+ offset_end = Vector3d(
228
+ brace.aim_offset_end_x_or_none or 0.0,
229
+ brace.aim_offset_end_y_or_none or 0.0,
230
+ brace.aim_offset_end_z_or_none or 0.0,
231
+ )
232
+ if brace.cutback_start_or_none or brace.cutback_end_or_none:
233
+ vx, vy, vz = coord_converter.axis_vector_beam(
234
+ point_start, point_end, 0.0
235
+ )
236
+ if brace.cutback_start_or_none:
237
+ offset_start += (brace.cutback_start_or_none or 0.0) * vx
238
+ if brace.cutback_end_or_none:
239
+ offset_end -= (brace.cutback_end_or_none or 0.0) * vx
240
+ case StbStripFooting() as stb_strip_footing:
241
+ vx, vy, vz = coord_converter.axis_vector_beam(point_start, point_end, 0.0)
242
+ strip_footing_base_offset: Vector3d = (
243
+ stb_strip_footing.offset_or_none or 0.0
244
+ ) * vy + (stb_strip_footing.level_or_none or 0.0) * vz
245
+ offset_start = (
246
+ -(stb_strip_footing.length_ex_start_or_none or 0.0) * vx
247
+ + strip_footing_base_offset
248
+ )
249
+ offset_end = (
250
+ stb_strip_footing.length_ex_end_or_none or 0.0
251
+ ) * vx + strip_footing_base_offset
252
+ case StbPile():
253
+ return Vector3d.zero(), Vector3d.zero()
254
+ case StbFoundationColumn() as foundation_column:
255
+ if (
256
+ foundation_column.id_section_fd_or_none is None
257
+ or foundation_column.length_fd_or_none is None
258
+ ):
259
+ if (
260
+ foundation_column.offset_wr_x_or_none
261
+ or foundation_column.offset_wr_y_or_none
262
+ ):
263
+ offset = Vector3d(
264
+ foundation_column.offset_wr_x_or_none or 0.0,
265
+ foundation_column.offset_wr_y_or_none or 0.0,
266
+ foundation_column.offset_z_or_none or 0.0,
267
+ )
268
+ offset_start = offset
269
+ offset_end = offset
270
+ else:
271
+ offset = Vector3d(
272
+ 0.0, 0.0, foundation_column.offset_z_or_none or 0.0
273
+ )
274
+ offset_start = offset
275
+ offset_end = offset
276
+ else:
277
+ offset = Vector3d(
278
+ foundation_column.offset_fd_x_or_none or 0.0,
279
+ foundation_column.offset_fd_y_or_none or 0.0,
280
+ foundation_column.offset_z_or_none or 0.0,
281
+ )
282
+ offset_start = offset
283
+ offset_end = offset
284
+ case StbParapet() as parapet:
285
+ vx, vy, vz = coord_converter.axis_vector_beam(point_start, point_end, 0.0)
286
+ offset_start = (parapet.offset_or_none or 0.0) * vy + (
287
+ parapet.level_or_none or 0.0
288
+ ) * vz
289
+ offset_end = offset_start
290
+ case _:
291
+ raise AssertionError("想定外の部材タイプです")
292
+ return offset_start, offset_end
293
+
294
+
295
+ def get_angle(
296
+ stb_element: StbColumn
297
+ | StbPost
298
+ | StbGirder
299
+ | StbBeam
300
+ | StbBrace
301
+ | StbStripFooting
302
+ | StbPile
303
+ | StbFoundationColumn
304
+ | StbParapet,
305
+ ) -> float:
306
+ match stb_element:
307
+ case (
308
+ StbColumn()
309
+ | StbPost()
310
+ | StbGirder()
311
+ | StbBeam()
312
+ | StbBrace()
313
+ | StbFoundationColumn()
314
+ ):
315
+ return stb_element.rotate_or_none or 0.0
316
+ case StbStripFooting() | StbPile() | StbParapet():
317
+ return 0.0
318
+ case _:
319
+ raise AssertionError("想定外の部材タイプです")
320
+
321
+
322
+ def get_lengths(
323
+ repo: RepositoryLatest,
324
+ stb_element: StbColumn
325
+ | StbPost
326
+ | StbGirder
327
+ | StbBeam
328
+ | StbBrace
329
+ | StbStripFooting
330
+ | StbPile
331
+ | StbFoundationColumn
332
+ | StbParapet,
333
+ length: float,
334
+ kind: Literal["S", "RC"],
335
+ ) -> list[float]:
336
+ lengths: list[float] = []
337
+ match stb_element:
338
+ case StbColumn() | StbPost():
339
+ if kind == "S":
340
+ if stb_element.steel_switch_height_bottom_or_none:
341
+ lengths.append(stb_element.steel_switch_height_bottom)
342
+ if stb_element.steel_switch_height_top_or_none:
343
+ lengths.append(stb_element.steel_switch_height_top)
344
+ lengths.insert(1, length - sum(lengths))
345
+ return lengths
346
+ case StbGirder() | StbBeam():
347
+ switch: (
348
+ list[StbGirderSteelSwitch]
349
+ | list[StbGirderConcreteSwitch]
350
+ | list[StbBeamSteelSwitch]
351
+ | list[StbBeamConcreteSwitch]
352
+ )
353
+ match stb_element, kind:
354
+ case StbGirder(), "S":
355
+ switch = stb_element.stb_girder_steel_switch
356
+ case StbGirder(), "RC":
357
+ switch = stb_element.stb_girder_concrete_switch
358
+ case StbBeam(), "S":
359
+ switch = stb_element.stb_beam_steel_switch
360
+ case StbBeam(), "RC":
361
+ switch = stb_element.stb_beam_concrete_switch
362
+ for i in range(len(switch)):
363
+ value = switch[i].distance
364
+ if i > 0:
365
+ value -= switch[i - 1].distance
366
+ lengths.append(value)
367
+ lengths.append(length - sum(lengths))
368
+ return lengths
369
+ case StbPile() as stb_pile:
370
+ if kind == "RC":
371
+ return member_pile.stb_pile_get_length_rc(repo, stb_pile)
372
+ elif kind == "S":
373
+ try:
374
+ stb_sec_pile_s: StbSecPileS = repo.get(
375
+ StbSecPileS, stb_pile.id_section
376
+ )
377
+ _, lengths = sec_pile_s.stb_sec_pile_s_to_shapes_and_length(
378
+ stb_sec_pile_s
379
+ )
380
+ return lengths
381
+ except ReferenceElementNotFoundError:
382
+ raise SchemaError(
383
+ f"部材 {stb_pile._name_for_log()} の断面が見つかりません。",
384
+ )
385
+ else:
386
+ raise AssertionError("想定外の部材タイプです")
387
+ case StbFoundationColumn() as foundation_column:
388
+ if foundation_column.length_fd_or_none is not None:
389
+ lengths.append(abs(foundation_column.length_fd))
390
+ if foundation_column.length_wr_or_none is not None:
391
+ lengths.append(abs(foundation_column.length_wr))
392
+ return lengths
393
+ case StbBrace() | StbStripFooting() | StbParapet():
394
+ lengths.append(length)
395
+ return lengths
396
+ case _:
397
+ raise AssertionError("想定外の部材タイプです")
398
+
399
+
400
+ def check_lengths(
401
+ length: float,
402
+ lengths: list[float],
403
+ shapes: list[ShapePair],
404
+ reporter: Reporter,
405
+ stb_element: StbColumn
406
+ | StbPost
407
+ | StbGirder
408
+ | StbBeam
409
+ | StbBrace
410
+ | StbStripFooting
411
+ | StbPile
412
+ | StbFoundationColumn
413
+ | StbParapet,
414
+ ) -> list[float]:
415
+ if len(shapes) != len(lengths):
416
+ reporter.warning(
417
+ message=f"{stb_element._name_for_log()} 断面切換位置の長さが"
418
+ "取得できなかったため、等間隔に分割します",
419
+ code=Code.MISSING_ATTRIBUTE,
420
+ phase=Phase.CONVERT_IFC,
421
+ stb_element=stb_element,
422
+ )
423
+ lengths = []
424
+ for i in range(len(shapes)):
425
+ lengths.append(length / len(shapes))
426
+ return lengths
427
+
428
+
429
+ def stb_element_to_element_line(
430
+ repo: RepositoryLatest,
431
+ stb_element: StbColumn
432
+ | StbPost
433
+ | StbGirder
434
+ | StbBeam
435
+ | StbBrace
436
+ | StbStripFooting
437
+ | StbPile
438
+ | StbFoundationColumn
439
+ | StbParapet,
440
+ node_coords: dict[int, Vector3d],
441
+ reporter: Reporter,
442
+ ) -> ElementLine | ElementLineSrc:
443
+ axis_position: ShapePosition = get_axis_position(stb_element)
444
+ element_type: ElementType = get_element_type(stb_element)
445
+ node_ids: list[int] = get_node_ids(stb_element)
446
+ point_start, point_end = get_points(
447
+ repo, stb_element, node_coords, reporter=reporter
448
+ )
449
+ offset_start, offset_end = get_offset(stb_element, point_start, point_end)
450
+ point_start += offset_start
451
+ point_end += offset_end
452
+ length: float = point_start.distance_to(point_end)
453
+ lengths: list[float] = [length]
454
+ angle: float = get_angle(stb_element)
455
+ name: str = name_converter.stb_element_to_ifc_name(stb_element)
456
+ shapes: list[ShapePair] | tuple[list[ShapePair], list[ShapePair]] | None = (
457
+ sec.get_shapes_element_line(repo, stb_element, reporter)
458
+ )
459
+ if isinstance(shapes, tuple):
460
+ shapes_rc, shapes_s = shapes
461
+ lengths_s: list[float] = [length]
462
+ lengths_rc: list[float] = [length]
463
+ if shapes_s and shapes_s[0].start and len(shapes_s) > 1:
464
+ lengths_s = get_lengths(repo, stb_element, length, kind="S")
465
+ lengths_s = check_lengths(length, lengths_s, shapes_s, reporter, stb_element)
466
+ if stb_element.kind_structure_or_none == "CFT":
467
+ lengths_rc = lengths_s
468
+ elif shapes_rc and shapes_rc[0].start and len(shapes_rc) > 1:
469
+ lengths_rc = get_lengths(repo, stb_element, length, kind="RC")
470
+ lengths_rc = check_lengths(length, lengths_rc, shapes_rc, reporter, stb_element)
471
+
472
+ element_line_s: ElementLine = ElementLine(
473
+ element_type=element_type,
474
+ lengths=lengths_s,
475
+ point_start=point_start,
476
+ point_end=point_end,
477
+ angle=angle,
478
+ shapes=shapes_s if shapes_s is not None else [],
479
+ axis_position=axis_position,
480
+ path=stb_element._path_xml(),
481
+ node_ids=node_ids,
482
+ )
483
+ element_line_rc: ElementLine = ElementLine(
484
+ element_type=element_type,
485
+ lengths=lengths_rc,
486
+ point_start=point_start,
487
+ point_end=point_end,
488
+ angle=angle,
489
+ shapes=shapes_rc if shapes_rc is not None else [],
490
+ axis_position=axis_position,
491
+ path=stb_element._path_xml(),
492
+ node_ids=node_ids,
493
+ )
494
+ element_line_src: ElementLineSrc = ElementLineSrc(
495
+ element_type=element_type,
496
+ guid=stb_element.guid_or_none,
497
+ name=name,
498
+ rc=element_line_rc,
499
+ steel=element_line_s,
500
+ path=stb_element._path_xml(),
501
+ node_ids=node_ids,
502
+ )
503
+ return element_line_src
504
+
505
+ if shapes and shapes[0].start:
506
+ kind_structure: str | None = stb_element.kind_structure_or_none
507
+ if kind_structure == "UNDEFINED":
508
+ lengths = [length]
509
+ elif kind_structure == "RC" or kind_structure == "S":
510
+ lengths = get_lengths(repo, stb_element, length, kind_structure) # type: ignore[arg-type]
511
+ else:
512
+ reporter.warning(
513
+ message=f"{kind_structure}は想定外の構造種別です。",
514
+ code=Code.SCHEMA_ERROR,
515
+ phase=Phase.CONVERT_IFC,
516
+ stb_element=stb_element,
517
+ )
518
+ lengths = [length]
519
+ lengths = check_lengths(length, lengths, shapes, reporter, stb_element)
520
+
521
+ element_line: ElementLine = ElementLine(
522
+ element_type=element_type,
523
+ guid=stb_element.guid_or_none,
524
+ lengths=lengths,
525
+ point_start=point_start,
526
+ point_end=point_end,
527
+ angle=angle,
528
+ shapes=shapes if shapes is not None else [],
529
+ axis_position=axis_position,
530
+ path=stb_element._path_xml(),
531
+ node_ids=node_ids,
532
+ )
533
+ return element_line
@@ -0,0 +1,100 @@
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
+ from stbkit.core.stb_exceptions import NoneAccessError
10
+
11
+ from stbkit.api.experimental.repository import RepositoryLatest
12
+ from stbkit.api.stb_latest import (
13
+ StbPile,
14
+ StbSecFigurePileRcConventional,
15
+ StbSecPileRc,
16
+ StbSecPileRcConventionalExtendedFoot,
17
+ StbSecPileRcConventionalExtendedTop,
18
+ StbSecPileRcConventionalExtendedTopFoot,
19
+ )
20
+
21
+ from ....._internal.utils.unit_utils import degree_to_radian
22
+
23
+
24
+ def stb_pile_get_length_rc(repo: RepositoryLatest, stb_pile: StbPile) -> list[float]:
25
+ length: float = stb_pile.length_all_or_none or 0.0
26
+ if length <= 0.0:
27
+ return [0.0]
28
+ src_rc: StbSecPileRc = repo.get(StbSecPileRc, stb_pile.id_section)
29
+ try:
30
+ conventional: StbSecFigurePileRcConventional | None = (
31
+ src_rc.stb_sec_pile_rc_conventional.stb_sec_figure_pile_rc_conventional
32
+ )
33
+ except NoneAccessError:
34
+ conventional = None
35
+ if conventional is not None:
36
+ if conventional.stb_sec_pile_rc_conventional_straight_or_none is not None:
37
+ return [length]
38
+ # ここから拡底、拡頭系の処理
39
+ result: list[float] = []
40
+ extend_foot: (
41
+ StbSecPileRcConventionalExtendedFoot
42
+ | StbSecPileRcConventionalExtendedTopFoot
43
+ | None
44
+ ) = (
45
+ conventional.stb_sec_pile_rc_conventional_extended_foot_or_none
46
+ or conventional.stb_sec_pile_rc_conventional_extended_top_foot_or_none
47
+ )
48
+ if extend_foot is not None:
49
+ length_extend_foot: float = extend_foot.length_extended_foot_or_none or 0.0
50
+ if length_extend_foot > 0.0:
51
+ result.append(length_extend_foot)
52
+ angle_extend_foot_taper_degree: float = (
53
+ extend_foot.angle_extended_foot_taper_or_none or 0.0
54
+ )
55
+ if 0.0 < angle_extend_foot_taper_degree < 90.0:
56
+ angle_extend_foot_taper_radian = degree_to_radian(
57
+ angle_extend_foot_taper_degree
58
+ )
59
+ length_taper = (
60
+ (
61
+ (extend_foot.d_extended_foot_or_none or 0.0)
62
+ - (extend_foot.d_axial_or_none or 0.0)
63
+ )
64
+ / 2.0
65
+ / math.tan(angle_extend_foot_taper_radian)
66
+ )
67
+ result.append(length_taper)
68
+ center_idnex: int = len(result)
69
+ result.append(0.0) # 中間部
70
+ extend_top: (
71
+ StbSecPileRcConventionalExtendedTop
72
+ | StbSecPileRcConventionalExtendedTopFoot
73
+ | None
74
+ ) = (
75
+ conventional.stb_sec_pile_rc_conventional_extended_top_or_none
76
+ or conventional.stb_sec_pile_rc_conventional_extended_top_foot_or_none
77
+ )
78
+ if extend_top is not None:
79
+ angle_extend_top_taper_degree: float = (
80
+ extend_top.angle_extended_top_taper_or_none or 0.0
81
+ )
82
+
83
+ if 0.0 < angle_extend_top_taper_degree < 90.0:
84
+ angle_extend_top_taper_radian = degree_to_radian(
85
+ angle_extend_top_taper_degree
86
+ )
87
+ length_taper = (
88
+ (
89
+ (extend_top.d_extended_top_or_none or 0.0)
90
+ - (extend_top.d_axial_or_none or 0.0)
91
+ )
92
+ / 2.0
93
+ / math.tan(angle_extend_top_taper_radian)
94
+ )
95
+ result.append(length_taper)
96
+ result.append(stb_pile.length_head_or_none or 0.0)
97
+ result[center_idnex] = length - sum(result)
98
+ return result
99
+ # 拡底、拡頭系の処理ここまで
100
+ return [length]