phg-vis 1.3.1__tar.gz → 1.4.0__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.
- {phg_vis-1.3.1 → phg_vis-1.4.0}/PKG-INFO +56 -1
- phg_vis-1.3.1/phg_vis.egg-info/PKG-INFO → phg_vis-1.4.0/README.md +63 -28
- phg_vis-1.4.0/phg/__init__.py +400 -0
- phg_vis-1.4.0/phg/ai_bridge.py +174 -0
- phg_vis-1.4.0/phg/gcu_api.py +709 -0
- phg_vis-1.4.0/phg/pipe_string_phg.py +439 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/shader_render.py +26 -12
- phg_vis-1.4.0/phg/visphg.py +79 -0
- phg_vis-1.4.0/phg/web_three.py +164 -0
- phg_vis-1.3.1/README.md → phg_vis-1.4.0/phg_vis.egg-info/PKG-INFO +70 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg_vis.egg-info/SOURCES.txt +4 -0
- phg_vis-1.4.0/phg_vis.egg-info/requires.txt +6 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/setup.py +8 -3
- phg_vis-1.3.1/phg/__init__.py +0 -113
- phg_vis-1.3.1/phg/pipe_string_phg.py +0 -285
- phg_vis-1.3.1/phg/visphg.py +0 -55
- {phg_vis-1.3.1 → phg_vis-1.4.0}/LICENSE +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/MANIFEST.in +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/phg_to_shader.py +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/GCU.dll +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/dragpad.exe +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/dragpad_config.ini +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/freeglut.dll +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/imgui/main.lua +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/lua.dll +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/script.phg +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/sqlite3.dll +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/vis.exe +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/vis.ini +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg/vis/zlib1.dll +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg_vis.egg-info/dependency_links.txt +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/phg_vis.egg-info/top_level.txt +0 -0
- {phg_vis-1.3.1 → phg_vis-1.4.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: phg_vis
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
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
|
|
@@ -12,6 +12,11 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
12
12
|
Requires-Python: >=3.8
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
+
Requires-Dist: psutil
|
|
16
|
+
Provides-Extra: shader
|
|
17
|
+
Requires-Dist: numpy; extra == "shader"
|
|
18
|
+
Requires-Dist: pygame; extra == "shader"
|
|
19
|
+
Requires-Dist: PyOpenGL; extra == "shader"
|
|
15
20
|
|
|
16
21
|
# PHG - Python Hypergraphics Library
|
|
17
22
|
|
|
@@ -27,6 +32,8 @@ PHG (Python Hypergraphics) is a powerful 3D modeling and visualization library t
|
|
|
27
32
|
- **Pipe Visualization** - Specialized system for visualizing pipe structures with world/local coordinate support
|
|
28
33
|
- **Shader Conversion** - Convert PHG scripts to GLSL shaders for GPU rendering
|
|
29
34
|
- **Dual Rendering Modes** - Both real-time visualization (vis.exe) and offscreen rendering
|
|
35
|
+
- **AI Parser Bridge** - Use DGE++ PHG parser to normalize/enhance scripts before visualization
|
|
36
|
+
- **Web Viewer** - Export OBJ and view in a three.js browser viewer
|
|
30
37
|
- **Python Integration** - Comprehensive Python API for all features
|
|
31
38
|
|
|
32
39
|
---
|
|
@@ -42,6 +49,11 @@ Or install from source:
|
|
|
42
49
|
pip install phg
|
|
43
50
|
```
|
|
44
51
|
|
|
52
|
+
Shader renderer dependencies (optional):
|
|
53
|
+
```bash
|
|
54
|
+
pip install phg_vis[shader]
|
|
55
|
+
```
|
|
56
|
+
|
|
45
57
|
---
|
|
46
58
|
|
|
47
59
|
## 🚀 Quick Start
|
|
@@ -86,6 +98,49 @@ phg.image(scene, filename="tower.png")
|
|
|
86
98
|
phg.image("sphere(5);|||view=2 width=1920 height=1080", filename="top_view.png")
|
|
87
99
|
```
|
|
88
100
|
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## ✨ Unified Visualization API
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import phg
|
|
107
|
+
|
|
108
|
+
# Traditional vis.exe
|
|
109
|
+
phg.visualize("box(10);", mode="vis")
|
|
110
|
+
|
|
111
|
+
# Shader ray-march preview (GLSL)
|
|
112
|
+
phg.visualize("sphere(5);", mode="shader", width=800, height=600)
|
|
113
|
+
|
|
114
|
+
# Web (three.js) viewer
|
|
115
|
+
phg.visualize("box(10);", mode="web", out_html="view.html")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### AI Parser Bridge (for improved PHG)
|
|
119
|
+
Use DGE++ PHG parser to normalize/enhance scripts before visualization:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
import phg
|
|
123
|
+
|
|
124
|
+
phg.visualize(script, mode="vis", ai=True)
|
|
125
|
+
phg.visualize(script, mode="shader", ai=True)
|
|
126
|
+
phg.visualize(script, mode="web", ai=True, out_html="ai_view.html")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Environment override (optional):
|
|
130
|
+
```
|
|
131
|
+
set PHG_AI_ROOT=C:\Users\18858\Documents\_AILab\DGE++\PHG
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Web live server (serves HTML + OBJ):
|
|
135
|
+
```python
|
|
136
|
+
phg.web_serve(script, host="127.0.0.1", port=8766, ai_root=None)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Notes for web viewer:
|
|
140
|
+
- Uses three.js CDN (requires network access)
|
|
141
|
+
- Uses AI bridge to export OBJ; ensure DGE++ is available
|
|
142
|
+
- Use `web_serve` to avoid file:// loader restrictions
|
|
143
|
+
|
|
89
144
|
---
|
|
90
145
|
|
|
91
146
|
## 📖 Syntax Reference
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: phg_vis
|
|
3
|
-
Version: 1.3.1
|
|
4
|
-
Summary: A package for the PHG modeling language and 3D visualization tool.
|
|
5
|
-
Home-page: https://github.com/panguojun/Coordinate-System
|
|
6
|
-
Author: romeosoft
|
|
7
|
-
Author-email: 18858146@qq.com
|
|
8
|
-
Platform: Windows
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
-
Classifier: Operating System :: Microsoft :: Windows
|
|
12
|
-
Requires-Python: >=3.8
|
|
13
|
-
Description-Content-Type: text/markdown
|
|
14
|
-
License-File: LICENSE
|
|
15
|
-
|
|
16
1
|
# PHG - Python Hypergraphics Library
|
|
17
2
|
|
|
18
3
|
PHG (Python Hypergraphics) is a powerful 3D modeling and visualization library that combines a minimalist modeling language with Python integration. It provides procedural 3D scene generation, shader-based rendering, and specialized pipe system visualization.
|
|
@@ -25,26 +10,33 @@ PHG (Python Hypergraphics) is a powerful 3D modeling and visualization library t
|
|
|
25
10
|
- **Hierarchical Modeling** - Support for nested nodes and transform inheritance
|
|
26
11
|
- **Parametric Design** - Flexible property system and function definitions
|
|
27
12
|
- **Pipe Visualization** - Specialized system for visualizing pipe structures with world/local coordinate support
|
|
28
|
-
- **Shader Conversion** - Convert PHG scripts to GLSL shaders for GPU rendering
|
|
29
|
-
- **Dual Rendering Modes** - Both real-time visualization (vis.exe) and offscreen rendering
|
|
30
|
-
- **
|
|
13
|
+
- **Shader Conversion** - Convert PHG scripts to GLSL shaders for GPU rendering
|
|
14
|
+
- **Dual Rendering Modes** - Both real-time visualization (vis.exe) and offscreen rendering
|
|
15
|
+
- **AI Parser Bridge** - Use DGE++ PHG parser to normalize/enhance scripts before visualization
|
|
16
|
+
- **Web Viewer** - Export OBJ and view in a three.js browser viewer
|
|
17
|
+
- **Python Integration** - Comprehensive Python API for all features
|
|
31
18
|
|
|
32
19
|
---
|
|
33
20
|
|
|
34
21
|
## 📦 Installation
|
|
35
22
|
|
|
36
23
|
```bash
|
|
37
|
-
pip install phg_vis
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Or install from source:
|
|
41
|
-
```bash
|
|
42
|
-
pip install phg
|
|
43
|
-
```
|
|
24
|
+
pip install phg_vis
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or install from source:
|
|
28
|
+
```bash
|
|
29
|
+
pip install phg
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Shader renderer dependencies (optional):
|
|
33
|
+
```bash
|
|
34
|
+
pip install phg_vis[shader]
|
|
35
|
+
```
|
|
44
36
|
|
|
45
37
|
---
|
|
46
38
|
|
|
47
|
-
## 🚀 Quick Start
|
|
39
|
+
## 🚀 Quick Start
|
|
48
40
|
|
|
49
41
|
### Python Usage
|
|
50
42
|
|
|
@@ -83,8 +75,51 @@ scene = """
|
|
|
83
75
|
phg.image(scene, filename="tower.png")
|
|
84
76
|
|
|
85
77
|
# Method 3: Multi-view rendering
|
|
86
|
-
phg.image("sphere(5);|||view=2 width=1920 height=1080", filename="top_view.png")
|
|
87
|
-
```
|
|
78
|
+
phg.image("sphere(5);|||view=2 width=1920 height=1080", filename="top_view.png")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## ✨ Unified Visualization API
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import phg
|
|
87
|
+
|
|
88
|
+
# Traditional vis.exe
|
|
89
|
+
phg.visualize("box(10);", mode="vis")
|
|
90
|
+
|
|
91
|
+
# Shader ray-march preview (GLSL)
|
|
92
|
+
phg.visualize("sphere(5);", mode="shader", width=800, height=600)
|
|
93
|
+
|
|
94
|
+
# Web (three.js) viewer
|
|
95
|
+
phg.visualize("box(10);", mode="web", out_html="view.html")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### AI Parser Bridge (for improved PHG)
|
|
99
|
+
Use DGE++ PHG parser to normalize/enhance scripts before visualization:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import phg
|
|
103
|
+
|
|
104
|
+
phg.visualize(script, mode="vis", ai=True)
|
|
105
|
+
phg.visualize(script, mode="shader", ai=True)
|
|
106
|
+
phg.visualize(script, mode="web", ai=True, out_html="ai_view.html")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Environment override (optional):
|
|
110
|
+
```
|
|
111
|
+
set PHG_AI_ROOT=C:\Users\18858\Documents\_AILab\DGE++\PHG
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Web live server (serves HTML + OBJ):
|
|
115
|
+
```python
|
|
116
|
+
phg.web_serve(script, host="127.0.0.1", port=8766, ai_root=None)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Notes for web viewer:
|
|
120
|
+
- Uses three.js CDN (requires network access)
|
|
121
|
+
- Uses AI bridge to export OBJ; ensure DGE++ is available
|
|
122
|
+
- Use `web_serve` to avoid file:// loader restrictions
|
|
88
123
|
|
|
89
124
|
---
|
|
90
125
|
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PHG - Python Hypergraphics Library
|
|
3
|
+
===================================
|
|
4
|
+
|
|
5
|
+
A powerful graphics library for procedural 3D visualization using PHG scripts.
|
|
6
|
+
|
|
7
|
+
Main Features:
|
|
8
|
+
- PHG script visualization via vis.exe
|
|
9
|
+
- Shader-based rendering with GLSL conversion
|
|
10
|
+
- Pipe system visualization with world/local coordinate systems
|
|
11
|
+
- Multiple pipe visualization support
|
|
12
|
+
- Real-time and image rendering capabilities
|
|
13
|
+
|
|
14
|
+
Version: 1.4.0
|
|
15
|
+
Author: PanGuoJun
|
|
16
|
+
License: MIT
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import tempfile
|
|
21
|
+
|
|
22
|
+
from .visphg import vis, image
|
|
23
|
+
from .shader_render import ShaderRenderer, render_shader
|
|
24
|
+
from .phg_to_shader import PHGToShaderConverter, phg_to_shader
|
|
25
|
+
from .pipe_string_phg import (
|
|
26
|
+
world_to_local_pipe_str,
|
|
27
|
+
local_pipe_to_phg,
|
|
28
|
+
world_pipe_to_phg,
|
|
29
|
+
world_pipestr_vis,
|
|
30
|
+
local_pipestr_vis,
|
|
31
|
+
multiple_pipes_vis
|
|
32
|
+
)
|
|
33
|
+
from .ai_bridge import (
|
|
34
|
+
compile_ai_phg,
|
|
35
|
+
vis_ai,
|
|
36
|
+
image_ai,
|
|
37
|
+
export_ai_obj,
|
|
38
|
+
web_view_ai,
|
|
39
|
+
)
|
|
40
|
+
from .web_three import write_three_view_html, serve_three_view
|
|
41
|
+
|
|
42
|
+
# Extend ShaderRenderer class to support direct PHG rendering
|
|
43
|
+
class PHGShaderRenderer(ShaderRenderer):
|
|
44
|
+
"""Shader renderer that supports direct PHG rendering"""
|
|
45
|
+
|
|
46
|
+
def render_phg(self, phg_script: str, duration=0, interactive=True):
|
|
47
|
+
"""
|
|
48
|
+
Render PHG script
|
|
49
|
+
|
|
50
|
+
Parameters:
|
|
51
|
+
phg_script: PHG script code
|
|
52
|
+
duration: Render duration
|
|
53
|
+
interactive: Whether to allow interaction
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
success: Whether rendering was successful
|
|
57
|
+
"""
|
|
58
|
+
converter = PHGToShaderConverter()
|
|
59
|
+
shader_code = converter.generate_shader_code(phg_script)
|
|
60
|
+
|
|
61
|
+
if not shader_code:
|
|
62
|
+
print("Error: PHG conversion failed")
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
return self.render_shader(shader_code, duration, interactive)
|
|
66
|
+
|
|
67
|
+
# Convenience functions
|
|
68
|
+
def render_phg(phg_script: str, width=800, height=600, duration=0, title="PHG Renderer"):
|
|
69
|
+
"""
|
|
70
|
+
Directly render PHG script
|
|
71
|
+
|
|
72
|
+
Parameters:
|
|
73
|
+
phg_script: PHG script code
|
|
74
|
+
width: Window width
|
|
75
|
+
height: Window height
|
|
76
|
+
duration: Render duration
|
|
77
|
+
title: Window title
|
|
78
|
+
"""
|
|
79
|
+
renderer = PHGShaderRenderer(width, height, title)
|
|
80
|
+
success = renderer.render_phg(phg_script, duration)
|
|
81
|
+
renderer.close()
|
|
82
|
+
return success
|
|
83
|
+
|
|
84
|
+
def convert_phg_to_shader(phg_script: str) -> str:
|
|
85
|
+
"""
|
|
86
|
+
Convert PHG script to GLSL shader code
|
|
87
|
+
|
|
88
|
+
Parameters:
|
|
89
|
+
phg_script: PHG script
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
shader_code: GLSL shader code
|
|
93
|
+
"""
|
|
94
|
+
return phg_to_shader(phg_script)
|
|
95
|
+
|
|
96
|
+
def visualize_pipe_variants(pipe_variants, start_position=None, colors=None, coordinate_system='world'):
|
|
97
|
+
"""
|
|
98
|
+
Visualize multiple pipe variants for comparison
|
|
99
|
+
|
|
100
|
+
Parameters:
|
|
101
|
+
pipe_variants: List of pipe strings or configuration dictionaries
|
|
102
|
+
start_position: Starting coordinate (optional)
|
|
103
|
+
colors: List of colors for each pipe variant
|
|
104
|
+
coordinate_system: 'world' or 'local' coordinate system
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
PHG script string
|
|
108
|
+
"""
|
|
109
|
+
from coordinate_system import vec3, quat, coord3
|
|
110
|
+
|
|
111
|
+
# Handle start position
|
|
112
|
+
if start_position is None:
|
|
113
|
+
start_c = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
|
|
114
|
+
else:
|
|
115
|
+
start_c = start_position
|
|
116
|
+
|
|
117
|
+
# Handle different input formats
|
|
118
|
+
if isinstance(pipe_variants[0], str):
|
|
119
|
+
# Simple list of pipe strings
|
|
120
|
+
if colors is None:
|
|
121
|
+
# Generate distinct colors for each variant
|
|
122
|
+
import colorsys
|
|
123
|
+
colors = []
|
|
124
|
+
for i in range(len(pipe_variants)):
|
|
125
|
+
hue = i / len(pipe_variants)
|
|
126
|
+
rgb = colorsys.hsv_to_rgb(hue, 0.8, 0.9)
|
|
127
|
+
colors.append(tuple(int(c * 255) for c in rgb))
|
|
128
|
+
|
|
129
|
+
if coordinate_system == 'world':
|
|
130
|
+
return world_pipestr_vis(pipe_variants, start_c, colors)
|
|
131
|
+
else:
|
|
132
|
+
return local_pipestr_vis(pipe_variants, start_c, colors)
|
|
133
|
+
|
|
134
|
+
else:
|
|
135
|
+
# List of configuration dictionaries
|
|
136
|
+
pipe_configs = []
|
|
137
|
+
for i, variant in enumerate(pipe_variants):
|
|
138
|
+
if isinstance(variant, str):
|
|
139
|
+
config = {
|
|
140
|
+
'pipe_str': variant,
|
|
141
|
+
'start_c': start_c,
|
|
142
|
+
'color': colors[i] if colors else None,
|
|
143
|
+
'radius': 0.3
|
|
144
|
+
}
|
|
145
|
+
else:
|
|
146
|
+
config = variant
|
|
147
|
+
if 'start_c' not in config:
|
|
148
|
+
config['start_c'] = start_c
|
|
149
|
+
|
|
150
|
+
pipe_configs.append(config)
|
|
151
|
+
|
|
152
|
+
return multiple_pipes_vis(pipe_configs, coordinate_system)
|
|
153
|
+
|
|
154
|
+
def create_pipe_comparison_grid(pipe_strings, grid_size=(2, 2), start_position=None,
|
|
155
|
+
base_color=(0, 55, 255), coordinate_system='world'):
|
|
156
|
+
"""
|
|
157
|
+
Create a grid layout for comparing multiple pipe paths
|
|
158
|
+
|
|
159
|
+
Parameters:
|
|
160
|
+
pipe_strings: List of pipe strings to compare
|
|
161
|
+
grid_size: (rows, cols) for grid layout
|
|
162
|
+
start_position: Base starting position
|
|
163
|
+
base_color: Base color for pipes
|
|
164
|
+
coordinate_system: 'world' or 'local'
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
PHG script string
|
|
168
|
+
"""
|
|
169
|
+
from coordinate_system import vec3, quat, coord3
|
|
170
|
+
|
|
171
|
+
if start_position is None:
|
|
172
|
+
start_position = coord3(vec3(0, 0, 0), quat(1, 0, 0, 0))
|
|
173
|
+
|
|
174
|
+
rows, cols = grid_size
|
|
175
|
+
spacing = 5.0 # Space between pipes in grid
|
|
176
|
+
|
|
177
|
+
pipe_configs = []
|
|
178
|
+
|
|
179
|
+
for i, pipe_str in enumerate(pipe_strings):
|
|
180
|
+
if i >= rows * cols:
|
|
181
|
+
break
|
|
182
|
+
|
|
183
|
+
row = i // cols
|
|
184
|
+
col = i % cols
|
|
185
|
+
|
|
186
|
+
# Calculate position in grid
|
|
187
|
+
x_offset = col * spacing
|
|
188
|
+
z_offset = row * spacing
|
|
189
|
+
|
|
190
|
+
# Create individual start position for this pipe
|
|
191
|
+
individual_start = coord3(
|
|
192
|
+
vec3(
|
|
193
|
+
start_position.o.x + x_offset,
|
|
194
|
+
start_position.o.y,
|
|
195
|
+
start_position.o.z + z_offset
|
|
196
|
+
),
|
|
197
|
+
start_position.Q()
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Generate color variation
|
|
201
|
+
color_variation = (
|
|
202
|
+
min(255, base_color[0] + (i * 30) % 100),
|
|
203
|
+
min(255, base_color[1] + (i * 50) % 100),
|
|
204
|
+
min(255, base_color[2] + (i * 70) % 100)
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
pipe_configs.append({
|
|
208
|
+
'pipe_str': pipe_str,
|
|
209
|
+
'start_c': individual_start,
|
|
210
|
+
'color': color_variation,
|
|
211
|
+
'radius': 0.25 + (i * 0.05) # Vary radius slightly
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
return multiple_pipes_vis(pipe_configs, coordinate_system)
|
|
215
|
+
|
|
216
|
+
def generate_pipe_variants_from_rules(base_pipe, num_variants=5, apply_rules=None):
|
|
217
|
+
"""
|
|
218
|
+
Generate pipe variants using transformation rules
|
|
219
|
+
|
|
220
|
+
Parameters:
|
|
221
|
+
base_pipe: Base pipe string
|
|
222
|
+
num_variants: Number of variants to generate
|
|
223
|
+
apply_rules: List of rules to apply ('swap', 'insert', 'cancel')
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
List of pipe variant strings
|
|
227
|
+
"""
|
|
228
|
+
if apply_rules is None:
|
|
229
|
+
apply_rules = ['swap', 'insert', 'cancel']
|
|
230
|
+
|
|
231
|
+
variants = [base_pipe]
|
|
232
|
+
|
|
233
|
+
# Import the pipe transformer if available
|
|
234
|
+
try:
|
|
235
|
+
from .pipe_string_phg import PipeStringTransformer
|
|
236
|
+
transformer = PipeStringTransformer()
|
|
237
|
+
|
|
238
|
+
for _ in range(num_variants - 1):
|
|
239
|
+
current_pipe = base_pipe
|
|
240
|
+
|
|
241
|
+
# Apply random transformations
|
|
242
|
+
import random
|
|
243
|
+
for _ in range(random.randint(1, 3)):
|
|
244
|
+
rule = random.choice(apply_rules)
|
|
245
|
+
|
|
246
|
+
if rule == 'swap' and len(current_pipe) >= 2:
|
|
247
|
+
i, j = random.sample(range(len(current_pipe)), 2)
|
|
248
|
+
current_pipe = transformer.swap_positions(current_pipe, i, j)
|
|
249
|
+
|
|
250
|
+
elif rule == 'insert':
|
|
251
|
+
position = random.randint(0, len(current_pipe))
|
|
252
|
+
direction = random.choice(list(transformer.CANCEL_PAIRS.keys()))
|
|
253
|
+
current_pipe = transformer.insert_cancel_pair(current_pipe, position, direction)
|
|
254
|
+
|
|
255
|
+
elif rule == 'cancel':
|
|
256
|
+
current_pipe = transformer.cancel_adjacent_pairs(current_pipe)
|
|
257
|
+
|
|
258
|
+
# Simplify and add if valid
|
|
259
|
+
simplified = transformer.simplify_path(current_pipe)
|
|
260
|
+
if simplified not in variants:
|
|
261
|
+
variants.append(simplified)
|
|
262
|
+
|
|
263
|
+
except ImportError:
|
|
264
|
+
# Fallback: simple variant generation
|
|
265
|
+
import random
|
|
266
|
+
for i in range(num_variants - 1):
|
|
267
|
+
# Simple character shuffling
|
|
268
|
+
pipe_list = list(base_pipe)
|
|
269
|
+
random.shuffle(pipe_list)
|
|
270
|
+
variant = ''.join(pipe_list)
|
|
271
|
+
if variant not in variants:
|
|
272
|
+
variants.append(variant)
|
|
273
|
+
|
|
274
|
+
return variants[:num_variants]
|
|
275
|
+
|
|
276
|
+
# Enhanced pipe visualization with transformation support
|
|
277
|
+
def visualize_pipe_with_transformations(pipe_string, start_position=None,
|
|
278
|
+
transformations=None, show_variants=3):
|
|
279
|
+
"""
|
|
280
|
+
Visualize a pipe string along with its transformed variants
|
|
281
|
+
|
|
282
|
+
Parameters:
|
|
283
|
+
pipe_string: Base pipe string
|
|
284
|
+
start_position: Starting coordinate
|
|
285
|
+
transformations: List of transformation rules to apply
|
|
286
|
+
show_variants: Number of variants to show
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
PHG script string
|
|
290
|
+
"""
|
|
291
|
+
# Generate variants
|
|
292
|
+
variants = generate_pipe_variants_from_rules(
|
|
293
|
+
pipe_string,
|
|
294
|
+
num_variants=show_variants + 1, # +1 for original
|
|
295
|
+
apply_rules=transformations
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# Create comparison visualization
|
|
299
|
+
return visualize_pipe_variants(variants, start_position)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def web_view(script: str, out_html: str = "phg_view.html", out_obj: str = None,
|
|
303
|
+
ai_root: str = None, title: str = "PHG Web Viewer") -> str:
|
|
304
|
+
"""
|
|
305
|
+
Export OBJ via AI parser and write a three.js HTML viewer.
|
|
306
|
+
"""
|
|
307
|
+
return web_view_ai(script, out_html=out_html, out_obj=out_obj, ai_root=ai_root, title=title)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def web_serve(script: str, host: str = "127.0.0.1", port: int = 8766,
|
|
311
|
+
ai_root: str = None, title: str = "PHG Web Viewer") -> str:
|
|
312
|
+
"""
|
|
313
|
+
Export OBJ via AI parser, write HTML, and serve with a local HTTP server.
|
|
314
|
+
"""
|
|
315
|
+
temp_dir = tempfile.mkdtemp(prefix="phg_web_")
|
|
316
|
+
out_obj = os.path.join(temp_dir, "scene.obj")
|
|
317
|
+
out_html = os.path.join(temp_dir, "viewer.html")
|
|
318
|
+
web_view_ai(script, out_html=out_html, out_obj=out_obj, ai_root=ai_root, title=title)
|
|
319
|
+
return serve_three_view(out_obj, html_path=out_html, host=host, port=port, title=title)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def visualize(script: str, mode: str = "vis", ai: bool = False, **kwargs):
|
|
323
|
+
"""
|
|
324
|
+
Unified visualization entrypoint.
|
|
325
|
+
mode: vis | image | shader | web
|
|
326
|
+
ai: use AI parser (DGE++) to normalize/expand before visualization
|
|
327
|
+
"""
|
|
328
|
+
mode = (mode or "vis").lower()
|
|
329
|
+
ai_root = kwargs.pop("ai_root", None)
|
|
330
|
+
|
|
331
|
+
if mode in ("vis", "native", "exe"):
|
|
332
|
+
return vis_ai(script, ai_root=ai_root) if ai else vis(script)
|
|
333
|
+
|
|
334
|
+
if mode in ("image", "img", "png"):
|
|
335
|
+
filename = kwargs.pop("filename", "shot.png")
|
|
336
|
+
return image_ai(script, filename=filename, ai_root=ai_root) if ai else image(script, filename=filename)
|
|
337
|
+
|
|
338
|
+
if mode in ("shader", "ray", "rt"):
|
|
339
|
+
phg_script = compile_ai_phg(script, ai_root=ai_root, include_setup=True) if ai else script
|
|
340
|
+
return render_phg(phg_script, **kwargs)
|
|
341
|
+
|
|
342
|
+
if mode in ("web", "three"):
|
|
343
|
+
out_html = kwargs.pop("out_html", "phg_view.html")
|
|
344
|
+
out_obj = kwargs.pop("out_obj", None)
|
|
345
|
+
title = kwargs.pop("title", "PHG Web Viewer")
|
|
346
|
+
return web_view_ai(script, out_html=out_html, out_obj=out_obj, ai_root=ai_root, title=title)
|
|
347
|
+
|
|
348
|
+
raise ValueError(f"Unknown mode: {mode}")
|
|
349
|
+
|
|
350
|
+
__all__ = [
|
|
351
|
+
# Core visualization functions
|
|
352
|
+
'vis',
|
|
353
|
+
'image',
|
|
354
|
+
'visualize',
|
|
355
|
+
|
|
356
|
+
# Shader rendering
|
|
357
|
+
'ShaderRenderer',
|
|
358
|
+
'render_shader',
|
|
359
|
+
'render_phg',
|
|
360
|
+
'PHGShaderRenderer',
|
|
361
|
+
|
|
362
|
+
# PHG conversion
|
|
363
|
+
'PHGToShaderConverter',
|
|
364
|
+
'phg_to_shader',
|
|
365
|
+
'convert_phg_to_shader',
|
|
366
|
+
'compile_ai_phg',
|
|
367
|
+
'vis_ai',
|
|
368
|
+
'image_ai',
|
|
369
|
+
'export_ai_obj',
|
|
370
|
+
'web_view',
|
|
371
|
+
'web_view_ai',
|
|
372
|
+
'web_serve',
|
|
373
|
+
'write_three_view_html',
|
|
374
|
+
'serve_three_view',
|
|
375
|
+
|
|
376
|
+
# Pipe visualization
|
|
377
|
+
'world_pipe_to_phg',
|
|
378
|
+
'local_pipe_to_phg',
|
|
379
|
+
'world_pipestr_vis',
|
|
380
|
+
'local_pipestr_vis',
|
|
381
|
+
'multiple_pipes_vis',
|
|
382
|
+
|
|
383
|
+
# Enhanced pipe visualization
|
|
384
|
+
'visualize_pipe_variants',
|
|
385
|
+
'create_pipe_comparison_grid',
|
|
386
|
+
'generate_pipe_variants_from_rules',
|
|
387
|
+
'visualize_pipe_with_transformations',
|
|
388
|
+
]
|
|
389
|
+
|
|
390
|
+
__version__ = "1.4.0"
|
|
391
|
+
__author__ = "PanGuoJun"
|
|
392
|
+
__description__ = "Python Hypergraphics Library"
|
|
393
|
+
|
|
394
|
+
if os.environ.get("PHG_VERBOSE"):
|
|
395
|
+
print(f"PHG {__version__} - {__description__}")
|
|
396
|
+
print("[OK] Visualization module loaded")
|
|
397
|
+
print("[OK] Shader converter loaded")
|
|
398
|
+
print("[OK] Pipe visualization loaded")
|
|
399
|
+
print("[OK] Multiple pipe visualization support loaded")
|
|
400
|
+
print("[OK] Pipe transformation utilities loaded")
|