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.
- stbkit/__main__.py +10 -0
- stbkit/api/__init__.py +48 -0
- stbkit/api/experimental/__init__.py +19 -0
- stbkit/api/experimental/repository/__init__.py +30 -0
- stbkit/api/py.typed +0 -0
- stbkit/api/stb_latest.py +7 -0
- stbkit/api/stb_v2_0_2.py +11 -0
- stbkit/api/stb_v2_1_1.py +9 -0
- stbkit/cli/__init__.py +17 -0
- stbkit/cli/_internal/cli_main.py +114 -0
- stbkit/cli/_internal/common.py +126 -0
- stbkit/cli/_internal/constants_exit_code.py +59 -0
- stbkit/cli/_internal/converter.py +693 -0
- stbkit/cli/_internal/diff.py +213 -0
- stbkit/cli/_internal/entry_points.py +25 -0
- stbkit/cli/_internal/global_parent.py +70 -0
- stbkit/cli/_internal/show_versions.py +36 -0
- stbkit/cli/_internal/validate.py +310 -0
- stbkit/cli/commands/convert.py +16 -0
- stbkit/cli/commands/diff.py +16 -0
- stbkit/cli/commands/validate.py +16 -0
- stbkit/cli/py.typed +0 -0
- stbkit/tools/__init__.py +12 -0
- stbkit/tools/_internal/__init__.py +5 -0
- stbkit/tools/_internal/constants.py +21 -0
- stbkit/tools/_internal/data_model/building_geometry.py +1208 -0
- stbkit/tools/_internal/data_model/building_geometry_web.py +106 -0
- stbkit/tools/_internal/data_model/element_data.py +93 -0
- stbkit/tools/_internal/data_model/ifc_data/entity_data.py +67 -0
- stbkit/tools/_internal/data_model/ifc_data/entity_names.py +32 -0
- stbkit/tools/_internal/data_model/shape_data.py +1089 -0
- stbkit/tools/_internal/diff/__init__.py +5 -0
- stbkit/tools/_internal/diff/common.py +50 -0
- stbkit/tools/_internal/diff/diff_xml.py +796 -0
- stbkit/tools/_internal/matrix.py +51 -0
- stbkit/tools/_internal/optional_dependencies/__init__.py +5 -0
- stbkit/tools/_internal/optional_dependencies/ifc_common.py +28 -0
- stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_entity_exporter.py +473 -0
- stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_profile_exporter.py +267 -0
- stbkit/tools/_internal/optional_dependencies/ifc_exporter/ifc_representation_exporter.py +178 -0
- stbkit/tools/_internal/optional_dependencies/ifc_pipeline.py +133 -0
- stbkit/tools/_internal/optional_dependencies/ifc_to_building_geometry.py +64 -0
- stbkit/tools/_internal/stb_io.py +116 -0
- stbkit/tools/_internal/stb_repair/_common.py +24 -0
- stbkit/tools/_internal/stb_repair/_stb_repair.py +197 -0
- stbkit/tools/_internal/stb_repair/_stb_v2_0_2_repair.py +53 -0
- stbkit/tools/_internal/stb_repair/_stb_v2_1_0_repair.py +109 -0
- stbkit/tools/_internal/stb_repair/_stb_v2_1_1_repair.py +109 -0
- stbkit/tools/_internal/studio_report.py +49 -0
- stbkit/tools/_internal/utils/atomic_writer.py +57 -0
- stbkit/tools/_internal/utils/float_rounding.py +49 -0
- stbkit/tools/_internal/utils/girder_utils.py +91 -0
- stbkit/tools/_internal/utils/guid_utils.py +30 -0
- stbkit/tools/_internal/utils/mesh_utils.py +1305 -0
- stbkit/tools/_internal/utils/node_utils.py +50 -0
- stbkit/tools/_internal/utils/unit_utils.py +23 -0
- stbkit/tools/_internal/vectors.py +222 -0
- stbkit/tools/converters/__init__.py +39 -0
- stbkit/tools/converters/_internal/__init__.py +5 -0
- stbkit/tools/converters/_internal/building_geometry_to_ply_text.py +32 -0
- stbkit/tools/converters/_internal/coord_converter.py +151 -0
- stbkit/tools/converters/_internal/element_data_to_building_geometry.py +549 -0
- stbkit/tools/converters/_internal/ifc_to_ply_text.py +21 -0
- stbkit/tools/converters/_internal/name_converter.py +23 -0
- stbkit/tools/converters/_internal/pipeline/__init__.py +5 -0
- stbkit/tools/converters/_internal/pipeline/data.py +188 -0
- stbkit/tools/converters/_internal/pipeline/execution.py +569 -0
- stbkit/tools/converters/_internal/pipeline/ply_pipeline.py +52 -0
- stbkit/tools/converters/_internal/pipeline/stb_pipeline.py +226 -0
- stbkit/tools/converters/_internal/pipeline/stb_pipeline_latest.py +39 -0
- stbkit/tools/converters/_internal/pipeline/step.py +139 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/__init__.py +17 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/_stb_latest_to_element_data.py +186 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_footing.py +49 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_line.py +533 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_pile.py +100 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/member/member_plane.py +103 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/open.py +70 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec.py +214 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_rc.py +67 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_s.py +97 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_beam_src.py +28 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_brace_s.py +49 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_cft.py +217 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_rc.py +41 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_s.py +127 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_column_src.py +173 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_foundation.py +225 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_parapet_rc.py +53 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_pile_rc.py +106 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_pile_s.py +100 -0
- stbkit/tools/converters/_internal/stb_latest_to_element_data/section/sec_steel.py +432 -0
- stbkit/tools/converters/_internal/stb_to_building_geometry.py +44 -0
- stbkit/tools/converters/_internal/stb_to_ifc_data/__init__.py +5 -0
- stbkit/tools/converters/_internal/stb_to_ifc_data/_stb_to_ifc_data.py +59 -0
- stbkit/tools/converters/_internal/stb_to_ifc_data/convert_option.py +22 -0
- stbkit/tools/converters/_internal/stb_to_ply_text.py +22 -0
- stbkit/tools/py.typed +0 -0
- stbkit/tools/upgrade/__init__.py +13 -0
- stbkit/tools/upgrade/_internal/__init__.py +5 -0
- stbkit/tools/upgrade/_internal/common.py +205 -0
- stbkit/tools/upgrade/_internal/upgrade.py +228 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/__init__.py +60 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_common.py +62 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_joint_beam_shape_h.py +44 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_pile_rc.py +101 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_pile_s.py +78 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_slab_deck.py +56 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/hook_sec_slab_rc.py +128 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_girder.py +126 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_open.py +110 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_sec_beam_rc.py +227 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hook_funcs/post_sec_beam_s.py +1153 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/hooks.py +22 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/post.py +42 -0
- stbkit/tools/upgrade/_internal/v2_0_2_to_v2_1_0/tables.py +99 -0
- stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/__init__.py +58 -0
- stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/hooks.py +32 -0
- stbkit/tools/upgrade/_internal/v2_1_0_to_v2_1_1/tables.py +56 -0
- stbkit-0.1.0a9.dev1.dist-info/METADATA +196 -0
- stbkit-0.1.0a9.dev1.dist-info/RECORD +125 -0
- stbkit-0.1.0a9.dev1.dist-info/WHEEL +5 -0
- stbkit-0.1.0a9.dev1.dist-info/entry_points.txt +2 -0
- stbkit-0.1.0a9.dev1.dist-info/licenses/LICENSE +373 -0
- 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
|
+
)
|