phg-vis 1.3.1__py3-none-any.whl → 1.4.0__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.
- phg/__init__.py +322 -35
- phg/ai_bridge.py +174 -0
- phg/gcu_api.py +709 -0
- phg/pipe_string_phg.py +342 -188
- phg/shader_render.py +26 -12
- phg/visphg.py +79 -55
- phg/web_three.py +164 -0
- {phg_vis-1.3.1.dist-info → phg_vis-1.4.0.dist-info}/METADATA +56 -1
- {phg_vis-1.3.1.dist-info → phg_vis-1.4.0.dist-info}/RECORD +12 -9
- {phg_vis-1.3.1.dist-info → phg_vis-1.4.0.dist-info}/LICENSE +0 -0
- {phg_vis-1.3.1.dist-info → phg_vis-1.4.0.dist-info}/WHEEL +0 -0
- {phg_vis-1.3.1.dist-info → phg_vis-1.4.0.dist-info}/top_level.txt +0 -0
phg/pipe_string_phg.py
CHANGED
|
@@ -2,284 +2,438 @@
|
|
|
2
2
|
Pipe String to PHG Converter
|
|
3
3
|
============================
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
5
|
+
This module provides functionality to convert pipe strings into PHG (Python Graphics) scripts.
|
|
6
|
+
Supports both world coordinate system and local coordinate system pipe descriptions.
|
|
7
|
+
|
|
8
|
+
Main Features:
|
|
9
|
+
- local_pipe_to_phg: Local coordinate system pipe conversion
|
|
10
|
+
- world_pipestr_vis: Direct visualization for world coordinate pipes (converts to local first)
|
|
11
|
+
- local_pipestr_vis: Direct visualization for local coordinate pipes
|
|
12
|
+
- multiple_pipes_vis: Advanced visualization for multiple pipes
|
|
13
|
+
|
|
14
|
+
Pipe String Format:
|
|
15
|
+
World Coordinate System:
|
|
16
|
+
- N: North (World X+)
|
|
17
|
+
- S: South (World X-)
|
|
18
|
+
- E: East (World Z+)
|
|
19
|
+
- W: West (World Z-)
|
|
20
|
+
- U: Up (World Y+)
|
|
21
|
+
- D: Down (World Y-)
|
|
22
|
+
|
|
23
|
+
Local Coordinate System:
|
|
24
|
+
- F: Forward (Local Z+)
|
|
25
|
+
- B: Backward (Local Z-)
|
|
26
|
+
- R: Right (Local X+)
|
|
27
|
+
- L: Left (Local X-)
|
|
28
|
+
- U: Up (Local Y+)
|
|
29
|
+
- D: Down (Local Y-)
|
|
21
30
|
"""
|
|
22
31
|
|
|
23
32
|
import phg
|
|
24
33
|
from coordinate_system import vec3, quat, coord3
|
|
25
34
|
|
|
26
|
-
#
|
|
35
|
+
# Default color and pipe radius
|
|
27
36
|
DEFAULT_PIPE_COLOR = (0, 55, 255)
|
|
28
37
|
DEFAULT_PIPE_RADIUS = 0.3
|
|
29
38
|
|
|
30
|
-
def
|
|
39
|
+
def world_to_local_pipe_str(world_pipe_str, start_c):
|
|
31
40
|
"""
|
|
32
|
-
|
|
41
|
+
Convert world coordinate system pipe string to local coordinate system
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
world_pipe_str:
|
|
36
|
-
start_c:
|
|
37
|
-
pipe_color: 管道颜色,格式为(R, G, B)元组
|
|
38
|
-
pipe_radius: 管道半径
|
|
43
|
+
Parameters:
|
|
44
|
+
world_pipe_str: World coordinate pipe string (e.g., "NNEUD")
|
|
45
|
+
start_c: Starting coordinate system
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
Returns:
|
|
48
|
+
Local coordinate pipe string
|
|
42
49
|
"""
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
'
|
|
51
|
+
if not world_pipe_str:
|
|
52
|
+
return ""
|
|
53
|
+
|
|
54
|
+
# World coordinate system direction definitions (cardinal directions)
|
|
55
|
+
directions = {
|
|
56
|
+
'E': vec3(1, 0, 0), # East (X+)
|
|
57
|
+
'W': vec3(-1, 0, 0), # West (X-)
|
|
58
|
+
'N': vec3(0, 0, 1), # North (Z+)
|
|
59
|
+
'S': vec3(0, 0, -1), # South (Z-)
|
|
60
|
+
'U': vec3(0, 1, 0), # Up (Y+)
|
|
61
|
+
'D': vec3(0, -1, 0) # Down (Y-)
|
|
52
62
|
}
|
|
53
63
|
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'L': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}ry:-90;m:x;z:-1.0;x:-1.0}}}},{{x:-1.0;ry:90;}}',
|
|
63
|
-
'U': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}rz:90;y:1.0;z:-1}}}},{{y:1.0;rx:90;}}',
|
|
64
|
-
'D': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}rz:-90;y:-1;z:-1}}}},{{y:-1.0;rx:-90;}}'
|
|
64
|
+
# Local coordinate system direction definitions
|
|
65
|
+
local_directions = {
|
|
66
|
+
'F': vec3(0, 0, 1), # Forward (local Z+)
|
|
67
|
+
'B': vec3(0, 0, -1), # Backward (local Z-)
|
|
68
|
+
'R': vec3(1, 0, 0), # Right (local X+)
|
|
69
|
+
'L': vec3(-1, 0, 0), # Left (local X-)
|
|
70
|
+
'U': vec3(0, 1, 0), # Up (local Y+)
|
|
71
|
+
'D': vec3(0, -1, 0) # Down (local Y-)
|
|
65
72
|
}
|
|
66
73
|
|
|
67
|
-
#
|
|
68
|
-
cur_c =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
# 遍历管道字符串中的每个字符
|
|
74
|
-
for move_char in world_pipe_str:
|
|
75
|
-
if move_char not in pipe_components:
|
|
76
|
-
print(f"警告: 未知的管道字符 '{move_char}',已跳过")
|
|
74
|
+
# Initialize local coordinate system
|
|
75
|
+
cur_c = start_c.Q()
|
|
76
|
+
local_pipe_str = ""
|
|
77
|
+
|
|
78
|
+
for i, move in enumerate(world_pipe_str):
|
|
79
|
+
if move not in directions:
|
|
77
80
|
continue
|
|
78
|
-
|
|
79
|
-
#
|
|
80
|
-
world_dir =
|
|
81
|
-
|
|
82
|
-
#
|
|
83
|
-
local_dir =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
world_dir.dot(cur_c.uz) # 在局部Z轴的分量
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
# 找到绝对值最大的分量来确定主要移动方向
|
|
81
|
+
|
|
82
|
+
# Get movement direction vector in world coordinate system
|
|
83
|
+
world_dir = directions[move]
|
|
84
|
+
|
|
85
|
+
# Transform world direction vector to current local coordinate system
|
|
86
|
+
local_dir = world_dir / cur_c
|
|
87
|
+
|
|
88
|
+
# Find the component with largest absolute value to determine primary movement direction
|
|
90
89
|
abs_components = [abs(local_dir.x), abs(local_dir.y), abs(local_dir.z)]
|
|
91
90
|
max_idx = abs_components.index(max(abs_components))
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
if max_idx == 0: # X
|
|
95
|
-
local_move = '
|
|
96
|
-
elif max_idx == 1: # Y
|
|
91
|
+
|
|
92
|
+
# Determine movement direction based on the largest component
|
|
93
|
+
if max_idx == 0: # X-axis
|
|
94
|
+
local_move = 'L' if local_dir.x > 0 else 'R'
|
|
95
|
+
elif max_idx == 1: # Y-axis
|
|
97
96
|
local_move = 'U' if local_dir.y > 0 else 'D'
|
|
98
|
-
else: # Z
|
|
99
|
-
local_move = 'F' if local_dir.z > 0 else 'B'
|
|
100
|
-
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
# 后退:沿局部Z轴负方向移动1.0单位
|
|
110
|
-
cur_c = cur_c * coord3(vec3(0, 0, -1.0))
|
|
111
|
-
elif local_move == 'R':
|
|
112
|
-
# 右转:绕Y轴旋转-90度,然后沿X轴移动1.0单位
|
|
97
|
+
else: # Z-axis
|
|
98
|
+
local_move = 'F' if local_dir.z > 0 else 'B' # NO BACKWARD!
|
|
99
|
+
|
|
100
|
+
# Debug first 8 characters
|
|
101
|
+
if i < 8:
|
|
102
|
+
print(f" [{i}] world:'{move}' → local_dir:({local_dir.x:.2f},{local_dir.y:.2f},{local_dir.z:.2f}) → local:'{local_move}', uz:({cur_c.uz.x:.2f},{cur_c.uz.y:.2f},{cur_c.uz.z:.2f})")
|
|
103
|
+
|
|
104
|
+
local_pipe_str += local_move
|
|
105
|
+
|
|
106
|
+
# Update local coordinate system (when turning)
|
|
107
|
+
if local_move == 'R':
|
|
113
108
|
rotation = quat(-3.1416 / 2, cur_c.uy)
|
|
114
109
|
cur_c = cur_c * rotation
|
|
115
|
-
cur_c = cur_c * coord3(vec3(1.0, 0, 0))
|
|
116
110
|
elif local_move == 'L':
|
|
117
|
-
# 左转:绕Y轴旋转90度,然后沿X轴移动1.0单位
|
|
118
111
|
rotation = quat(3.1416 / 2, cur_c.uy)
|
|
119
112
|
cur_c = cur_c * rotation
|
|
120
|
-
cur_c = cur_c * coord3(vec3(-1.0, 0, 0))
|
|
121
113
|
elif local_move == 'U':
|
|
122
|
-
|
|
123
|
-
rotation = quat(3.1416 / 2, cur_c.ux)
|
|
114
|
+
rotation = quat(3.1416 / 2, -cur_c.ux)
|
|
124
115
|
cur_c = cur_c * rotation
|
|
125
|
-
cur_c = cur_c * coord3(vec3(0, 1.0, 0))
|
|
126
116
|
elif local_move == 'D':
|
|
127
|
-
|
|
128
|
-
rotation = quat(-3.1416 / 2, cur_c.ux)
|
|
117
|
+
rotation = quat(-3.1416 / 2, -cur_c.ux)
|
|
129
118
|
cur_c = cur_c * rotation
|
|
130
|
-
|
|
119
|
+
|
|
120
|
+
return local_pipe_str
|
|
131
121
|
|
|
132
|
-
|
|
133
|
-
inner_script = ',\n'.join(script_parts)
|
|
134
|
-
|
|
135
|
-
# 获取起始坐标系的四元数
|
|
136
|
-
q = start_c.Q()
|
|
137
|
-
|
|
138
|
-
# 构建完整的PHG脚本
|
|
139
|
-
complete_script = f"""{{
|
|
140
|
-
{{xyz:{start_c.o.x},{start_c.o.y},{start_c.o.z};q:{q.w},{q.x},{q.y},{q.z};s:0.5;
|
|
141
|
-
<{inner_script}>}}
|
|
142
|
-
}}"""
|
|
143
|
-
|
|
144
|
-
return complete_script
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def local_pipe_to_phg(local_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
|
|
122
|
+
def local_pipe_to_phg(local_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
|
|
148
123
|
"""
|
|
149
|
-
|
|
124
|
+
Convert local coordinate system pipe string to PHG script
|
|
150
125
|
|
|
151
|
-
|
|
152
|
-
local_pipe_str:
|
|
153
|
-
start_c:
|
|
154
|
-
pipe_color:
|
|
155
|
-
pipe_radius:
|
|
126
|
+
Parameters:
|
|
127
|
+
local_pipe_str: Local coordinate pipe string (e.g., "FFRUD")
|
|
128
|
+
start_c: Starting coordinate system
|
|
129
|
+
pipe_color: Pipe color as (R, G, B) tuple
|
|
130
|
+
pipe_radius: Pipe radius
|
|
156
131
|
|
|
157
|
-
|
|
158
|
-
PHG
|
|
132
|
+
Returns:
|
|
133
|
+
PHG script string
|
|
159
134
|
"""
|
|
160
135
|
|
|
161
|
-
#
|
|
136
|
+
# Parse color
|
|
162
137
|
r, g, b = pipe_color
|
|
163
138
|
|
|
164
|
-
#
|
|
139
|
+
# Pipe component mapping
|
|
165
140
|
pipe_components = {
|
|
166
141
|
'F': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:90;z:-0.5;}};z:1.0}}',
|
|
167
|
-
'B': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:-90;z
|
|
142
|
+
'B': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:-90;z:-1.5;}};z:-1.0}}',
|
|
168
143
|
'R': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}ry:90;x:1.0;z:-1.0}}}},{{x:1.0;ry:-90;}}',
|
|
169
144
|
'L': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}ry:-90;m:x;z:-1.0;x:-1.0}}}},{{x:-1.0;ry:90;}}',
|
|
170
145
|
'U': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}rz:90;y:1.0;z:-1}}}},{{y:1.0;rx:90;}}',
|
|
171
146
|
'D': f'{{{{{{rgb:{r},{g},{b};md:elbow 90 0.5 {pipe_radius};x:0.5;z:0.5;}}rz:-90;y:-1;z:-1}}}},{{y:-1.0;rx:-90;}}'
|
|
172
147
|
}
|
|
173
148
|
|
|
174
|
-
#
|
|
149
|
+
# Store all pipe component scripts
|
|
175
150
|
script_parts = []
|
|
176
151
|
|
|
177
|
-
#
|
|
152
|
+
# Iterate through each character in pipe string
|
|
178
153
|
for move_char in local_pipe_str:
|
|
179
154
|
if move_char not in pipe_components:
|
|
180
|
-
print(f"
|
|
155
|
+
print(f"Warning: Unknown pipe character '{move_char}', skipped")
|
|
181
156
|
continue
|
|
182
157
|
|
|
183
|
-
#
|
|
158
|
+
# Directly use local coordinate system movement commands
|
|
184
159
|
script_parts.append(pipe_components[move_char])
|
|
185
160
|
|
|
186
|
-
#
|
|
161
|
+
# Combine all pipe component scripts
|
|
187
162
|
inner_script = ',\n'.join(script_parts)
|
|
188
163
|
|
|
189
|
-
#
|
|
164
|
+
# Get quaternion of starting coordinate system
|
|
190
165
|
q = start_c.Q()
|
|
191
166
|
|
|
192
|
-
#
|
|
167
|
+
# Build complete PHG script
|
|
193
168
|
complete_script = f"""{{
|
|
194
169
|
{{xyz:{start_c.o.x},{start_c.o.y},{start_c.o.z};q:{q.w},{q.x},{q.y},{q.z};s:0.5;
|
|
195
170
|
<{inner_script}>}}
|
|
196
171
|
}}"""
|
|
197
172
|
|
|
198
|
-
return complete_script
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def
|
|
173
|
+
return complete_script
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def world_pipe_to_phg(world_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
|
|
177
|
+
"""
|
|
178
|
+
Convert world coordinate pipe string to PHG script.
|
|
179
|
+
|
|
180
|
+
Parameters:
|
|
181
|
+
world_pipe_str: World coordinate pipe string (e.g., "NNEUD")
|
|
182
|
+
start_c: Starting coordinate system
|
|
183
|
+
pipe_color: Pipe color as (R, G, B) tuple
|
|
184
|
+
pipe_radius: Pipe radius
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
PHG script string
|
|
188
|
+
"""
|
|
189
|
+
local_pipe_str = world_to_local_pipe_str(world_pipe_str, start_c)
|
|
190
|
+
return local_pipe_to_phg(local_pipe_str, start_c, pipe_color, pipe_radius)
|
|
191
|
+
|
|
192
|
+
def world_pipestr_vis(world_pipe_strs, start_c=None, pipe_colors=None, pipe_radius=DEFAULT_PIPE_RADIUS):
|
|
202
193
|
"""
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
start_c:
|
|
208
|
-
|
|
209
|
-
pipe_radius:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
PHG
|
|
194
|
+
Direct visualization for world coordinate pipe strings with support for multiple pipes
|
|
195
|
+
|
|
196
|
+
Parameters:
|
|
197
|
+
world_pipe_strs: World coordinate pipe string or list of strings (e.g., "NNEUD" or ["NNE", "SSU"])
|
|
198
|
+
start_c: Starting coordinate system, defaults to origin
|
|
199
|
+
pipe_colors: Single color or list of colors as (R, G, B) tuples
|
|
200
|
+
pipe_radius: Pipe radius
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
PHG script string
|
|
213
204
|
"""
|
|
214
|
-
#
|
|
205
|
+
# Handle single string input
|
|
206
|
+
if isinstance(world_pipe_strs, str):
|
|
207
|
+
world_pipe_strs = [world_pipe_strs]
|
|
208
|
+
|
|
209
|
+
# Handle single color input
|
|
210
|
+
if pipe_colors is None:
|
|
211
|
+
pipe_colors = [DEFAULT_PIPE_COLOR] * len(world_pipe_strs)
|
|
212
|
+
elif isinstance(pipe_colors, tuple):
|
|
213
|
+
pipe_colors = [pipe_colors] * len(world_pipe_strs)
|
|
214
|
+
|
|
215
|
+
# Ensure colors list matches pipes list length
|
|
216
|
+
if len(pipe_colors) != len(world_pipe_strs):
|
|
217
|
+
pipe_colors = [DEFAULT_PIPE_COLOR] * len(world_pipe_strs)
|
|
218
|
+
print("Warning: Colors list length doesn't match pipes list, using default colors")
|
|
219
|
+
|
|
220
|
+
# Use default origin if no starting coordinate provided
|
|
215
221
|
if start_c is None:
|
|
216
222
|
start_c = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
|
|
217
223
|
|
|
218
|
-
#
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
224
|
+
# Generate PHG scripts for all pipes
|
|
225
|
+
script_parts = []
|
|
226
|
+
for i, (pipe_str, color) in enumerate(zip(world_pipe_strs, pipe_colors)):
|
|
227
|
+
# Convert world coordinate pipe string to local coordinate system first
|
|
228
|
+
local_pipe_str = world_to_local_pipe_str(pipe_str, start_c)
|
|
229
|
+
# Generate PHG script from local pipe string
|
|
230
|
+
phg_script = local_pipe_to_phg(local_pipe_str, start_c, color, pipe_radius)
|
|
231
|
+
# Extract inner content between outer braces
|
|
232
|
+
inner_content = phg_script.strip()[1:-1].strip()
|
|
233
|
+
script_parts.append(inner_content)
|
|
234
|
+
|
|
235
|
+
# Combine all pipe scripts
|
|
236
|
+
combined_script = "{\n" + ",\n".join(script_parts) + "\n}"
|
|
237
|
+
|
|
238
|
+
# Call visualization function
|
|
222
239
|
try:
|
|
223
|
-
|
|
224
|
-
|
|
240
|
+
phg.vis(combined_script)
|
|
241
|
+
print(f"Visualizing {len(world_pipe_strs)} world coordinate pipes (converted to local)")
|
|
225
242
|
except ImportError:
|
|
226
|
-
print("
|
|
243
|
+
print("Warning: Cannot import visualization module, returning PHG script")
|
|
227
244
|
|
|
228
|
-
return
|
|
245
|
+
return combined_script
|
|
229
246
|
|
|
230
|
-
|
|
231
|
-
def local_pipestr_vis(local_pipe_str, start_c=None, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
|
|
247
|
+
def local_pipestr_vis(local_pipe_strs, start_c=None, pipe_colors=None, pipe_radius=DEFAULT_PIPE_RADIUS):
|
|
232
248
|
"""
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
start_c:
|
|
238
|
-
|
|
239
|
-
pipe_radius:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
PHG
|
|
249
|
+
Direct visualization for local coordinate pipe strings with support for multiple pipes
|
|
250
|
+
|
|
251
|
+
Parameters:
|
|
252
|
+
local_pipe_strs: Local coordinate pipe string or list of strings (e.g., "FFRUD" or ["FFR", "LLU"])
|
|
253
|
+
start_c: Starting coordinate system, defaults to origin
|
|
254
|
+
pipe_colors: Single color or list of colors as (R, G, B) tuples
|
|
255
|
+
pipe_radius: Pipe radius
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
PHG script string
|
|
243
259
|
"""
|
|
244
|
-
#
|
|
260
|
+
# Handle single string input
|
|
261
|
+
if isinstance(local_pipe_strs, str):
|
|
262
|
+
local_pipe_strs = [local_pipe_strs]
|
|
263
|
+
|
|
264
|
+
# Handle single color input
|
|
265
|
+
if pipe_colors is None:
|
|
266
|
+
pipe_colors = [DEFAULT_PIPE_COLOR] * len(local_pipe_strs)
|
|
267
|
+
elif isinstance(pipe_colors, tuple):
|
|
268
|
+
pipe_colors = [pipe_colors] * len(local_pipe_strs)
|
|
269
|
+
|
|
270
|
+
# Ensure colors list matches pipes list length
|
|
271
|
+
if len(pipe_colors) != len(local_pipe_strs):
|
|
272
|
+
pipe_colors = [DEFAULT_PIPE_COLOR] * len(local_pipe_strs)
|
|
273
|
+
print("Warning: Colors list length doesn't match pipes list, using default colors")
|
|
274
|
+
|
|
275
|
+
# Use default origin if no starting coordinate provided
|
|
245
276
|
if start_c is None:
|
|
246
277
|
start_c = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
|
|
247
278
|
|
|
248
|
-
#
|
|
249
|
-
|
|
279
|
+
# Generate PHG scripts for all pipes
|
|
280
|
+
script_parts = []
|
|
281
|
+
for i, (pipe_str, color) in enumerate(zip(local_pipe_strs, pipe_colors)):
|
|
282
|
+
phg_script = local_pipe_to_phg(pipe_str, start_c, color, pipe_radius)
|
|
283
|
+
# Extract inner content between outer braces
|
|
284
|
+
inner_content = phg_script.strip()[1:-1].strip()
|
|
285
|
+
script_parts.append(inner_content)
|
|
286
|
+
|
|
287
|
+
# Combine all pipe scripts
|
|
288
|
+
combined_script = "{\n" + ",\n".join(script_parts) + "\n}"
|
|
250
289
|
|
|
251
|
-
#
|
|
290
|
+
# Call visualization function
|
|
252
291
|
try:
|
|
253
|
-
|
|
254
|
-
|
|
292
|
+
phg.vis(combined_script)
|
|
293
|
+
print(f"Visualizing {len(local_pipe_strs)} local coordinate pipes")
|
|
255
294
|
except ImportError:
|
|
256
|
-
print("
|
|
295
|
+
print("Warning: Cannot import visualization module, returning PHG script")
|
|
257
296
|
|
|
258
|
-
return
|
|
297
|
+
return combined_script
|
|
259
298
|
|
|
299
|
+
def multiple_pipes_vis(pipe_configs, coordinate_system='world'):
|
|
300
|
+
"""
|
|
301
|
+
Advanced visualization for multiple pipes with individual configurations
|
|
302
|
+
|
|
303
|
+
Parameters:
|
|
304
|
+
pipe_configs: List of pipe configuration dictionaries with keys:
|
|
305
|
+
- 'pipe_str': Pipe string (required)
|
|
306
|
+
- 'start_c': Starting coordinate (optional, defaults to origin)
|
|
307
|
+
- 'color': Pipe color (optional, defaults to DEFAULT_PIPE_COLOR)
|
|
308
|
+
- 'radius': Pipe radius (optional, defaults to DEFAULT_PIPE_RADIUS)
|
|
309
|
+
coordinate_system: 'world' or 'local' coordinate system
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
PHG script string
|
|
313
|
+
"""
|
|
314
|
+
script_parts = []
|
|
315
|
+
|
|
316
|
+
for i, config in enumerate(pipe_configs):
|
|
317
|
+
pipe_str = config.get('pipe_str')
|
|
318
|
+
start_c = config.get('start_c', coord3(vec3(0, 0, 0), quat(1, 0, 0, 0)))
|
|
319
|
+
color = config.get('color', DEFAULT_PIPE_COLOR)
|
|
320
|
+
radius = config.get('radius', DEFAULT_PIPE_RADIUS)
|
|
321
|
+
|
|
322
|
+
if coordinate_system.lower() == 'world':
|
|
323
|
+
# Convert world coordinate pipe string to local coordinate system first
|
|
324
|
+
local_pipe_str = world_to_local_pipe_str(pipe_str, start_c)
|
|
325
|
+
phg_script = local_pipe_to_phg(local_pipe_str, start_c, color, radius)
|
|
326
|
+
else:
|
|
327
|
+
# Use local coordinate pipe string directly
|
|
328
|
+
phg_script = local_pipe_to_phg(pipe_str, start_c, color, radius)
|
|
329
|
+
|
|
330
|
+
# Extract inner content
|
|
331
|
+
inner_content = phg_script.strip()[1:-1].strip()
|
|
332
|
+
script_parts.append(inner_content)
|
|
333
|
+
|
|
334
|
+
# Combine all pipe scripts
|
|
335
|
+
combined_script = "{\n" + ",\n".join(script_parts) + "\n}"
|
|
336
|
+
|
|
337
|
+
# Call visualization
|
|
338
|
+
try:
|
|
339
|
+
phg.vis(combined_script)
|
|
340
|
+
print(f"Visualizing {len(pipe_configs)} pipes in {coordinate_system} coordinate system")
|
|
341
|
+
except ImportError:
|
|
342
|
+
print("Warning: Cannot import visualization module, returning PHG script")
|
|
343
|
+
|
|
344
|
+
return combined_script
|
|
260
345
|
|
|
261
|
-
#
|
|
346
|
+
# Usage Examples
|
|
262
347
|
if __name__ == "__main__":
|
|
263
|
-
#
|
|
348
|
+
# Create starting coordinate system (example)
|
|
264
349
|
start_coord = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
|
|
265
350
|
|
|
266
|
-
#
|
|
267
|
-
example_world_pipe = "
|
|
268
|
-
print("
|
|
269
|
-
|
|
270
|
-
|
|
351
|
+
# Example 1: World coordinate pipe string visualization
|
|
352
|
+
example_world_pipe = "NNEUD" # North twice, east, up, down
|
|
353
|
+
print("World Coordinate Pipe Example:")
|
|
354
|
+
print(f"Original world pipe: '{example_world_pipe}'")
|
|
355
|
+
|
|
356
|
+
# Convert to local coordinate system
|
|
357
|
+
local_pipe_str = world_to_local_pipe_str(example_world_pipe, start_coord)
|
|
358
|
+
print(f"Converted to local: '{local_pipe_str}'")
|
|
359
|
+
|
|
360
|
+
# Generate PHG script
|
|
361
|
+
phg_script = local_pipe_to_phg(local_pipe_str, start_coord)
|
|
362
|
+
print("Generated PHG Script:")
|
|
271
363
|
print(phg_script)
|
|
272
364
|
print()
|
|
273
365
|
|
|
274
|
-
#
|
|
275
|
-
example_local_pipe = "FFRUD" #
|
|
276
|
-
print("
|
|
366
|
+
# Example 2: Single local coordinate pipe string
|
|
367
|
+
example_local_pipe = "FFRUD" # Movements in local coordinate system
|
|
368
|
+
print("Local Coordinate Pipe Example:")
|
|
277
369
|
phg_script = local_pipe_to_phg(example_local_pipe, start_coord)
|
|
278
|
-
print("
|
|
370
|
+
print("Generated PHG Script:")
|
|
279
371
|
print(phg_script)
|
|
280
372
|
print()
|
|
281
373
|
|
|
282
|
-
#
|
|
283
|
-
print("
|
|
284
|
-
|
|
285
|
-
#
|
|
374
|
+
# Example 3: Multiple pipes visualization
|
|
375
|
+
print("Multiple Pipes Visualization Example:")
|
|
376
|
+
|
|
377
|
+
# Multiple world coordinate pipes with different colors
|
|
378
|
+
world_pipes = ["NNE", "SSU", "EEW"]
|
|
379
|
+
world_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] # Red, Green, Blue
|
|
380
|
+
world_pipestr_vis(world_pipes, start_coord, world_colors)
|
|
381
|
+
print()
|
|
382
|
+
|
|
383
|
+
# Multiple local coordinate pipes
|
|
384
|
+
local_pipes = ["FFR", "BBL", "UUD"]
|
|
385
|
+
local_colors = [(255, 255, 0), (255, 0, 255), (0, 255, 255)] # Yellow, Magenta, Cyan
|
|
386
|
+
local_pipestr_vis(local_pipes, start_coord, local_colors)
|
|
387
|
+
print()
|
|
388
|
+
|
|
389
|
+
# Example 4: Advanced multiple pipes configuration
|
|
390
|
+
print("Advanced Multiple Pipes Configuration:")
|
|
391
|
+
pipe_configs = [
|
|
392
|
+
{
|
|
393
|
+
'pipe_str': 'NNE',
|
|
394
|
+
'start_c': coord3(vec3(0, 0, 0), quat(1, 0, 0, 0)),
|
|
395
|
+
'color': (255, 100, 100),
|
|
396
|
+
'radius': 0.4
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
'pipe_str': 'SSU',
|
|
400
|
+
'start_c': coord3(vec3(5, 0, 0), quat(1, 0, 0, 0)),
|
|
401
|
+
'color': (100, 255, 100),
|
|
402
|
+
'radius': 0.3
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
'pipe_str': 'FFR', # Local coordinate pipe
|
|
406
|
+
'start_c': coord3(vec3(0, 5, 0), quat(1, 0, 0, 0)),
|
|
407
|
+
'color': (100, 100, 255),
|
|
408
|
+
'radius': 0.2
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
|
|
412
|
+
# Visualize with mixed coordinate systems
|
|
413
|
+
multiple_pipes_vis(pipe_configs, 'world') # First two are world, third is local but will be treated as world
|
|
414
|
+
print()
|
|
415
|
+
|
|
416
|
+
# Example 5: Explicit coordinate system specification
|
|
417
|
+
print("Explicit Coordinate System Example:")
|
|
418
|
+
world_configs = [
|
|
419
|
+
{
|
|
420
|
+
'pipe_str': 'NNE',
|
|
421
|
+
'start_c': coord3(vec3(0, 0, 0), quat(1, 0, 0, 0)),
|
|
422
|
+
'color': (255, 0, 0),
|
|
423
|
+
'radius': 0.3
|
|
424
|
+
}
|
|
425
|
+
]
|
|
426
|
+
|
|
427
|
+
local_configs = [
|
|
428
|
+
{
|
|
429
|
+
'pipe_str': 'FFR',
|
|
430
|
+
'start_c': coord3(vec3(3, 0, 0), quat(1, 0, 0, 0)),
|
|
431
|
+
'color': (0, 255, 0),
|
|
432
|
+
'radius': 0.3
|
|
433
|
+
}
|
|
434
|
+
]
|
|
435
|
+
|
|
436
|
+
# Visualize world coordinate pipe
|
|
437
|
+
world_result = multiple_pipes_vis(world_configs, 'world')
|
|
438
|
+
# Visualize local coordinate pipe
|
|
439
|
+
local_result = multiple_pipes_vis(local_configs, 'local')
|