phg-vis 1.3.1__py3-none-any.whl → 1.3.2__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 CHANGED
@@ -8,9 +8,10 @@ Main Features:
8
8
  - PHG script visualization via vis.exe
9
9
  - Shader-based rendering with GLSL conversion
10
10
  - Pipe system visualization with world/local coordinate systems
11
+ - Multiple pipe visualization support
11
12
  - Real-time and image rendering capabilities
12
13
 
13
- Version: 0.2.0
14
+ Version: 1.3.1
14
15
  Author: PanGuoJun
15
16
  License: MIT
16
17
  """
@@ -22,7 +23,8 @@ from .pipe_string_phg import (
22
23
  world_pipe_to_phg,
23
24
  local_pipe_to_phg,
24
25
  world_pipestr_vis,
25
- local_pipestr_vis
26
+ local_pipestr_vis,
27
+ multiple_pipes_vis
26
28
  )
27
29
 
28
30
  # Extend ShaderRenderer class to support direct PHG rendering
@@ -79,6 +81,211 @@ def convert_phg_to_shader(phg_script: str) -> str:
79
81
  """
80
82
  return phg_to_shader(phg_script)
81
83
 
84
+ def visualize_pipe_variants(pipe_variants, start_position=None, colors=None, coordinate_system='world'):
85
+ """
86
+ Visualize multiple pipe variants for comparison
87
+
88
+ Parameters:
89
+ pipe_variants: List of pipe strings or configuration dictionaries
90
+ start_position: Starting coordinate (optional)
91
+ colors: List of colors for each pipe variant
92
+ coordinate_system: 'world' or 'local' coordinate system
93
+
94
+ Returns:
95
+ PHG script string
96
+ """
97
+ from coordinate_system import vec3, quat, coord3
98
+
99
+ # Handle start position
100
+ if start_position is None:
101
+ start_c = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
102
+ else:
103
+ start_c = start_position
104
+
105
+ # Handle different input formats
106
+ if isinstance(pipe_variants[0], str):
107
+ # Simple list of pipe strings
108
+ if colors is None:
109
+ # Generate distinct colors for each variant
110
+ import colorsys
111
+ colors = []
112
+ for i in range(len(pipe_variants)):
113
+ hue = i / len(pipe_variants)
114
+ rgb = colorsys.hsv_to_rgb(hue, 0.8, 0.9)
115
+ colors.append(tuple(int(c * 255) for c in rgb))
116
+
117
+ if coordinate_system == 'world':
118
+ return world_pipestr_vis(pipe_variants, start_c, colors)
119
+ else:
120
+ return local_pipestr_vis(pipe_variants, start_c, colors)
121
+
122
+ else:
123
+ # List of configuration dictionaries
124
+ pipe_configs = []
125
+ for i, variant in enumerate(pipe_variants):
126
+ if isinstance(variant, str):
127
+ config = {
128
+ 'pipe_str': variant,
129
+ 'start_c': start_c,
130
+ 'color': colors[i] if colors else None,
131
+ 'radius': 0.3
132
+ }
133
+ else:
134
+ config = variant
135
+ if 'start_c' not in config:
136
+ config['start_c'] = start_c
137
+
138
+ pipe_configs.append(config)
139
+
140
+ return multiple_pipes_vis(pipe_configs, coordinate_system)
141
+
142
+ def create_pipe_comparison_grid(pipe_strings, grid_size=(2, 2), start_position=None,
143
+ base_color=(0, 55, 255), coordinate_system='world'):
144
+ """
145
+ Create a grid layout for comparing multiple pipe paths
146
+
147
+ Parameters:
148
+ pipe_strings: List of pipe strings to compare
149
+ grid_size: (rows, cols) for grid layout
150
+ start_position: Base starting position
151
+ base_color: Base color for pipes
152
+ coordinate_system: 'world' or 'local'
153
+
154
+ Returns:
155
+ PHG script string
156
+ """
157
+ from coordinate_system import vec3, quat, coord3
158
+
159
+ if start_position is None:
160
+ start_position = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
161
+
162
+ rows, cols = grid_size
163
+ spacing = 5.0 # Space between pipes in grid
164
+
165
+ pipe_configs = []
166
+
167
+ for i, pipe_str in enumerate(pipe_strings):
168
+ if i >= rows * cols:
169
+ break
170
+
171
+ row = i // cols
172
+ col = i % cols
173
+
174
+ # Calculate position in grid
175
+ x_offset = col * spacing
176
+ z_offset = row * spacing
177
+
178
+ # Create individual start position for this pipe
179
+ individual_start = coord3(
180
+ vec3(
181
+ start_position.o.x + x_offset,
182
+ start_position.o.y,
183
+ start_position.o.z + z_offset
184
+ ),
185
+ start_position.Q()
186
+ )
187
+
188
+ # Generate color variation
189
+ color_variation = (
190
+ min(255, base_color[0] + (i * 30) % 100),
191
+ min(255, base_color[1] + (i * 50) % 100),
192
+ min(255, base_color[2] + (i * 70) % 100)
193
+ )
194
+
195
+ pipe_configs.append({
196
+ 'pipe_str': pipe_str,
197
+ 'start_c': individual_start,
198
+ 'color': color_variation,
199
+ 'radius': 0.25 + (i * 0.05) # Vary radius slightly
200
+ })
201
+
202
+ return multiple_pipes_vis(pipe_configs, coordinate_system)
203
+
204
+ def generate_pipe_variants_from_rules(base_pipe, num_variants=5, apply_rules=None):
205
+ """
206
+ Generate pipe variants using transformation rules
207
+
208
+ Parameters:
209
+ base_pipe: Base pipe string
210
+ num_variants: Number of variants to generate
211
+ apply_rules: List of rules to apply ('swap', 'insert', 'cancel')
212
+
213
+ Returns:
214
+ List of pipe variant strings
215
+ """
216
+ if apply_rules is None:
217
+ apply_rules = ['swap', 'insert', 'cancel']
218
+
219
+ variants = [base_pipe]
220
+
221
+ # Import the pipe transformer if available
222
+ try:
223
+ from .pipe_string_phg import PipeStringTransformer
224
+ transformer = PipeStringTransformer()
225
+
226
+ for _ in range(num_variants - 1):
227
+ current_pipe = base_pipe
228
+
229
+ # Apply random transformations
230
+ import random
231
+ for _ in range(random.randint(1, 3)):
232
+ rule = random.choice(apply_rules)
233
+
234
+ if rule == 'swap' and len(current_pipe) >= 2:
235
+ i, j = random.sample(range(len(current_pipe)), 2)
236
+ current_pipe = transformer.swap_positions(current_pipe, i, j)
237
+
238
+ elif rule == 'insert':
239
+ position = random.randint(0, len(current_pipe))
240
+ direction = random.choice(list(transformer.CANCEL_PAIRS.keys()))
241
+ current_pipe = transformer.insert_cancel_pair(current_pipe, position, direction)
242
+
243
+ elif rule == 'cancel':
244
+ current_pipe = transformer.cancel_adjacent_pairs(current_pipe)
245
+
246
+ # Simplify and add if valid
247
+ simplified = transformer.simplify_path(current_pipe)
248
+ if simplified not in variants:
249
+ variants.append(simplified)
250
+
251
+ except ImportError:
252
+ # Fallback: simple variant generation
253
+ import random
254
+ for i in range(num_variants - 1):
255
+ # Simple character shuffling
256
+ pipe_list = list(base_pipe)
257
+ random.shuffle(pipe_list)
258
+ variant = ''.join(pipe_list)
259
+ if variant not in variants:
260
+ variants.append(variant)
261
+
262
+ return variants[:num_variants]
263
+
264
+ # Enhanced pipe visualization with transformation support
265
+ def visualize_pipe_with_transformations(pipe_string, start_position=None,
266
+ transformations=None, show_variants=3):
267
+ """
268
+ Visualize a pipe string along with its transformed variants
269
+
270
+ Parameters:
271
+ pipe_string: Base pipe string
272
+ start_position: Starting coordinate
273
+ transformations: List of transformation rules to apply
274
+ show_variants: Number of variants to show
275
+
276
+ Returns:
277
+ PHG script string
278
+ """
279
+ # Generate variants
280
+ variants = generate_pipe_variants_from_rules(
281
+ pipe_string,
282
+ num_variants=show_variants + 1, # +1 for original
283
+ apply_rules=transformations
284
+ )
285
+
286
+ # Create comparison visualization
287
+ return visualize_pipe_variants(variants, start_position)
288
+
82
289
  __all__ = [
83
290
  # Core visualization functions
84
291
  'vis',
@@ -100,6 +307,13 @@ __all__ = [
100
307
  'local_pipe_to_phg',
101
308
  'world_pipestr_vis',
102
309
  'local_pipestr_vis',
310
+ 'multiple_pipes_vis',
311
+
312
+ # Enhanced pipe visualization
313
+ 'visualize_pipe_variants',
314
+ 'create_pipe_comparison_grid',
315
+ 'generate_pipe_variants_from_rules',
316
+ 'visualize_pipe_with_transformations',
103
317
  ]
104
318
 
105
319
  __version__ = "1.3.1"
@@ -109,5 +323,7 @@ __description__ = "Python Hypergraphics Library"
109
323
  # Package initialization information
110
324
  print(f"PHG {__version__} - {__description__}")
111
325
  print("[OK] Visualization module loaded")
112
- print("[OK] Shader converter loaded")
113
- print("[OK] Pipe visualization loaded")
326
+ print("[OK] Shader converter loaded")
327
+ print("[OK] Pipe visualization loaded")
328
+ print("[OK] Multiple pipe visualization support loaded")
329
+ print("[OK] Pipe transformation utilities loaded")
phg/pipe_string_phg.py CHANGED
@@ -2,59 +2,59 @@
2
2
  Pipe String to PHG Converter
3
3
  ============================
4
4
 
5
- 该模块提供了管道字符串转换为PHGPython Graphics)脚本的功能。
6
- 支持世界坐标系和局部坐标系两种管道描述方式。
7
-
8
- 主要功能:
9
- - world_pipe_to_phg: 世界坐标系管道转换
10
- - local_pipe_to_phg: 局部坐标系管道转换
11
- - world_pipestr_vis: 世界坐标系管道直接可视化
12
- - local_pipestr_vis: 局部坐标系管道直接可视化
13
-
14
- 管道字符串格式:
15
- - F: 前进 (Forward)
16
- - B: 后退 (Back)
17
- - R: 右转 (Right)
18
- - L: 左转 (Left)
19
- - U: 上转 (Up)
20
- - D: 下转 (Down)
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
+ - world_pipe_to_phg: World coordinate system pipe conversion
10
+ - local_pipe_to_phg: Local coordinate system pipe conversion
11
+ - world_pipestr_vis: Direct visualization for world coordinate pipes
12
+ - local_pipestr_vis: Direct visualization for local coordinate pipes
13
+
14
+ Pipe String Format:
15
+ - F: Forward
16
+ - B: Backward
17
+ - R: Right
18
+ - L: Left
19
+ - U: Up
20
+ - D: Down
21
21
  """
22
22
 
23
23
  import phg
24
24
  from coordinate_system import vec3, quat, coord3
25
25
 
26
- # 默认颜色和管径
26
+ # Default color and pipe radius
27
27
  DEFAULT_PIPE_COLOR = (0, 55, 255)
28
28
  DEFAULT_PIPE_RADIUS = 0.3
29
29
 
30
30
  def world_pipe_to_phg(world_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
31
31
  """
