osis-python 0.5.1__tar.gz → 0.5.3__tar.gz
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.
- {osis_python-0.5.1/src/osis_python.egg-info → osis_python-0.5.3}/PKG-INFO +1 -1
- {osis_python-0.5.1 → osis_python-0.5.3/src/osis_python.egg-info}/PKG-INFO +1 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/osis_python.egg-info/SOURCES.txt +8 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/__init__.py +1 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/boundary/manager.py +13 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/__init__.py +2 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/all_func.py +2 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/client.py +11 -2
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/command.py +11 -2
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/engine.py +32 -7
- osis_python-0.5.3/src/pyosis/core/exceptions.py +32 -0
- osis_python-0.5.3/src/pyosis/core/references.py +87 -0
- osis_python-0.5.3/src/pyosis/display/__init__.py +8 -0
- osis_python-0.5.3/src/pyosis/display/interface.py +103 -0
- osis_python-0.5.3/src/pyosis/display/manager.py +115 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/dynamic/manager.py +2 -2
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/element/manager.py +13 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/general/interface.py +15 -19
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/geometry/manager.py +8 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/live/manager.py +15 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/load/manager.py +34 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/load/tendon.py +18 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/material/manager.py +8 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/node/manager.py +8 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/project/interface.py +12 -1
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/project/manager.py +30 -6
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/manager.py +49 -4
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/manager.py +36 -7
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/param.py +17 -8
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/thickness/manager.py +8 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/generator.py +3 -2
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/out_to_python.py +99 -5
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/routes.py +6 -0
- osis_python-0.5.3/tests/test_delete_occupied.py +432 -0
- osis_python-0.5.3/tests/test_project_manager.py +135 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/LICENSE +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/README.md +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/pyproject.toml +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/setup.cfg +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/osis_python.egg-info/dependency_links.txt +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/osis_python.egg-info/requires.txt +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/osis_python.egg-info/top_level.txt +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/boundary/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/boundary/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/control/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/control/control.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/control/io.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/control/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/control/nonlinear.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/apdl_sync.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/basic_manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/build.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/core/sync_apdl_cli.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/dynamic/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/dynamic/load_to_mass.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/dynamic/modal.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/dynamic/seismic.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/element/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/element/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/general/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/geometry/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/geometry/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/live/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/live/analysis.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/live/grade.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/live/lane.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/load/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/load/loadcase.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/load/static.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/material/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/material/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/node/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/node/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/post/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/post/combine.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/post/design_check.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/post/display.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/post/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/project/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/component_thickness.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/coordinate.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/creep_shrink.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/damping.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/property/pu_curve.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/quick_building/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/quick_building/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/result/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/result/check.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/result/env.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/result/loadcase.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/result/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/result/result.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/common.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/composite.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/numeric.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/rebar.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/rib.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/section/steel.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/settlement/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/settlement/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/settlement/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stability/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stability/buckling.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stability/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stage/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stage/define.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stage/manager.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/stage/overall.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/thickness/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/thickness/interface.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/__init__.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/matrix.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/parser.py +0 -0
- {osis_python-0.5.1 → osis_python-0.5.3}/src/pyosis/transfer/split.py +0 -0
|
@@ -23,7 +23,12 @@ src/pyosis/core/build.py
|
|
|
23
23
|
src/pyosis/core/client.py
|
|
24
24
|
src/pyosis/core/command.py
|
|
25
25
|
src/pyosis/core/engine.py
|
|
26
|
+
src/pyosis/core/exceptions.py
|
|
27
|
+
src/pyosis/core/references.py
|
|
26
28
|
src/pyosis/core/sync_apdl_cli.py
|
|
29
|
+
src/pyosis/display/__init__.py
|
|
30
|
+
src/pyosis/display/interface.py
|
|
31
|
+
src/pyosis/display/manager.py
|
|
27
32
|
src/pyosis/dynamic/__init__.py
|
|
28
33
|
src/pyosis/dynamic/load_to_mass.py
|
|
29
34
|
src/pyosis/dynamic/manager.py
|
|
@@ -104,4 +109,6 @@ src/pyosis/transfer/matrix.py
|
|
|
104
109
|
src/pyosis/transfer/out_to_python.py
|
|
105
110
|
src/pyosis/transfer/parser.py
|
|
106
111
|
src/pyosis/transfer/routes.py
|
|
107
|
-
src/pyosis/transfer/split.py
|
|
112
|
+
src/pyosis/transfer/split.py
|
|
113
|
+
tests/test_delete_occupied.py
|
|
114
|
+
tests/test_project_manager.py
|
|
@@ -7,7 +7,7 @@ A library for extending OSIS functionality.
|
|
|
7
7
|
A library that allows users to use CAE with great flexibility.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
__version__ = "0.5.
|
|
10
|
+
__version__ = "0.5.3"
|
|
11
11
|
__author__ = "CCCC Highway Consultant Co. Ltd." # 中交公路规划设计院 - 工程技术研究中心 - lzh - wjh - myf
|
|
12
12
|
|
|
13
13
|
from .core.engine import OSISEngine
|
|
@@ -23,6 +23,7 @@ from typing import Any, Literal
|
|
|
23
23
|
from enum import IntEnum
|
|
24
24
|
|
|
25
25
|
from ..core.client import osis_client
|
|
26
|
+
from ..core import get_references, raise_if_occupied
|
|
26
27
|
from .interface import (
|
|
27
28
|
osis_boundary_general,
|
|
28
29
|
osis_boundary_elstcspt,
|
|
@@ -638,6 +639,10 @@ class BoundaryManager:
|
|
|
638
639
|
return 1
|
|
639
640
|
return max(bd.no for bd in boundaries) + 1
|
|
640
641
|
|
|
642
|
+
def get_dependencies(self, no: int) -> dict[str, list]:
|
|
643
|
+
"""查询边界被谁引用"""
|
|
644
|
+
return get_references("Boundary", no=no)
|
|
645
|
+
|
|
641
646
|
# ── 增删改 ────────────────────────────────
|
|
642
647
|
def create(self, no: int | None, type: str, *args: Any, **kwargs: Any) -> Boundary:
|
|
643
648
|
"""创建边界(便捷入口,内部转发到对应 create_* 方法)
|
|
@@ -846,7 +851,14 @@ class BoundaryManager:
|
|
|
846
851
|
return self.get(no) # type: ignore[return-value]
|
|
847
852
|
|
|
848
853
|
def delete(self, no: int) -> None:
|
|
849
|
-
"""删除边界
|
|
854
|
+
"""删除边界
|
|
855
|
+
|
|
856
|
+
Raises:
|
|
857
|
+
DependencyError: 存在依赖项时
|
|
858
|
+
RuntimeError: 删除失败时抛出异常
|
|
859
|
+
"""
|
|
860
|
+
deps = self.get_dependencies(no)
|
|
861
|
+
raise_if_occupied("Boundary", deps, no=no)
|
|
850
862
|
ok, err = osis_boundary_del(no)
|
|
851
863
|
if not ok:
|
|
852
864
|
raise RuntimeError(f"删除边界 {no} 失败: {err}")
|
|
@@ -26,6 +26,8 @@ session.mount("https://", adapter) # 如果你后续用HTTPS
|
|
|
26
26
|
|
|
27
27
|
DEFAULT_PORT = 18080
|
|
28
28
|
DEFAULT_URL = "http://localhost"
|
|
29
|
+
DEFAULT_TIMEOUT = 300
|
|
30
|
+
DEFAULT_SOLVE_TIMEOUT = 600
|
|
29
31
|
|
|
30
32
|
def set_osis_url(url):
|
|
31
33
|
'''
|
|
@@ -42,12 +44,19 @@ def set_osis_port(port):
|
|
|
42
44
|
DEFAULT_PORT = port
|
|
43
45
|
|
|
44
46
|
# ========== 通用客户端函数(复用连接池) ==========
|
|
45
|
-
def osis_client(
|
|
47
|
+
def osis_client(
|
|
48
|
+
func_name: str,
|
|
49
|
+
payload: dict,
|
|
50
|
+
base_url=None,
|
|
51
|
+
timeout: float | None = None,
|
|
52
|
+
) -> dict:
|
|
46
53
|
"""
|
|
47
54
|
通用 OSIS 接口客户端(复用连接池,高效批量调用)
|
|
48
55
|
Args:
|
|
49
56
|
func_name: C++ 接口名(如 "OSIS_Run")
|
|
50
57
|
payload: 请求参数字典(自动序列化为 JSON)
|
|
58
|
+
base_url: url
|
|
59
|
+
timeout: HTTP 超时秒数,默认 DEFAULT_TIMEOUT
|
|
51
60
|
Returns:
|
|
52
61
|
异常时返回 (False, 错误信息)
|
|
53
62
|
"""
|
|
@@ -59,7 +68,7 @@ def osis_client(func_name: str, payload: dict, base_url=None) -> dict:
|
|
|
59
68
|
url,
|
|
60
69
|
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
|
|
61
70
|
headers={"Content-Type": "application/json; charset=utf-8"},
|
|
62
|
-
timeout=
|
|
71
|
+
timeout=timeout if timeout is not None else DEFAULT_TIMEOUT,
|
|
63
72
|
)
|
|
64
73
|
|
|
65
74
|
data = None
|
|
@@ -19,7 +19,11 @@ from .client import osis_client
|
|
|
19
19
|
# f.write(f"[{timestamp}] {text}\n")
|
|
20
20
|
# f.close()
|
|
21
21
|
|
|
22
|
-
def osis_run(
|
|
22
|
+
def osis_run(
|
|
23
|
+
strCmd: str = "",
|
|
24
|
+
mode: Literal["stash", "exec"] = "exec",
|
|
25
|
+
timeout: float | None = None,
|
|
26
|
+
) -> tuple[bool, str]:
|
|
23
27
|
"""
|
|
24
28
|
http 模拟 C++ 原生 OSIS_Run 函数
|
|
25
29
|
Args:
|
|
@@ -27,11 +31,16 @@ def osis_run(strCmd: str="", mode: Literal["stash", "exec"]="exec") -> tuple[boo
|
|
|
27
31
|
mode: 运行模式,此参数为了同时执行多条命令提高效率
|
|
28
32
|
* 使用 stash 仅会将命令流存到OSIS中,不会执行
|
|
29
33
|
* 收到 exec 信号才会执行暂存包括当前的所有命令流。
|
|
34
|
+
timeout: HTTP 超时秒数,默认由 osis_client 决定
|
|
30
35
|
|
|
31
36
|
Returns:
|
|
32
37
|
tuple (bool, str): 是否成功,失败原因
|
|
33
38
|
"""
|
|
34
|
-
response = osis_client(
|
|
39
|
+
response = osis_client(
|
|
40
|
+
"OSIS_Run",
|
|
41
|
+
{"strCmd": strCmd, "mode": mode},
|
|
42
|
+
timeout=timeout,
|
|
43
|
+
)
|
|
35
44
|
return response['success'], response['error']
|
|
36
45
|
|
|
37
46
|
def _log(text, log_dir="pyosis_logs"):
|
|
@@ -41,6 +41,7 @@ from ..stability.manager import StabilityManager, stability_manager
|
|
|
41
41
|
from ..dynamic.manager import DynamicManager, dynamic_manager
|
|
42
42
|
from ..post.manager import PostManager, post_manager
|
|
43
43
|
from ..result.manager import ResultManager, result_manager
|
|
44
|
+
from ..display.manager import DisplayManager, display_manager
|
|
44
45
|
from ..general.interface import (
|
|
45
46
|
osis_matrix,
|
|
46
47
|
output_result_for_calc_book,
|
|
@@ -69,7 +70,7 @@ class OSISEngine:
|
|
|
69
70
|
- tendon: 钢束管理器(含 prop/shape 子管理器)
|
|
70
71
|
- live: 活载管理器(含 grade/lane/case 子管理器)
|
|
71
72
|
- geometry: 几何管理器(三维样条曲线)
|
|
72
|
-
- property
|
|
73
|
+
- prop: 属性管理器(property 坐标系、收缩徐变、阻尼等)
|
|
73
74
|
- thickness: 厚度管理器(壳厚度特性)
|
|
74
75
|
- control: 控制管理器(全局参数、分析设置)
|
|
75
76
|
- project: 项目管理器(创建、打开、保存项目)
|
|
@@ -78,6 +79,7 @@ class OSISEngine:
|
|
|
78
79
|
- dynamic: 动力分析管理器(荷载转换质量、模态、反应谱)
|
|
79
80
|
- post: 后处理管理器(荷载组合、规范验算、结果显示)
|
|
80
81
|
- result: 结果导出管理器(工况结果、包络结果、验算结果)
|
|
82
|
+
- display: 显示管理器(边界 / 荷载 / 钢束显隐等)
|
|
81
83
|
|
|
82
84
|
通用操作可直接通过 engine 调用:
|
|
83
85
|
- run(), solve(), replot(), clear(), clc()
|
|
@@ -114,6 +116,9 @@ class OSISEngine:
|
|
|
114
116
|
### 后处理 ###
|
|
115
117
|
self._post = post_manager
|
|
116
118
|
self._result = result_manager
|
|
119
|
+
|
|
120
|
+
### 显示 ###
|
|
121
|
+
self._display = display_manager
|
|
117
122
|
|
|
118
123
|
# OSIS端口与网址
|
|
119
124
|
if port is None:
|
|
@@ -228,6 +233,13 @@ class OSISEngine:
|
|
|
228
233
|
"""结果导出管理器(工况结果、包络结果、验算结果)"""
|
|
229
234
|
return self._result
|
|
230
235
|
|
|
236
|
+
### 显示 ###
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def display(self) -> DisplayManager:
|
|
240
|
+
"""显示管理器(边界 / 荷载 / 钢束显隐等)"""
|
|
241
|
+
return self._display
|
|
242
|
+
|
|
231
243
|
# ──────────────────────────────────────────
|
|
232
244
|
# 通用操作(直接暴露 general 和 core 的函数)
|
|
233
245
|
# ──────────────────────────────────────────
|
|
@@ -246,9 +258,13 @@ class OSISEngine:
|
|
|
246
258
|
if not ok:
|
|
247
259
|
raise RuntimeError(f"执行失败: {err}")
|
|
248
260
|
|
|
249
|
-
def solve(self) -> None:
|
|
250
|
-
"""求解工程
|
|
251
|
-
|
|
261
|
+
def solve(self, timeout: float | None = None) -> None:
|
|
262
|
+
"""求解工程
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
timeout: HTTP 超时秒数,默认 600(10 分钟)
|
|
266
|
+
"""
|
|
267
|
+
ok, err = osis_solve(timeout=timeout)
|
|
252
268
|
if not ok:
|
|
253
269
|
raise RuntimeError(f"求解失败: {err}")
|
|
254
270
|
|
|
@@ -293,9 +309,14 @@ class OSISEngine:
|
|
|
293
309
|
# 便捷方法(委托给 project manager)
|
|
294
310
|
# ──────────────────────────────────────────
|
|
295
311
|
|
|
296
|
-
def save_project(self) -> None:
|
|
297
|
-
"""
|
|
298
|
-
|
|
312
|
+
def save_project(self, filepath: str = "") -> None:
|
|
313
|
+
"""保存项目
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
filepath: 工程文件路径。为空时使用当前项目路径;
|
|
317
|
+
非空时使用传入路径。
|
|
318
|
+
"""
|
|
319
|
+
self._project.save(filepath)
|
|
299
320
|
|
|
300
321
|
def new_project(self, type: int = 1, filepath: str = "") -> None:
|
|
301
322
|
"""新建项目
|
|
@@ -314,6 +335,10 @@ class OSISEngine:
|
|
|
314
335
|
"""
|
|
315
336
|
self._project.open(filepath)
|
|
316
337
|
|
|
338
|
+
def close(self) -> None:
|
|
339
|
+
"""关闭 OSIS 软件"""
|
|
340
|
+
self._project.close()
|
|
341
|
+
|
|
317
342
|
# ──────────────────────────────────────────
|
|
318
343
|
# 便捷方法(委托给 control manager)
|
|
319
344
|
# ──────────────────────────────────────────
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyosis 自定义异常
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
class DependencyError(RuntimeError):
|
|
6
|
+
"""删除实体时存在依赖项
|
|
7
|
+
|
|
8
|
+
Attributes:
|
|
9
|
+
entity_type: 实体类型字符串,如 "Material"
|
|
10
|
+
id_value: 实体编号(int)或名称(str)
|
|
11
|
+
no: 按编号寻址时的编号,否则为 None
|
|
12
|
+
name: 按名称寻址时的名称,否则为 None
|
|
13
|
+
dependencies: 依赖关系字典
|
|
14
|
+
"""
|
|
15
|
+
def __init__(self, entity_type: str, id_value: int | str, dependencies: dict[str, list]):
|
|
16
|
+
self.entity_type = entity_type
|
|
17
|
+
self.id_value = id_value
|
|
18
|
+
self.dependencies = dependencies
|
|
19
|
+
if isinstance(id_value, int):
|
|
20
|
+
self.no = id_value
|
|
21
|
+
self.name = None
|
|
22
|
+
label = f"#{id_value}"
|
|
23
|
+
else:
|
|
24
|
+
self.no = None
|
|
25
|
+
self.name = id_value
|
|
26
|
+
label = id_value
|
|
27
|
+
|
|
28
|
+
lines = [f"无法删除 {entity_type} {label},存在以下依赖:"]
|
|
29
|
+
for kind, refs in dependencies.items():
|
|
30
|
+
if refs:
|
|
31
|
+
lines.append(f" - {kind}: {refs}")
|
|
32
|
+
super().__init__("\n".join(lines))
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
通用引用查询客户端封装
|
|
3
|
+
|
|
4
|
+
后端 C++ 暴露 /GetReferences 接口,根据 entityType 字符串分派
|
|
5
|
+
到对应 Info 类的 getRelated* 方法。
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
from typing import Literal
|
|
9
|
+
from .client import osis_client
|
|
10
|
+
from .exceptions import DependencyError
|
|
11
|
+
|
|
12
|
+
# 支持的实体类型(与 C++ GetReferences.cpp 中的 if-else 分支对齐)
|
|
13
|
+
EntityType = Literal[
|
|
14
|
+
"Material", "Section", "Node", "Element", "Boundary",
|
|
15
|
+
"TendonShape", "TendonProp", "LoadCase", "LiveGrade", "LiveLane",
|
|
16
|
+
"CoorSys", "CreepShrink", "PUCurve", "ShellThickness",
|
|
17
|
+
"Damping", "Spline",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
通用引用查询客户端封装
|
|
23
|
+
后端 /GetReferences 统一字符串协议:{entityType, idKey("no"|"name"), idValue}
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_references(entity_type: str, *, no: int | None = None, name: str | None = None) -> dict[str, list]:
|
|
29
|
+
"""查询某个实体被哪些其他实体引用
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
entity_type: 实体类型,如 "Material" / "Node" / "TendonShape" / "LoadCase"
|
|
33
|
+
no: 按编号寻址时传(Material/Section/Node/Element)
|
|
34
|
+
name: 按名称寻址时传(TendonShape/LoadCase/...)
|
|
35
|
+
no 与 name 二选一。
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
引用关系字典,如 {"elements":[101,102], "loads":["自重"], ...}
|
|
39
|
+
无依赖时返回空字典。
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
ValueError: no/name 都没传,或都传了
|
|
43
|
+
RuntimeError: 查询失败
|
|
44
|
+
"""
|
|
45
|
+
if no is not None and name is not None:
|
|
46
|
+
raise ValueError("no 与 name 只能传一个")
|
|
47
|
+
if no is None and name is None:
|
|
48
|
+
raise ValueError("必须提供 no 或 name")
|
|
49
|
+
|
|
50
|
+
if no is not None:
|
|
51
|
+
id_key, id_value = "no", str(no)
|
|
52
|
+
else:
|
|
53
|
+
id_key, id_value = "name", name
|
|
54
|
+
|
|
55
|
+
resp = osis_client("GetReferences", {
|
|
56
|
+
"entityType": entity_type,
|
|
57
|
+
"idKey": id_key,
|
|
58
|
+
"idValue": id_value,
|
|
59
|
+
})
|
|
60
|
+
if not resp.get("success"):
|
|
61
|
+
raise RuntimeError(f"查询 {entity_type}({id_key}={id_value}) 引用失败: {resp.get('error')}")
|
|
62
|
+
return resp.get("data") or {}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def raise_if_occupied(
|
|
66
|
+
entity_type: str,
|
|
67
|
+
deps: dict[str, list],
|
|
68
|
+
*,
|
|
69
|
+
no: int | None = None,
|
|
70
|
+
name: str | None = None,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""存在非空依赖时抛出 DependencyError。
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
entity_type: 实体类型,如 "Material" / "TendonShape"
|
|
76
|
+
deps: get_references / get_dependencies 返回的依赖字典
|
|
77
|
+
no: 按编号寻址时传
|
|
78
|
+
name: 按名称寻址时传
|
|
79
|
+
"""
|
|
80
|
+
non_empty = {k: v for k, v in deps.items() if v}
|
|
81
|
+
if not non_empty:
|
|
82
|
+
return
|
|
83
|
+
if no is None and name is None:
|
|
84
|
+
raise ValueError("必须提供 no 或 name")
|
|
85
|
+
id_value = no if no is not None else name
|
|
86
|
+
raise DependencyError(entity_type, id_value, non_empty)
|
|
87
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""显示控制命令接口
|
|
2
|
+
|
|
3
|
+
控制边界、荷载、钢束显隐,以及视图方向、显示开关等。
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Literal, Sequence, Union
|
|
7
|
+
|
|
8
|
+
from ..core import REGISTRY
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@REGISTRY.register("DispCtrl")
|
|
12
|
+
def osis_disp_ctrl(
|
|
13
|
+
eObject: Literal["bc", "boundary", "lg", "load", "td", "tendon"],
|
|
14
|
+
eType: str,
|
|
15
|
+
ids: Union[str, int, Sequence[Union[str, int]]],
|
|
16
|
+
bShow: Literal[0, 1] = 1,
|
|
17
|
+
):
|
|
18
|
+
"""控制边界 / 荷载 / 钢束的显示与隐藏。
|
|
19
|
+
|
|
20
|
+
格式: ``dispctrl,<Object>,<Type>,<Number/Name...>,<0|1>``
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
eObject (str): 对象类型
|
|
24
|
+
* ``bc`` / ``boundary`` = 边界
|
|
25
|
+
* ``lg`` / ``load`` = 荷载
|
|
26
|
+
* ``td`` / ``tendon`` = 钢束
|
|
27
|
+
eType (str): 子类型
|
|
28
|
+
* 边界: ``all``, ``general``, ``mstslv``, ``release``, ``elstcspt``,
|
|
29
|
+
``generalelstcspt``, ``rigid``, ``secfactor``
|
|
30
|
+
* 荷载: ``all``, ``gravity``, ``nforce``, ``line``, ``pointforce``,
|
|
31
|
+
``pointmoment``, ``displacement``, ``initial``, ``utemp``, ``gtemp``,
|
|
32
|
+
``pst``, ``cforce``, ``elementsurface``
|
|
33
|
+
* 钢束: 通常为 ``all``
|
|
34
|
+
ids: 编号或名称
|
|
35
|
+
* ``all`` = 全部
|
|
36
|
+
* 单个编号 / 名称,或多个组成的序列(如 ``[1, 2, "3to10"]``、``["T1", "T2"]``)
|
|
37
|
+
bShow (int): ``0`` = 隐藏,``1`` = 显示
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
tuple (bool, str): 是否成功,失败原因
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
>>> # 显示全部边界
|
|
44
|
+
>>> osis_disp_ctrl("bc", "all", "all", 1)
|
|
45
|
+
>>> # 显示一般边界 1、2、3to10
|
|
46
|
+
>>> osis_disp_ctrl("bc", "general", [1, 2, "3to10"], 1)
|
|
47
|
+
>>> # 显示全部节点力荷载
|
|
48
|
+
>>> osis_disp_ctrl("lg", "nforce", "all", 1)
|
|
49
|
+
>>> # 显示名为 DeadLoad 的荷载
|
|
50
|
+
>>> osis_disp_ctrl("lg", "all", "DeadLoad", 1)
|
|
51
|
+
>>> # 隐藏钢束 1、2、3to10
|
|
52
|
+
>>> osis_disp_ctrl("td", "all", [1, 2, "3to10"], 0)
|
|
53
|
+
>>> # 显示钢束 T1、T2
|
|
54
|
+
>>> osis_disp_ctrl("td", "all", ["T1", "T2"], 1)
|
|
55
|
+
"""
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@REGISTRY.register("/control")
|
|
60
|
+
def osis_control(
|
|
61
|
+
eAction: str,
|
|
62
|
+
eArg: str | None = None,
|
|
63
|
+
):
|
|
64
|
+
"""视图 / 界面控制命令。
|
|
65
|
+
|
|
66
|
+
格式: ``/control,<Action>[,<Arg>]``
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
eAction (str): 子命令
|
|
70
|
+
* ``view`` = 切换视图方向(配合 eArg)
|
|
71
|
+
* 其他如 ``quickCreateModel`` 等
|
|
72
|
+
eArg (str | None): 子命令参数
|
|
73
|
+
* 当 eAction 为 ``view`` 时: ``standard`` / ``top`` / ``right`` / ``front``
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
tuple (bool, str): 是否成功,失败原因
|
|
77
|
+
|
|
78
|
+
Examples:
|
|
79
|
+
>>> osis_control("view", "standard")
|
|
80
|
+
>>> osis_control("view", "top")
|
|
81
|
+
>>> osis_control("view", "right")
|
|
82
|
+
>>> osis_control("view", "front")
|
|
83
|
+
"""
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@REGISTRY.register("Plsm")
|
|
88
|
+
def osis_plsm(bFlag: Literal[0, 1] = 1):
|
|
89
|
+
"""显示开关(Plsm)。
|
|
90
|
+
|
|
91
|
+
格式: ``plsm,<0|1>``
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
bFlag (int): ``0`` = 关,``1`` = 开
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
tuple (bool, str): 是否成功,失败原因
|
|
98
|
+
|
|
99
|
+
Examples:
|
|
100
|
+
>>> osis_plsm(1)
|
|
101
|
+
>>> osis_plsm(0)
|
|
102
|
+
"""
|
|
103
|
+
pass
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""显示管理器 - 控制显隐、视图方向与显示开关
|
|
2
|
+
|
|
3
|
+
设计理念:
|
|
4
|
+
- 隐藏底层命令接口细节,提供原生 Python 风格 API
|
|
5
|
+
- 无状态设计,操作直接提交到 OSIS
|
|
6
|
+
|
|
7
|
+
用法:
|
|
8
|
+
>>> from pyosis.display import display_manager
|
|
9
|
+
>>> display_manager.disp_ctrl("bc", "all", "all", 1)
|
|
10
|
+
>>> display_manager.set_view("top")
|
|
11
|
+
>>> display_manager.set_plsm(1)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import Literal, Sequence, Union
|
|
17
|
+
|
|
18
|
+
from .interface import osis_control, osis_disp_ctrl, osis_plsm
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DisplayManager:
|
|
22
|
+
"""显示管理器
|
|
23
|
+
|
|
24
|
+
控制边界 / 荷载 / 钢束显隐、视图方向与显示开关。
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def disp_ctrl(
|
|
28
|
+
self,
|
|
29
|
+
obj: Literal["bc", "boundary", "lg", "load", "td", "tendon"],
|
|
30
|
+
type: str,
|
|
31
|
+
ids: Union[str, int, Sequence[Union[str, int]]],
|
|
32
|
+
show: Literal[0, 1] = 1,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""控制边界 / 荷载 / 钢束的显示与隐藏。
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
obj: 对象类型
|
|
38
|
+
* ``bc`` / ``boundary`` = 边界
|
|
39
|
+
* ``lg`` / ``load`` = 荷载
|
|
40
|
+
* ``td`` / ``tendon`` = 钢束
|
|
41
|
+
type: 子类型(``all`` 或具体类型,见 ``osis_disp_ctrl`` 文档)
|
|
42
|
+
ids: 编号或名称(``all`` / 单个 / 序列)
|
|
43
|
+
show: ``0`` = 隐藏,``1`` = 显示
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
RuntimeError: 操作失败时抛出异常
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
>>> display_manager.disp_ctrl("bc", "all", "all", 1)
|
|
50
|
+
>>> display_manager.disp_ctrl("bc", "general", [1, 2, "3to10"], 1)
|
|
51
|
+
>>> display_manager.disp_ctrl("lg", "nforce", "all", 1)
|
|
52
|
+
>>> display_manager.disp_ctrl("td", "all", ["T1", "T2"], 1)
|
|
53
|
+
"""
|
|
54
|
+
ok, err = osis_disp_ctrl(obj, type, ids, show)
|
|
55
|
+
if not ok:
|
|
56
|
+
raise RuntimeError(f"显示控制失败: {err}")
|
|
57
|
+
|
|
58
|
+
def control(self, action: str, arg: str | None = None) -> None:
|
|
59
|
+
"""视图 / 界面控制(对应 ``/control,...``)。
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
action: 子命令,如 ``view``、``quickCreateModel``
|
|
63
|
+
arg: 子命令参数;``view`` 时为 ``standard`` / ``top`` / ``right`` / ``front``
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
RuntimeError: 操作失败时抛出异常
|
|
67
|
+
"""
|
|
68
|
+
ok, err = osis_control(action, arg)
|
|
69
|
+
if not ok:
|
|
70
|
+
raise RuntimeError(f"界面控制失败: {err}")
|
|
71
|
+
|
|
72
|
+
def set_view(
|
|
73
|
+
self,
|
|
74
|
+
view: Literal["standard", "top", "right", "front"] = "standard",
|
|
75
|
+
) -> None:
|
|
76
|
+
"""切换视图方向。
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
view: ``standard`` / ``top`` / ``right`` / ``front``
|
|
80
|
+
|
|
81
|
+
Raises:
|
|
82
|
+
RuntimeError: 操作失败时抛出异常
|
|
83
|
+
|
|
84
|
+
Examples:
|
|
85
|
+
>>> display_manager.set_view("top")
|
|
86
|
+
>>> display_manager.set_view("front")
|
|
87
|
+
"""
|
|
88
|
+
self.control("view", view)
|
|
89
|
+
|
|
90
|
+
def set_plsm(self, enabled: Literal[0, 1] = 1) -> None:
|
|
91
|
+
"""显示开关(Plsm)。
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
enabled: ``0`` = 关,``1`` = 开
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
RuntimeError: 操作失败时抛出异常
|
|
98
|
+
|
|
99
|
+
Examples:
|
|
100
|
+
>>> display_manager.set_plsm(1)
|
|
101
|
+
>>> display_manager.set_plsm(0)
|
|
102
|
+
"""
|
|
103
|
+
ok, err = osis_plsm(enabled)
|
|
104
|
+
if not ok:
|
|
105
|
+
raise RuntimeError(f"设置 Plsm 失败: {err}")
|
|
106
|
+
|
|
107
|
+
def __repr__(self) -> str:
|
|
108
|
+
return "DisplayManager()"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# ═════════════════════════════════════════════
|
|
112
|
+
# 全局单例
|
|
113
|
+
# ═════════════════════════════════════════════
|
|
114
|
+
|
|
115
|
+
display_manager = DisplayManager()
|
|
@@ -579,7 +579,7 @@ class RspecAnalManager:
|
|
|
579
579
|
|
|
580
580
|
def _load(self) -> list[RspecAnal]:
|
|
581
581
|
"""从服务端加载所有反应谱工况信息"""
|
|
582
|
-
resp = osis_client("
|
|
582
|
+
resp = osis_client("GetAllRespSpecInfo", {})
|
|
583
583
|
if not resp['success']:
|
|
584
584
|
raise RuntimeError(f"{resp['error']}")
|
|
585
585
|
rsp = [RspecAnal._from_dict(d) for d in resp.get("data", [])]
|
|
@@ -594,7 +594,7 @@ class RspecAnalManager:
|
|
|
594
594
|
names = [str(name)]
|
|
595
595
|
if not isinstance(names, list):
|
|
596
596
|
raise TypeError(f"不支持的名称类型: {type(name)}")
|
|
597
|
-
resp = osis_client("
|
|
597
|
+
resp = osis_client("GetRespSpecInfoByNames", {"name": names})
|
|
598
598
|
if not resp['success']:
|
|
599
599
|
raise RuntimeError(f"{resp['error']}")
|
|
600
600
|
rsp = [RspecAnal._from_dict(d) if d else None for d in resp.get("data", [])]
|
|
@@ -15,6 +15,7 @@ from dataclasses import dataclass, field
|
|
|
15
15
|
from typing import Any, Literal
|
|
16
16
|
from enum import Enum
|
|
17
17
|
from ..core.client import osis_client
|
|
18
|
+
from ..core import get_references, raise_if_occupied
|
|
18
19
|
from .interface import (
|
|
19
20
|
osis_element_beam3d,
|
|
20
21
|
osis_element_truss,
|
|
@@ -555,6 +556,10 @@ class ElementManager:
|
|
|
555
556
|
ele_no = [ele.no for ele in elements]
|
|
556
557
|
return max(ele_no) + 1
|
|
557
558
|
|
|
559
|
+
def get_dependencies(self, no: int) -> dict[str, list]:
|
|
560
|
+
"""查询单元被谁引用"""
|
|
561
|
+
return get_references("Element", no=no)
|
|
562
|
+
|
|
558
563
|
# ── 增删改 ────────────────────────────────
|
|
559
564
|
def create(self, no: int | None, type: str, *args: Any, **kwargs: Any) -> Element:
|
|
560
565
|
"""创建单元(便捷入口,内部转发到对应 create_* 方法)
|
|
@@ -699,7 +704,14 @@ class ElementManager:
|
|
|
699
704
|
return self.get(no)
|
|
700
705
|
|
|
701
706
|
def delete(self, no: int) -> None:
|
|
702
|
-
"""删除单元
|
|
707
|
+
"""删除单元
|
|
708
|
+
|
|
709
|
+
Raises:
|
|
710
|
+
DependencyError: 存在依赖项时
|
|
711
|
+
RuntimeError: 删除失败时抛出异常
|
|
712
|
+
"""
|
|
713
|
+
deps = self.get_dependencies(no)
|
|
714
|
+
raise_if_occupied("Element", deps, no=no)
|
|
703
715
|
ok, err = osis_element_del(no)
|
|
704
716
|
if not ok:
|
|
705
717
|
raise RuntimeError(f"删除单元 {no} 失败: {err}")
|