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,226 @@
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 dataclasses import dataclass, field
8
+ from pathlib import Path
9
+ from typing import Literal, cast
10
+
11
+ from stbkit.core import stb_io
12
+ from stbkit.core._internal.constants import (
13
+ DEFAULT_MAX_XML_SIZE,
14
+ LATEST_STB_VERSION,
15
+ )
16
+ from stbkit.core.data_model.common import StBridgeRoot
17
+ from stbkit.core.stb_exceptions import UnsupportedStbVersionError
18
+ from stbkit.core.stb_reporting import NullReporter
19
+ from stbkit.core.stb_typing import StbVersion
20
+
21
+ from ...._internal.stb_repair._stb_repair import repair_stb
22
+ from ....upgrade._internal.upgrade import upgrade_to
23
+ from .data import (
24
+ _DataFormat,
25
+ _FileData,
26
+ _FileFormat,
27
+ _ObjectData,
28
+ _StbVersion,
29
+ _TextData,
30
+ )
31
+ from .step import _ExecutableStep, _ExecutionContext, _ExecutionResult
32
+
33
+
34
+ def _get_pipeline_stb_version(stb: StBridgeRoot) -> _StbVersion:
35
+ try:
36
+ return _StbVersion(stb.version)
37
+ except ValueError:
38
+ return _StbVersion.UNSPECIFIED
39
+
40
+
41
+ def _get_load_stb_version(version: _StbVersion) -> StbVersion | None:
42
+ if version == _StbVersion.UNSPECIFIED:
43
+ return None
44
+ if version == _StbVersion.LATEST:
45
+ return LATEST_STB_VERSION
46
+ return cast(StbVersion, version.value)
47
+
48
+
49
+ class StbFileData(_FileData):
50
+ def __init__(
51
+ self,
52
+ path: Path,
53
+ *,
54
+ stb_version: _StbVersion = _StbVersion.UNSPECIFIED,
55
+ encoding: str | None = None,
56
+ ) -> None:
57
+ super().__init__(
58
+ format=_DataFormat.STB,
59
+ path=path,
60
+ file_format=_FileFormat.XML,
61
+ stb_version=stb_version,
62
+ encoding=encoding,
63
+ )
64
+
65
+
66
+ class StbTextData(_TextData):
67
+ def __init__(
68
+ self,
69
+ text: str,
70
+ *,
71
+ stb_version: _StbVersion = _StbVersion.UNSPECIFIED,
72
+ has_xml_declaration: bool = True,
73
+ ) -> None:
74
+ self.has_xml_declaration: bool = has_xml_declaration
75
+ super().__init__(
76
+ format=_DataFormat.STB,
77
+ text=text,
78
+ file_format=_FileFormat.XML,
79
+ stb_version=stb_version,
80
+ )
81
+
82
+
83
+ class StbData[TStb: StBridgeRoot](_ObjectData[TStb]):
84
+ def __init__(self, value: TStb, stb_version: _StbVersion) -> None:
85
+ super().__init__(format=_DataFormat.STB, value=value, stb_version=stb_version)
86
+
87
+
88
+ class StbUnspecifiedData(StbData[StBridgeRoot]):
89
+ def __init__(self, value: StBridgeRoot) -> None:
90
+ super().__init__(value=value, stb_version=_StbVersion.UNSPECIFIED)
91
+
92
+
93
+ class StbLoadStep(_ExecutableStep[StbFileData | StbTextData, StbData[StBridgeRoot]]):
94
+ name = "STB Load"
95
+
96
+ def execute(
97
+ self,
98
+ data: StbFileData | StbTextData,
99
+ *,
100
+ context: _ExecutionContext,
101
+ ) -> _ExecutionResult[StbData[StBridgeRoot]]:
102
+ stb: StBridgeRoot
103
+ version = _get_load_stb_version(data.stb_version or _StbVersion.UNSPECIFIED)
104
+ max_size: int = (
105
+ context.max_size if context.max_size is not None else DEFAULT_MAX_XML_SIZE
106
+ )
107
+ if isinstance(data, StbTextData):
108
+ stb = stb_io.loads(
109
+ data.text,
110
+ version=version,
111
+ max_size=max_size,
112
+ reporter=context.reporter,
113
+ )
114
+ else:
115
+ stb = stb_io.load(
116
+ data.path,
117
+ version=version,
118
+ encoding=data.encoding,
119
+ max_size=max_size,
120
+ reporter=context.reporter,
121
+ )
122
+ return _ExecutionResult(output=StbData(stb, _get_pipeline_stb_version(stb)))
123
+
124
+
125
+ class StbDumpsStep[TStb: StBridgeRoot](_ExecutableStep[StbData[TStb], StbTextData]):
126
+ name = "STB Dump"
127
+
128
+ def execute(
129
+ self,
130
+ data: StbData[TStb],
131
+ *,
132
+ context: _ExecutionContext,
133
+ ) -> _ExecutionResult[StbTextData]:
134
+ text = stb_io.dumps(data.value, reporter=context.reporter)
135
+ return _ExecutionResult(
136
+ output=StbTextData(
137
+ text,
138
+ stb_version=data.stb_version or _StbVersion.UNSPECIFIED,
139
+ )
140
+ )
141
+
142
+
143
+ @dataclass(frozen=True)
144
+ class StbToVersionStep(_ExecutableStep[StbData[StBridgeRoot], StbData[StBridgeRoot]]):
145
+ """ST-Bridgeを指定されたバージョンへ更新するステップ。"""
146
+
147
+ target_version: _StbVersion
148
+ name: str = field(init=False)
149
+
150
+ def __post_init__(self) -> None:
151
+ object.__setattr__(self, "name", f"STB -> {self.target_version.value}")
152
+
153
+ def execute(
154
+ self,
155
+ data: StbData[StBridgeRoot],
156
+ *,
157
+ context: _ExecutionContext,
158
+ ) -> _ExecutionResult[StbData[StBridgeRoot]]:
159
+ if self.target_version in (
160
+ _StbVersion.LATEST,
161
+ _StbVersion.UNSPECIFIED,
162
+ ):
163
+ raise ValueError(
164
+ "StbToVersionStepには具体的なST-Bridgeバージョンを指定してください"
165
+ )
166
+
167
+ actual_version = _get_pipeline_stb_version(data.value)
168
+ if actual_version == self.target_version:
169
+ return _ExecutionResult(output=StbData(data.value, self.target_version))
170
+
171
+ target_version: Literal["2.0.1", "2.0.2", "2.1.0", "2.1.1"]
172
+ match self.target_version:
173
+ case _StbVersion.V2_0_1:
174
+ target_version = "2.0.1"
175
+ case _StbVersion.V2_0_2:
176
+ target_version = "2.0.2"
177
+ case _StbVersion.V2_1_0:
178
+ target_version = "2.1.0"
179
+ case _StbVersion.V2_1_1:
180
+ target_version = "2.1.1"
181
+ case _StbVersion.V2_0_0:
182
+ raise UnsupportedStbVersionError("2.0.0への変換")
183
+ case _:
184
+ raise ValueError(
185
+ "StbToVersionStepには具体的なST-Bridgeバージョンを指定してください"
186
+ )
187
+
188
+ converted: StBridgeRoot = upgrade_to(
189
+ data.value,
190
+ to_version=target_version,
191
+ reporter=context.reporter,
192
+ )
193
+
194
+ return _ExecutionResult(output=StbData(converted, self.target_version))
195
+
196
+
197
+ class StbAssignGuidsStep[TStb: StBridgeRoot](
198
+ _ExecutableStep[StbData[TStb], StbData[TStb]]
199
+ ):
200
+ """ST-Bridge内のguid未設定要素へguidを割り当てるステップ"""
201
+
202
+ name = "STB Assign GUIDs"
203
+
204
+ def execute(
205
+ self,
206
+ data: StbData[TStb],
207
+ *,
208
+ context: _ExecutionContext,
209
+ ) -> _ExecutionResult[StbData[TStb]]:
210
+ from stbkit.core._internal.transform.guid_tools import assign_guid_all
211
+
212
+ assign_guid_all(data.value)
213
+ return _ExecutionResult(output=data)
214
+
215
+
216
+ class StbRepairStep[TStb: StBridgeRoot](_ExecutableStep[StbData[TStb], StbData[TStb]]):
217
+ name = "STB Repair"
218
+
219
+ def execute(
220
+ self,
221
+ data: StbData[TStb],
222
+ *,
223
+ context: _ExecutionContext,
224
+ ) -> _ExecutionResult[StbData[TStb]]:
225
+ repair_stb(data.value, reporter=context.reporter or NullReporter())
226
+ return _ExecutionResult(output=data)
@@ -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 stbkit.core.data_model.common import StBridgeRoot
8
+
9
+ from stbkit.api import stb_latest
10
+
11
+ from ....upgrade._internal.upgrade import upgrade_to_latest
12
+ from .data import _StbVersion
13
+ from .stb_pipeline import StbData
14
+ from .step import _ExecutableStep, _ExecutionContext, _ExecutionResult
15
+
16
+
17
+ class StbLatestData(StbData[stb_latest.StBridge]):
18
+ def __init__(self, value: stb_latest.StBridge) -> None:
19
+ super().__init__(value=value, stb_version=_StbVersion.LATEST)
20
+
21
+
22
+ class StbToLatestStep[TStb: StBridgeRoot](
23
+ _ExecutableStep[StbData[TStb], StbLatestData]
24
+ ):
25
+ name = "STB -> STB Latest"
26
+
27
+ def execute(
28
+ self,
29
+ data: StbData[TStb],
30
+ *,
31
+ context: _ExecutionContext,
32
+ ) -> _ExecutionResult[StbLatestData]:
33
+ stb: StBridgeRoot = data.value
34
+ if isinstance(stb, stb_latest.StBridge):
35
+ return _ExecutionResult(output=StbLatestData(stb))
36
+ if isinstance(stb, StBridgeRoot):
37
+ stb_latest_value = upgrade_to_latest(stb, reporter=context.reporter)
38
+ return _ExecutionResult(output=StbLatestData(stb_latest_value))
39
+ raise TypeError(f"ST-Bridgeデータではありません: {type(stb)}")
@@ -0,0 +1,139 @@
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 collections.abc import Callable, Sequence
8
+ from dataclasses import dataclass, field
9
+ from pathlib import Path
10
+ from typing import Any, Protocol, cast
11
+
12
+ from stbkit.core.stb_reporting import NullReporter, Reporter
13
+
14
+ from .data import _Data
15
+
16
+
17
+ @dataclass
18
+ class _ExecutionContext:
19
+ work_dir: Path | None = None
20
+ keep_temporary_files: bool = False
21
+ reporter: Reporter = field(default_factory=NullReporter)
22
+ max_size: int | None = None
23
+ """max_sizeは読み込む ST-Bridgeのサイズ上限(バイト)。
24
+ Noneの場合は読み込み側の既定値を使用する。"""
25
+ on_step_completed: Callable[[str, _Data], None] | None = None
26
+ """複合ステップ内を含む各単一ステップの完了時に呼び出される。
27
+ CLIの中間ファイル保存など、変換処理そのものとは独立した処理の実装のために使用する。"""
28
+ ifc_round_digits: int | None = None
29
+ ifc_round_digits_mm: int | None = None
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class _ExecutionResult[OutData: _Data]:
34
+ output: OutData
35
+ cleanup_paths: tuple[Path, ...] = ()
36
+ """結果を利用し終わった後に削除してよい一時パス。
37
+ 複合ステップでは直ちに削除せず、最上位の呼び出し側へ集約して返す。"""
38
+
39
+
40
+ class _ExecutableStep[InData: _Data, OutData: _Data](Protocol):
41
+ name: str
42
+
43
+ def execute(
44
+ self,
45
+ data: InData,
46
+ *,
47
+ context: _ExecutionContext,
48
+ ) -> _ExecutionResult[OutData]: ...
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ class _FunctionExecutableStep[InData: _Data, OutData: _Data]:
53
+ name: str
54
+ func: Callable[[InData, _ExecutionContext], _ExecutionResult[OutData]]
55
+
56
+ def execute(
57
+ self,
58
+ data: InData,
59
+ *,
60
+ context: _ExecutionContext,
61
+ ) -> _ExecutionResult[OutData]:
62
+ return self.func(data, context)
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class _CompositeExecutableStep[InData: _Data, OutData: _Data](
67
+ _ExecutableStep[InData, OutData]
68
+ ):
69
+ name: str
70
+ runners: Sequence[_ExecutableStep[Any, Any]]
71
+
72
+ def execute(
73
+ self,
74
+ data: InData,
75
+ *,
76
+ context: _ExecutionContext,
77
+ ) -> _ExecutionResult[OutData]:
78
+ tmp_data: _Data = data
79
+ cleanup_paths: list[Path] = []
80
+ for runner in self.runners:
81
+ result = _execute_step(runner, tmp_data, context=context)
82
+ tmp_data = result.output
83
+ cleanup_paths.extend(result.cleanup_paths)
84
+ return _ExecutionResult(
85
+ output=cast(OutData, tmp_data),
86
+ cleanup_paths=tuple(cleanup_paths),
87
+ )
88
+
89
+
90
+ class _NoOpStep[InData: _Data](_ExecutableStep[InData, InData]):
91
+ name = "No-Op"
92
+
93
+ def execute(
94
+ self,
95
+ data: InData,
96
+ *,
97
+ context: _ExecutionContext,
98
+ ) -> _ExecutionResult[InData]:
99
+ return _ExecutionResult(output=data)
100
+
101
+
102
+ def _execute_step[InData: _Data, OutData: _Data](
103
+ step: _ExecutableStep[InData, OutData],
104
+ data: InData,
105
+ *,
106
+ context: _ExecutionContext,
107
+ ) -> _ExecutionResult[OutData]:
108
+ """ステップを実行し、単一ステップであれば完了通知も行う"""
109
+ result = step.execute(data, context=context)
110
+ if context.on_step_completed is not None and not isinstance(
111
+ step, _CompositeExecutableStep
112
+ ):
113
+ context.on_step_completed(step.name, result.output)
114
+ return result
115
+
116
+
117
+ def _compose_steps(
118
+ name: str,
119
+ steps: Sequence[_ExecutableStep[Any, Any]],
120
+ ) -> _ExecutableStep[Any, Any]:
121
+ """
122
+ ステップを平坦化し、不要なNo-Opを除いて最小の実行単位を返す。
123
+
124
+ 変換ルートを組み立てる側が複合ステップの入れ子や、単一ステップだけの複合オブジェクトを意識せずに済むようにする。
125
+ """
126
+ flattened: list[_ExecutableStep[Any, Any]] = []
127
+ for step in steps:
128
+ if isinstance(step, _CompositeExecutableStep):
129
+ flattened.extend(step.runners)
130
+ elif isinstance(step, _NoOpStep):
131
+ continue
132
+ else:
133
+ flattened.append(step)
134
+
135
+ if not flattened:
136
+ return _NoOpStep()
137
+ if len(flattened) == 1:
138
+ return flattened[0]
139
+ return _CompositeExecutableStep(name=name, runners=tuple(flattened))
@@ -0,0 +1,17 @@
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 ._stb_latest_to_element_data import (
8
+ node_coords_from_stb_nodes,
9
+ node_infos_from_stb_nodes,
10
+ stb_to_element_data,
11
+ )
12
+
13
+ __all__ = [
14
+ "node_coords_from_stb_nodes",
15
+ "node_infos_from_stb_nodes",
16
+ "stb_to_element_data",
17
+ ]
@@ -0,0 +1,186 @@
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.repository import get_repository
8
+ from stbkit.core.stb_exceptions import NoneAccessError
9
+ from stbkit.core.stb_reporting import Code, Phase, Reporter
10
+
11
+ from stbkit.api.experimental.repository import RepositoryLatest
12
+ from stbkit.api.stb_latest import (
13
+ StbBeam,
14
+ StbBrace,
15
+ StbColumn,
16
+ StbFoundationColumn,
17
+ StbGirder,
18
+ StbMembers,
19
+ StbModel,
20
+ StbNodes,
21
+ StbParapet,
22
+ StbPile,
23
+ StbPost,
24
+ StBridge,
25
+ StbStripFooting,
26
+ )
27
+
28
+ from ...._internal.data_model.element_data import (
29
+ ElementData,
30
+ ElementPlane,
31
+ Node,
32
+ )
33
+ from ...._internal.vectors import Vector3d
34
+ from . import open
35
+ from .member.member_footing import stb_footing_to_line_element
36
+ from .member.member_line import stb_element_to_element_line
37
+ from .member.member_plane import (
38
+ stb_slab_to_ifc_data,
39
+ stb_wall_to_ifc_data,
40
+ )
41
+
42
+
43
+ def node_coords_from_stb_nodes(stb_nodes: StbNodes) -> dict[int, Vector3d]:
44
+ return {node.id: Vector3d.from_stb_node(node) for node in stb_nodes.stb_node}
45
+
46
+
47
+ def node_infos_from_stb_nodes(stb_nodes: StbNodes) -> dict[int, Node]:
48
+ return {
49
+ node.id: Node(
50
+ position=Vector3d.from_stb_node(node),
51
+ xpath=node._path_xml(),
52
+ guid=node.guid_or_none,
53
+ )
54
+ for node in stb_nodes.stb_node
55
+ }
56
+
57
+
58
+ def stb_to_element_data(
59
+ stb: StBridge,
60
+ *,
61
+ reporter: Reporter,
62
+ ) -> ElementData:
63
+ reporter.info(
64
+ "---ST-Bridge->ジオメトリデータ変換処理開始---",
65
+ code=Code.PROGRESS_INFO,
66
+ phase=Phase.CONVERT_GEOMETRY,
67
+ )
68
+ result: ElementData = ElementData()
69
+ repo: RepositoryLatest = get_repository(stb)
70
+ try:
71
+ stb_model: StbModel = stb.stb_model
72
+ stb_members: StbMembers = stb_model.stb_members
73
+ except NoneAccessError:
74
+ reporter.error(
75
+ "部材情報がありません",
76
+ code=Code.MEMBER_NOT_FOUND,
77
+ phase=Phase.CONVERT_GEOMETRY,
78
+ )
79
+ return result
80
+ try:
81
+ stb_nodes: StbNodes = stb.stb_model.stb_nodes
82
+ except NoneAccessError:
83
+ reporter.error(
84
+ "節点情報がありません",
85
+ code=Code.MEMBER_NOT_FOUND,
86
+ phase=Phase.CONVERT_GEOMETRY,
87
+ )
88
+ return result
89
+ node_coords: dict[int, Vector3d] = node_coords_from_stb_nodes(stb_nodes)
90
+ try:
91
+ _ = stb.stb_model.stb_sections
92
+ except NoneAccessError:
93
+ reporter.error(
94
+ "断面情報がありません",
95
+ code=Code.MEMBER_NOT_FOUND,
96
+ phase=Phase.CONVERT_GEOMETRY,
97
+ )
98
+ return result
99
+ stb_member_lines: list[
100
+ StbColumn
101
+ | StbPost
102
+ | StbGirder
103
+ | StbBeam
104
+ | StbBrace
105
+ | StbPile
106
+ | StbStripFooting
107
+ | StbFoundationColumn
108
+ | StbParapet
109
+ ] = []
110
+ try:
111
+ stb_member_lines.extend(stb_members.stb_columns.stb_column)
112
+ except NoneAccessError:
113
+ pass
114
+ try:
115
+ stb_member_lines.extend(stb_members.stb_posts.stb_post)
116
+ except NoneAccessError:
117
+ pass
118
+ try:
119
+ stb_member_lines.extend(stb_members.stb_girders.stb_girder)
120
+ except NoneAccessError:
121
+ pass
122
+ try:
123
+ stb_member_lines.extend(stb_members.stb_beams.stb_beam)
124
+ except NoneAccessError:
125
+ pass
126
+ try:
127
+ stb_member_lines.extend(stb_members.stb_braces.stb_brace)
128
+ except NoneAccessError:
129
+ pass
130
+ try:
131
+ stb_member_lines.extend(stb_members.stb_strip_footings.stb_strip_footing)
132
+ except NoneAccessError:
133
+ pass
134
+ try:
135
+ stb_member_lines.extend(stb_members.stb_piles.stb_pile)
136
+ except NoneAccessError:
137
+ pass
138
+ try:
139
+ stb_member_lines.extend(
140
+ stb_members.stb_foundation_columns.stb_foundation_column
141
+ )
142
+ except NoneAccessError:
143
+ pass
144
+ try:
145
+ stb_member_lines.extend(stb_members.stb_parapets.stb_parapet)
146
+ except NoneAccessError:
147
+ pass
148
+
149
+ result.extend(
150
+ [
151
+ stb_element_to_element_line(repo, ele, node_coords, reporter)
152
+ for ele in stb_member_lines
153
+ ]
154
+ )
155
+ stb_id_to_planes: dict[int, ElementPlane] = {}
156
+ if stb_members.stb_slabs_or_none:
157
+ for stb_slab in stb_members.stb_slabs.stb_slab:
158
+ result.append(
159
+ stb_slab_to_ifc_data(
160
+ stb_slab,
161
+ node_coords,
162
+ repo,
163
+ stb_id_to_planes,
164
+ reporter,
165
+ )
166
+ )
167
+ if stb_members.stb_walls_or_none:
168
+ for stb_wall in stb_members.stb_walls.stb_wall:
169
+ result.append(
170
+ stb_wall_to_ifc_data(
171
+ stb_wall,
172
+ node_coords,
173
+ repo,
174
+ stb_id_to_planes,
175
+ reporter,
176
+ )
177
+ )
178
+ if stb_members.stb_open_arrangements_or_none:
179
+ open.add_open(stb_model, stb_id_to_planes, reporter=reporter)
180
+
181
+ if stb_members.stb_footings_or_none and stb_members.stb_footings.stb_footing:
182
+ for stb_footing in stb_members.stb_footings.stb_footing:
183
+ result.append(
184
+ stb_footing_to_line_element(repo, stb_footing, node_coords, reporter)
185
+ )
186
+ return result
@@ -0,0 +1,49 @@
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_reporting import Reporter
8
+
9
+ from stbkit.api.experimental.repository import RepositoryLatest
10
+ from stbkit.api.stb_latest import StbFooting, StbSecFoundationRc
11
+
12
+ from ....._internal.data_model.element_data import ElementLine, ElementType
13
+ from ....._internal.data_model.shape_data import ShapePosition
14
+ from ....._internal.vectors import Vector3d
15
+ from ..section.sec_foundation import stb_sec_foundation_rc_to_shapes_and_depth
16
+
17
+
18
+ def stb_footing_to_line_element(
19
+ repo: RepositoryLatest,
20
+ stb_footing: StbFooting,
21
+ node_coords: dict[int, Vector3d],
22
+ reporter: Reporter,
23
+ ) -> ElementLine:
24
+ point: Vector3d = node_coords[stb_footing.id_node]
25
+ offset: Vector3d = Vector3d(
26
+ stb_footing.offset_x if stb_footing.offset_x_or_none else 0.0,
27
+ stb_footing.offset_y if stb_footing.offset_y_or_none else 0.0,
28
+ stb_footing.level_bottom if stb_footing.level_bottom_or_none else 0.0,
29
+ )
30
+ angle: float = stb_footing.rotate if stb_footing.rotate_or_none else 0.0
31
+ point_bottom: Vector3d = point + offset
32
+ stb_sec_foundation_rc: StbSecFoundationRc = repo.deref(stb_footing).id_section
33
+ shapes, lengths = stb_sec_foundation_rc_to_shapes_and_depth(
34
+ stb_sec_foundation_rc, reporter
35
+ )
36
+ point_top: Vector3d = point_bottom + sum(lengths) * Vector3d.unit_z()
37
+ return ElementLine(
38
+ element_type=ElementType.FOOTING,
39
+ name=stb_footing.name_or_none,
40
+ guid=stb_footing.guid_or_none,
41
+ lengths=lengths,
42
+ point_start=point_bottom,
43
+ point_end=point_top,
44
+ angle=angle,
45
+ shapes=shapes,
46
+ axis_position=ShapePosition.DIAGRAM_CORE,
47
+ path=stb_footing._path_xml(),
48
+ node_ids=[stb_footing.id_node],
49
+ )