32
- 将世界坐标系下的管道字符串转换为PHG脚本
32
+ Convert world coordinate system pipe string to PHG script
33
33
 
34
- 参数:
35
- world_pipe_str: 世界坐标系管道字符串(如 "FFRUD"
36
- start_c: 起始坐标系
37
- pipe_color: 管道颜色,格式为(R, G, B)元组
38
- pipe_radius: 管道半径
34
+ Parameters:
35
+ world_pipe_str: World coordinate pipe string (e.g., "FFRUD")
36
+ start_c: Starting coordinate system
37
+ pipe_color: Pipe color as (R, G, B) tuple
38
+ pipe_radius: Pipe radius
39
39
 
40
- 返回:
41
- PHG脚本字符串
40
+ Returns:
41
+ PHG script string
42
42
  """
43
43
 
44
- # 世界坐标系方向定义
44
+ # World coordinate direction definitions
45
45
  world_directions = {
46
- 'F': vec3(0, 0, 1), # 前(世界Z+)
47
- 'B': vec3(0, 0, -1), # 后(世界Z-)
48
- 'R': vec3(1, 0, 0), # 右(世界X+)
49
- 'L': vec3(-1, 0, 0), # 左(世界X-)
50
- 'U': vec3(0, 1, 0), # 上(世界Y+)
51
- 'D': vec3(0, -1, 0) # 下(世界Y-)
46
+ 'F': vec3(0, 0, 1), # Forward (World Z+)
47
+ 'B': vec3(0, 0, -1), # Backward (World Z-)
48
+ 'R': vec3(1, 0, 0), # Right (World X+)
49
+ 'L': vec3(-1, 0, 0), # Left (World X-)
50
+ 'U': vec3(0, 1, 0), # Up (World Y+)
51
+ 'D': vec3(0, -1, 0) # Down (World Y-)
52
52
  }
53
53
 
54
- # 解析颜色
54
+ # Parse color
55
55
  r, g, b = pipe_color
56
56
 
57
- # 管道部件映射(所有部件使用固定长度1.0
57
+ # Pipe component mapping (all components use fixed length 1.0)
58
58
  pipe_components = {
59
59
  'F': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:90;z:-0.5;}};z:1.0}}',
60
60
  'B': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:-90;z:{-1.0-0.5};}};z:1.0}}',
@@ -64,78 +64,78 @@ def world_pipe_to_phg(world_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pi
64
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;}}'
65
65
  }
66
66
 
67
- # 初始化当前坐标系(使用起始坐标系)
67
+ # Initialize current coordinate system (using starting coordinate)
68
68
  cur_c = coord3(start_c.o, start_c.Q())
69
69
 
70
- # 存储所有管道部件的脚本
70
+ # Store all pipe component scripts
71
71
  script_parts = []
72
72
 
73
- # 遍历管道字符串中的每个字符
73
+ # Iterate through each character in pipe string
74
74
  for move_char in world_pipe_str:
75
75
  if move_char not in pipe_components:
76
- print(f"警告: 未知的管道字符 '{move_char}',已跳过")
76
+ print(f"Warning: Unknown pipe character '{move_char}', skipped")
77
77
  continue
78
78
 
79
- # 获取当前移动在世界坐标系中的方向
79
+ # Get current movement direction in world coordinates
80
80
  world_dir = world_directions[move_char]
81
81
 
82
- # 将世界方向转换到当前局部坐标系
82
+ # Transform world direction to current local coordinate system
83
83
  local_dir = vec3(
84
- world_dir.dot(cur_c.ux), # 在局部X轴的分量
85
- world_dir.dot(cur_c.uy), # 在局部Y轴的分量
86
- world_dir.dot(cur_c.uz) # 在局部Z轴的分量
84
+ world_dir.dot(cur_c.ux), # Component in local X-axis
85
+ world_dir.dot(cur_c.uy), # Component in local Y-axis
86
+ world_dir.dot(cur_c.uz) # Component in local Z-axis
87
87
  )
88
88
 
89
- # 找到绝对值最大的分量来确定主要移动方向
89
+ # Find component with largest absolute value to determine main movement direction
90
90
  abs_components = [abs(local_dir.x), abs(local_dir.y), abs(local_dir.z)]
91
91
  max_idx = abs_components.index(max(abs_components))
92
92
 
93
- # 根据最大分量确定局部移动方向
94
- if max_idx == 0: # X
93
+ # Determine local movement direction based on maximum component
94
+ if max_idx == 0: # X-axis
95
95
  local_move = 'R' if local_dir.x > 0 else 'L'
96
- elif max_idx == 1: # Y
96
+ elif max_idx == 1: # Y-axis
97
97
  local_move = 'U' if local_dir.y > 0 else 'D'
98
- else: # Z
98
+ else: # Z-axis
99
99
  local_move = 'F' if local_dir.z > 0 else 'B'
100
100
 
101
- # 添加对应的管道部件脚本
101
+ # Add corresponding pipe component script
102
102
  script_parts.append(pipe_components[local_move])
103
103
 
104
- # 更新当前坐标系(模拟移动后的新位置和方向)
104
+ # Update current coordinate system (simulate new position and direction after movement)
105
105
  if local_move == 'F':
106
- # 前进:沿局部Z轴正方向移动1.0单位
106
+ # Forward: move 1.0 unit along local Z-axis positive direction
107
107
  cur_c = cur_c * coord3(vec3(0, 0, 1.0))
108
108
  elif local_move == 'B':
109
- # 后退:沿局部Z轴负方向移动1.0单位
109
+ # Backward: move 1.0 unit along local Z-axis negative direction
110
110
  cur_c = cur_c * coord3(vec3(0, 0, -1.0))
111
111
  elif local_move == 'R':
112
- # 右转:绕Y轴旋转-90度,然后沿X轴移动1.0单位
112
+ # Right turn: rotate -90 degrees around Y-axis, then move 1.0 unit along X-axis
113
113
  rotation = quat(-3.1416 / 2, cur_c.uy)
114
114
  cur_c = cur_c * rotation
115
115
  cur_c = cur_c * coord3(vec3(1.0, 0, 0))
116
116
  elif local_move == 'L':
117
- # 左转:绕Y轴旋转90度,然后沿X轴移动1.0单位
117
+ # Left turn: rotate 90 degrees around Y-axis, then move 1.0 unit along X-axis
118
118
  rotation = quat(3.1416 / 2, cur_c.uy)
119
119
  cur_c = cur_c * rotation
120
120
  cur_c = cur_c * coord3(vec3(-1.0, 0, 0))
121
121
  elif local_move == 'U':
122
- # 上转:绕X轴旋转90度,然后沿Y轴移动1.0单位
122
+ # Up turn: rotate 90 degrees around X-axis, then move 1.0 unit along Y-axis
123
123
  rotation = quat(3.1416 / 2, cur_c.ux)
124
124
  cur_c = cur_c * rotation
125
125
  cur_c = cur_c * coord3(vec3(0, 1.0, 0))
126
126
  elif local_move == 'D':
127
- # 下转:绕X轴旋转-90度,然后沿Y轴移动1.0单位
127
+ # Down turn: rotate -90 degrees around X-axis, then move 1.0 unit along Y-axis
128
128
  rotation = quat(-3.1416 / 2, cur_c.ux)
129
129
  cur_c = cur_c * rotation
130
130
  cur_c = cur_c * coord3(vec3(0, -1.0, 0))
131
131
 
132
- # 组合所有管道部件的脚本
132
+ # Combine all pipe component scripts
133
133
  inner_script = ',\n'.join(script_parts)
134
134
 
135
- # 获取起始坐标系的四元数
135
+ # Get quaternion of starting coordinate system
136
136
  q = start_c.Q()
137
137
 
138
- # 构建完整的PHG脚本
138
+ # Build complete PHG script
139
139
  complete_script = f"""{{
140
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
141
  <{inner_script}>}}
@@ -146,22 +146,22 @@ def world_pipe_to_phg(world_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pi
146
146
 
147
147
  def local_pipe_to_phg(local_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
148
148
  """
149
- 将局部坐标系下的管道字符串转换为PHG脚本
149
+ Convert local coordinate system pipe string to PHG script
150
150
 
151
- 参数:
152
- local_pipe_str: 局部坐标系管道字符串(如 "FFRUD"
153
- start_c: 起始坐标系
154
- pipe_color: 管道颜色,格式为(R, G, B)元组
155
- pipe_radius: 管道半径
151
+ Parameters:
152
+ local_pipe_str: Local coordinate pipe string (e.g., "FFRUD")
153
+ start_c: Starting coordinate system
154
+ pipe_color: Pipe color as (R, G, B) tuple
155
+ pipe_radius: Pipe radius
156
156
 
157
- 返回:
158
- PHG脚本字符串
157
+ Returns:
158
+ PHG script string
159
159
  """
160
160
 
161
- # 解析颜色
161
+ # Parse color
162
162
  r, g, b = pipe_color
163
163
 
164
- # 管道部件映射(所有部件使用固定长度1.0
164
+ # Pipe component mapping (all components use fixed length 1.0)
165
165
  pipe_components = {
166
166
  'F': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:90;z:-0.5;}};z:1.0}}',
167
167
  'B': f'{{{{rgb:{r},{g},{b};md:cylinder {pipe_radius} 1.0;rx:-90;z:{-1.0-0.5};}};z:1.0}}',
@@ -171,25 +171,25 @@ def local_pipe_to_phg(local_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pi
171
171
  '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
172
  }
173
173
 
174
- # 存储所有管道部件的脚本
174
+ # Store all pipe component scripts
175
175
  script_parts = []
176
176
 
177
- # 遍历管道字符串中的每个字符
177
+ # Iterate through each character in pipe string
178
178
  for move_char in local_pipe_str:
179
179
  if move_char not in pipe_components:
180
- print(f"警告: 未知的管道字符 '{move_char}',已跳过")
180
+ print(f"Warning: Unknown pipe character '{move_char}', skipped")
181
181
  continue
182
182
 
183
- # 直接使用局部坐标系的移动命令
183
+ # Directly use local coordinate system movement commands
184
184
  script_parts.append(pipe_components[move_char])
185
185
 
186
- # 组合所有管道部件的脚本
186
+ # Combine all pipe component scripts
187
187
  inner_script = ',\n'.join(script_parts)
188
188
 
189
- # 获取起始坐标系的四元数
189
+ # Get quaternion of starting coordinate system
190
190
  q = start_c.Q()
191
191
 
192
- # 构建完整的PHG脚本
192
+ # Build complete PHG script
193
193
  complete_script = f"""{{
194
194
  {{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
195
  <{inner_script}>}}
@@ -198,88 +198,214 @@ def local_pipe_to_phg(local_pipe_str, start_c, pipe_color=DEFAULT_PIPE_COLOR, pi
198
198
  return complete_script
199
199
 
200
200
 
201
- def world_pipestr_vis(world_pipe_str, start_c=None, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
201
+ def world_pipestr_vis(world_pipe_strs, start_c=None, pipe_colors=None, pipe_radius=DEFAULT_PIPE_RADIUS):
202
202
  """
203
- 世界坐标系管道字符串直接可视化
204
-
205
- 参数:
206
- world_pipe_str: 世界坐标系管道字符串(如 "FFRUD"
207
- start_c: 起始坐标系,默认为原点
208
- pipe_color: 管道颜色,格式为(R, G, B)元组
209
- pipe_radius: 管道半径
210
-
211
- 返回:
212
- PHG脚本字符串
203
+ Direct visualization for world coordinate pipe strings with support for multiple pipes
204
+
205
+ Parameters:
206
+ world_pipe_strs: World coordinate pipe string or list of strings (e.g., "FFRUD" or ["FFR", "LLU"])
207
+ start_c: Starting coordinate system, defaults to origin
208
+ pipe_colors: Single color or list of colors as (R, G, B) tuples
209
+ pipe_radius: Pipe radius
210
+
211
+ Returns:
212
+ PHG script string
213
213
  """
214
- # 如果没有提供起始坐标系,使用默认原点
214
+ # Handle single string input
215
+ if isinstance(world_pipe_strs, str):
216
+ world_pipe_strs = [world_pipe_strs]
217
+
218
+ # Handle single color input
219
+ if pipe_colors is None:
220
+ pipe_colors = [DEFAULT_PIPE_COLOR] * len(world_pipe_strs)
221
+ elif isinstance(pipe_colors, tuple):
222
+ pipe_colors = [pipe_colors] * len(world_pipe_strs)
223
+
224
+ # Ensure colors list matches pipes list length
225
+ if len(pipe_colors) != len(world_pipe_strs):
226
+ pipe_colors = [DEFAULT_PIPE_COLOR] * len(world_pipe_strs)
227
+ print("Warning: Colors list length doesn't match pipes list, using default colors")
228
+
229
+ # Use default origin if no starting coordinate provided
215
230
  if start_c is None:
216
231
  start_c = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
217
232
 
218
- # 生成PHG脚本
219
- phg_script = world_pipe_to_phg(world_pipe_str, start_c, pipe_color, pipe_radius)
233
+ # Generate PHG scripts for all pipes
234
+ script_parts = []
235
+ for i, (pipe_str, color) in enumerate(zip(world_pipe_strs, pipe_colors)):
236
+ phg_script = world_pipe_to_phg(pipe_str, start_c, color, pipe_radius)
237
+ # Extract inner content between outer braces
238
+ inner_content = phg_script.strip()[1:-1].strip()
239
+ script_parts.append(inner_content)
220
240
 
221
- # 调用可视化函数
241
+ # Combine all pipe scripts
242
+ combined_script = "{\n" + ",\n".join(script_parts) + "\n}"
243
+
244
+ # Call visualization function
222
245
  try:
223
- from .visphg import vis
224
- vis(phg_script)
246
+ phg.vis(combined_script)
247
+ print(f"Visualizing {len(world_pipe_strs)} world coordinate pipes")
225
248
  except ImportError:
226
- print("警告: 无法导入可视化模块,返回PHG脚本")
249
+ print("Warning: Cannot import visualization module, returning PHG script")
227
250
 
228
- return phg_script
251
+ return combined_script
229
252
 
230
253
 
231
- def local_pipestr_vis(local_pipe_str, start_c=None, pipe_color=DEFAULT_PIPE_COLOR, pipe_radius=DEFAULT_PIPE_RADIUS):
254
+ def local_pipestr_vis(local_pipe_strs, start_c=None, pipe_colors=None, pipe_radius=DEFAULT_PIPE_RADIUS):
232
255
  """
233
- 局部坐标系管道字符串直接可视化
234
-
235
- 参数:
236
- local_pipe_str: 局部坐标系管道字符串(如 "FFRUD"
237
- start_c: 起始坐标系,默认为原点
238
- pipe_color: 管道颜色,格式为(R, G, B)元组
239
- pipe_radius: 管道半径
240
-
241
- 返回:
242
- PHG脚本字符串
256
+ Direct visualization for local coordinate pipe strings with support for multiple pipes
257
+
258
+ Parameters:
259
+ local_pipe_strs: Local coordinate pipe string or list of strings (e.g., "FFRUD" or ["FFR", "LLU"])
260
+ start_c: Starting coordinate system, defaults to origin
261
+ pipe_colors: Single color or list of colors as (R, G, B) tuples
262
+ pipe_radius: Pipe radius
263
+
264
+ Returns:
265
+ PHG script string
243
266
  """
244
- # 如果没有提供起始坐标系,使用默认原点
267
+ # Handle single string input
268
+ if isinstance(local_pipe_strs, str):
269
+ local_pipe_strs = [local_pipe_strs]
270
+
271
+ # Handle single color input
272
+ if pipe_colors is None:
273
+ pipe_colors = [DEFAULT_PIPE_COLOR] * len(local_pipe_strs)
274
+ elif isinstance(pipe_colors, tuple):
275
+ pipe_colors = [pipe_colors] * len(local_pipe_strs)
276
+
277
+ # Ensure colors list matches pipes list length
278
+ if len(pipe_colors) != len(local_pipe_strs):
279
+ pipe_colors = [DEFAULT_PIPE_COLOR] * len(local_pipe_strs)
280
+ print("Warning: Colors list length doesn't match pipes list, using default colors")
281
+
282
+ # Use default origin if no starting coordinate provided
245
283
  if start_c is None:
246
284
  start_c = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
247
285
 
248
- # 生成PHG脚本
249
- phg_script = local_pipe_to_phg(local_pipe_str, start_c, pipe_color, pipe_radius)
286
+ # Generate PHG scripts for all pipes
287
+ script_parts = []
288
+ for i, (pipe_str, color) in enumerate(zip(local_pipe_strs, pipe_colors)):
289
+ phg_script = local_pipe_to_phg(pipe_str, start_c, color, pipe_radius)
290
+ # Extract inner content between outer braces
291
+ inner_content = phg_script.strip()[1:-1].strip()
292
+ script_parts.append(inner_content)
293
+
294
+ # Combine all pipe scripts
295
+ combined_script = "{\n" + ",\n".join(script_parts) + "\n}"
250
296
 
251
- # 调用可视化函数
297
+ # Call visualization function
252
298
  try:
253
- from .visphg import vis
254
- vis(phg_script)
299
+ phg.vis(combined_script)
300
+ print(f"Visualizing {len(local_pipe_strs)} local coordinate pipes")
255
301
  except ImportError:
256
- print("警告: 无法导入可视化模块,返回PHG脚本")
302
+ print("Warning: Cannot import visualization module, returning PHG script")
257
303
 
258
- return phg_script
304
+ return combined_script
259
305
 
260
306
 
261
- # 使用示例
307
+ def multiple_pipes_vis(pipe_configs, coordinate_system='world'):
308
+ """
309
+ Advanced visualization for multiple pipes with individual configurations
310
+
311
+ Parameters:
312
+ pipe_configs: List of pipe configuration dictionaries with keys:
313
+ - 'pipe_str': Pipe string (required)
314
+ - 'start_c': Starting coordinate (optional, defaults to origin)
315
+ - 'color': Pipe color (optional, defaults to DEFAULT_PIPE_COLOR)
316
+ - 'radius': Pipe radius (optional, defaults to DEFAULT_PIPE_RADIUS)
317
+ coordinate_system: 'world' or 'local' coordinate system
318
+
319
+ Returns:
320
+ PHG script string
321
+ """
322
+ script_parts = []
323
+
324
+ for i, config in enumerate(pipe_configs):
325
+ pipe_str = config.get('pipe_str')
326
+ start_c = config.get('start_c', coord3(vec3(0, 0, 0), quat(1, 0, 0, 0)))
327
+ color = config.get('color', DEFAULT_PIPE_COLOR)
328
+ radius = config.get('radius', DEFAULT_PIPE_RADIUS)
329
+
330
+ if coordinate_system.lower() == 'world':
331
+ phg_script = world_pipe_to_phg(pipe_str, start_c, color, radius)
332
+ else:
333
+ phg_script = local_pipe_to_phg(pipe_str, start_c, color, radius)
334
+
335
+ # Extract inner content
336
+ inner_content = phg_script.strip()[1:-1].strip()
337
+ script_parts.append(inner_content)
338
+
339
+ # Combine all pipe scripts
340
+ combined_script = "{\n" + ",\n".join(script_parts) + "\n}"
341
+
342
+ # Call visualization
343
+ try:
344
+ phg.vis(combined_script)
345
+ print(f"Visualizing {len(pipe_configs)} pipes in {coordinate_system} coordinate system")
346
+ except ImportError:
347
+ print("Warning: Cannot import visualization module, returning PHG script")
348
+
349
+ return combined_script
350
+
351
+
352
+ # Usage Examples
262
353
  if __name__ == "__main__":
263
- # 创建起始坐标系(示例)
354
+ # Create starting coordinate system (example)
264
355
  start_coord = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
265
356
 
266
- # 示例1: 世界坐标系管道字符串
267
- example_world_pipe = "FFRUD" # 前进2次,右转,上转,下转
268
- print("世界坐标系管道示例:")
357
+ # Example 1: Single world coordinate pipe string
358
+ example_world_pipe = "FFRUD" # Forward twice, right, up, down
359
+ print("World Coordinate Pipe Example:")
269
360
  phg_script = world_pipe_to_phg(example_world_pipe, start_coord)
270
- print("生成的PHG脚本:")
361
+ print("Generated PHG Script:")
271
362
  print(phg_script)
272
363
  print()
273
364
 
274
- # 示例2: 局部坐标系管道字符串
275
- example_local_pipe = "FFRUD" # 在局部坐标系中的移动
276
- print("局部坐标系管道示例:")
365
+ # Example 2: Single local coordinate pipe string
366
+ example_local_pipe = "FFRUD" # Movements in local coordinate system
367
+ print("Local Coordinate Pipe Example:")
277
368
  phg_script = local_pipe_to_phg(example_local_pipe, start_coord)
278
- print("生成的PHG脚本:")
369
+ print("Generated PHG Script:")
279
370
  print(phg_script)
280
371
  print()
281
372
 
282
- # 示例3: 直接可视化
283
- print("直接可视化示例:")
284
- # world_pipestr_vis(example_world_pipe) # 世界坐标系可视化
285
- # local_pipestr_vis(example_local_pipe) # 局部坐标系可视化
373
+ # Example 3: Multiple pipes visualization
374
+ print("Multiple Pipes Visualization Example:")
375
+
376
+ # Multiple world coordinate pipes with different colors
377
+ world_pipes = ["FFR", "LLU", "RRD"]
378
+ world_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] # Red, Green, Blue
379
+ world_pipestr_vis(world_pipes, start_coord, world_colors)
380
+ print()
381
+
382
+ # Multiple local coordinate pipes
383
+ local_pipes = ["FFR", "BBL", "UUD"]
384
+ local_colors = [(255, 255, 0), (255, 0, 255), (0, 255, 255)] # Yellow, Magenta, Cyan
385
+ local_pipestr_vis(local_pipes, start_coord, local_colors)
386
+ print()
387
+
388
+ # Example 4: Advanced multiple pipes configuration
389
+ print("Advanced Multiple Pipes Configuration:")
390
+ pipe_configs = [
391
+ {
392
+ 'pipe_str': 'FFR',
393
+ 'start_c': coord3(vec3(0, 0, 0), quat(1, 0, 0, 0)),
394
+ 'color': (255, 100, 100),
395
+ 'radius': 0.4
396
+ },
397
+ {
398
+ 'pipe_str': 'LLU',
399
+ 'start_c': coord3(vec3(5, 0, 0), quat(1, 0, 0, 0)),
400
+ 'color': (100, 255, 100),
401
+ 'radius': 0.3
402
+ },
403
+ {
404
+ 'pipe_str': 'RRD',
405
+ 'start_c': coord3(vec3(0, 5, 0), quat(1, 0, 0, 0)),
406
+ 'color': (100, 100, 255),
407
+ 'radius': 0.2
408
+ }
409
+ ]
410
+
411
+ multiple_pipes_vis(pipe_configs, 'world')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: phg_vis
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: A package for the PHG modeling language and 3D visualization tool.
5
5
  Home-page: https://github.com/panguojun/Coordinate-System
6
6
  Author: romeosoft
@@ -1,6 +1,6 @@
1
- phg/__init__.py,sha256=TvWMc1ho6g9enlj0nhtr5eidViu6xyt0CrUOW31Q9F4,3097
1
+ phg/__init__.py,sha256=kH5hF-vqbLqzBE_xkOYabiYFtdb4CXtlwl67uPbDHpo,10767
2
2
  phg/phg_to_shader.py,sha256=rb_LnGE1Py08oz72ES5CnjyCDbjVWDU3If0cYZq4SUU,15172
3
- phg/pipe_string_phg.py,sha256=FPFatph2WCVoUzEflIJWRotwH0Yb79VJaKvmyaj4zDI,10654
3
+ phg/pipe_string_phg.py,sha256=xoG8AtHRae_sOskSZxTc7lBgwnemv1u8Ko9GvnvHr8Q,16257
4
4
  phg/shader_render.py,sha256=_T8IFp1h5Hcj8TMMHwFMbxhGdHLnOqka7pJ4pde7zMA,16780
5
5
  phg/visphg.py,sha256=CtALoNJs0eDT8wnXk_76XG4UsOcV6cWucvWqz7AhOSc,1923
6
6
  phg/vis/GCU.dll,sha256=k_slWZ5nOzZNi9zCe0_SKc0F7zXoLyRuRDomyirPY4I,2687488
@@ -15,8 +15,8 @@ phg/vis/vis.exe,sha256=9LGgETiO4lwhz_gJzdUg6gPP9EwGLT5SuLjN3wR2sso,1388032
15
15
  phg/vis/vis.ini,sha256=IjS0Av2BqresPR2oGCOoq5zliXN2wFRMK3rXcU15vKs,161
16
16
  phg/vis/zlib1.dll,sha256=oVw_r326ve3oveVZhlSiF8BloZQ6lfqXJEAhUYfMjOQ,89088
17
17
  phg/vis/imgui/main.lua,sha256=AIB5dpGrPHXuRiNW7Bg7eu5Lpi2DDcn6n4JS7OS1Hdk,4742
18
- phg_vis-1.3.1.dist-info/LICENSE,sha256=tDnRkJxBYPzWdfh2gArRqrUPJxQZRZHJVs68qqBHIq4,1083
19
- phg_vis-1.3.1.dist-info/METADATA,sha256=rJB_6RA15BncZfzq2BPKCgI02cesmNrB67eIzPtdpbM,17945
20
- phg_vis-1.3.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
21
- phg_vis-1.3.1.dist-info/top_level.txt,sha256=5GGhpTP8yi-zTXwW2HrI-zcxKxIM_nHXhL7r0iIDE_k,4
22
- phg_vis-1.3.1.dist-info/RECORD,,
18
+ phg_vis-1.3.2.dist-info/LICENSE,sha256=tDnRkJxBYPzWdfh2gArRqrUPJxQZRZHJVs68qqBHIq4,1083
19
+ phg_vis-1.3.2.dist-info/METADATA,sha256=gMSdSe_22WeBMCBSxhLdpIYV4EbiP7NhJPVf_FnKQKU,17945
20
+ phg_vis-1.3.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
21
+ phg_vis-1.3.2.dist-info/top_level.txt,sha256=5GGhpTP8yi-zTXwW2HrI-zcxKxIM_nHXhL7r0iIDE_k,4
22
+ phg_vis-1.3.2.dist-info/RECORD,,