Metadata-Version: 2.1
Name: phg_vis
Version: 5.0.6
Summary: A package for the PHG modeling language and 3D visualization tool.
Home-page: https://github.com/panguojun/Coordinate-System
Author: romeosoft
Platform: Windows
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: process
Requires-Dist: psutil<7.0,>=5.9; extra == "process"
Provides-Extra: shader
Requires-Dist: numpy; extra == "shader"
Requires-Dist: pygame; extra == "shader"
Requires-Dist: PyOpenGL; extra == "shader"

# PHG VIS

`phg_vis` is a Windows-oriented PHG modeling and visualization package. It bundles the Python API, the PHG runtime bridge, the desktop `vis.exe` viewer, Dragpad file opener, and required viewer runtime files.

Current release target: `5.0.5`

## What Is Included

- Python package `phg`
- Desktop viewer: `vis.exe`
- PHG geometry/runtime bridge: `GCU.dll`
- Drag-and-drop / double-click opener: `dragpad.exe`
- Runtime DLLs needed by the viewer
- PHG visualization helpers for interactive viewing, screenshots, web preview, and engineering scene inspection

The package is designed to be environment-neutral. Do not ship private machine paths, user profile paths, reader executable paths, or project-specific absolute directories in package defaults.

## Main Features

- Interactive PHG rendering through the bundled `vis.exe`
- PHG script execution through `GCU.dll`
- Direct loading of `.phg`, `.sce`, `.sm`, `.grid`, `.obj`, `.wlkx`, and `.rvm` where the corresponding reader is configured
- Unicode-safe file opening through Dragpad, including non-ASCII parent directories
- Remote VIS probe with local fallback
- Stable local cold-start behavior before sending PHG content to VIS
- PHG path-node syntax such as `a/b/c`
- Local-first node reference lookup for scoped PHG scripts
- Boolean-script workflow support through the PHG runtime
- Diagnostic logs for PHG execution and viewer-side request handling
- Web/Three.js preview helpers for exported OBJ scenes
- PHG semantic recovery reports through `phg.semantic_recovery`
- Optional shader conversion and rendering helpers

## Semantic Recovery

`phg_vis` includes a PHG semantic recovery engine for converting a PHG scene into engineering-readable semantic reports. The current engine is pipe-first: it identifies pipe route geometry first, then uses that route to infer start/end nozzles, route nodes, straight pipe segments, inline pipe parts, nearby obstacle candidates, nearby wall/tower/shell candidates, and pipeline topology evidence.

The recovery engine is available both as a Python API and as a command-line tool. It is intended for PHG files that already contain geometry primitives, including automatic routing outputs such as `AUTO_PIPE_*` nodes. If a scene contains `AUTO_PIPE_*_grid_pt_*`, `AUTO_PIPE_*_grid_seg_*`, and nozzle/stub nodes, the engine promotes valid routed pipes into `PipelineTopology` records.

### Python API

Use `recover_phg_semantics()` when you want all generated files plus the structured payload:

```python
from pathlib import Path
import phg

input_phg = Path(r"C:\path\to\scene.phg")
output_prefix = input_phg.with_name(input_phg.stem + "_semantic")

result = phg.recover_phg_semantics(input_phg, output_prefix)

print("JSON:", result.json_path)
print("Markdown:", result.markdown_path)
print("Semantic text:", result.semantic_text_path)
print(result.semantic_text)

payload = result.payload
print("Recovered pipelines:", len(payload["pipelines"]))
print("Pipe semantic descriptions:", len(payload["pipe_semantics"]))
```

Use `recover_phg_semantic_text()` when you only need the human-readable semantic text:

```python
import phg

text = phg.recover_phg_semantic_text(r"C:\path\to\scene.phg")
print(text)
```

### Command Line

After installation, run:

```bash
phg-semantic-recovery scene.phg --output-prefix scene_semantic_report
```

To also print the semantic text to stdout:

```bash
phg-semantic-recovery scene.phg --output-prefix scene_semantic_report --print-text
```

The module entry point is equivalent:

```bash
python -m phg.semantic_recovery scene.phg --output-prefix scene_semantic_report --print-text
```

### Output Files

For an output prefix named `scene_semantic_report`, the engine writes:

- `scene_semantic_report.json`
- `scene_semantic_report.md`
- `scene_semantic_report_semantic_text.md`

`*.json` is the complete machine-readable result. It keeps geometry coordinates, route points, primitive parameters, recovered ports, recovered pipelines, pipe semantic descriptions, QGraph results, and legality diagnostics. Use this file for programmatic analysis and downstream tools.

`*.md` is the compact technical report. It includes summary counts, pipeline topology, route node names, route segment names, inline part names, constraint results, QGraph summary, and primitive inventory. This report is useful for quickly checking whether the PHG produced recoverable topology.

`*_semantic_text.md` is the human-readable semantic text. This report intentionally avoids printing raw coordinates and prefers PHG node names. It is the recommended file to show to engineers when reviewing semantic recovery output.

### Pipe-First Recognition

The pipe-first recognizer uses `AUTO_PIPE_*` naming conventions when present:

- `AUTO_PIPE_<n>_grid_pt_*` becomes the route node sequence.
- `AUTO_PIPE_<n>_grid_seg_*` becomes straight pipe segment evidence.
- `AUTO_PIPE_<n>_start_nozzle_escape_stub_*` and `AUTO_PIPE_<n>_end_nozzle_escape_stub_*` become start/end nozzle evidence.
- `AUTO_PIPE_<n>_grid_status` and similar nodes are treated as pipe-related inline/status parts.
- `AUTO_PIPE_<n>_grid_rejected_text` is reported as a rejected or incomplete route, not as a successful pipeline.

A valid routed pipe is promoted into `payload["pipelines"]` with:

- `id`: pipe id, for example `AUTO_PIPE_0`
- `owners`: start and end nozzle node names
- `port_ids`: generated start/end semantic ports
- `attrs["resolution_basis"]`: `auto_pipe_route_semantics`
- `attrs["resolved_topology"]`: `True`
- `attrs["route_point_names"]`: ordered route node names
- `attrs["route_segment_names"]`: straight segment node names
- `attrs["inline_part_names"]`: pipe-related inline or endpoint parts

Rejected or incomplete routes remain in `payload["pipe_semantics"]` with unresolved fields such as `route_polyline`, but they are not promoted into successful `pipelines`.

### Example Semantic Text

The human-readable report describes pipes by node names:

```text
AUTO_PIPE_0 从 AUTO_PIPE_0_start_nozzle_escape_stub_red 连接到 AUTO_PIPE_0_end_nozzle_escape_stub_red。
路径包含 6 个路径点、5 个直管段。
路径: AUTO_PIPE_0_grid_pt_00 -> AUTO_PIPE_0_grid_pt_01 -> AUTO_PIPE_0_grid_pt_02 -> AUTO_PIPE_0_grid_pt_03 -> AUTO_PIPE_0_grid_pt_04 -> AUTO_PIPE_0_grid_pt_05。
中间/端部部件: AUTO_PIPE_0_end_nozzle_escape_stub_red(管嘴/端部短节), AUTO_PIPE_0_grid_status(管道相关构件), AUTO_PIPE_0_start_nozzle_escape_stub_red(管嘴/端部短节)。
邻近障碍物候选: 暂未发现。
切近墙壁/塔壁/壳体候选: 暂未发现。
```

The compact Markdown topology section looks like:

```text
## Pipeline Topology

- `AUTO_PIPE_0`: owners `AUTO_PIPE_0_start_nozzle_escape_stub_red -> AUTO_PIPE_0_end_nozzle_escape_stub_red`, ports `2`, naming_resolved `True`, resolved `True`, route_geoms `5`, route_path `True`, basis `auto_pipe_route_semantics`
  - route_nodes: AUTO_PIPE_0_grid_pt_00 -> AUTO_PIPE_0_grid_pt_01 -> AUTO_PIPE_0_grid_pt_02 -> AUTO_PIPE_0_grid_pt_03 -> AUTO_PIPE_0_grid_pt_04 -> AUTO_PIPE_0_grid_pt_05
  - route_segments: AUTO_PIPE_0_grid_seg_01, AUTO_PIPE_0_grid_seg_02, AUTO_PIPE_0_grid_seg_03, AUTO_PIPE_0_grid_seg_04, AUTO_PIPE_0_grid_seg_05
  - inline_parts: AUTO_PIPE_0_end_nozzle_escape_stub_red, AUTO_PIPE_0_grid_status, AUTO_PIPE_0_start_nozzle_escape_stub_red
```

### Result Validation Checklist

For a successful pipe recovery run, check:

- `payload["pipe_semantics"]` contains the recovered `AUTO_PIPE_*` descriptions.
- `payload["pipelines"]` contains every routed pipe that has at least two route nodes and at least one route segment.
- The compact `.md` report has a non-empty `Pipeline Topology` section.
- The semantic text report describes pipes using node names instead of raw coordinates.
- Rejected routes are reported as incomplete and are not counted as resolved pipelines.

### Current Limits

The current engine is strongest for named automatic pipe routing output. Device, valve, obstacle, wall, tower, and shell recognition is still conservative. When those objects cannot be uniquely classified, the report uses candidate or unresolved fields instead of inventing a false semantic binding.

## Installation

```bash
pip install phg_vis
```

Install from source:

```bash
pip install .
```

Optional extras:

```bash
pip install .[shader]
pip install .[process]
```

## Quick Start

Interactive VIS render:

```python
from pathlib import Path
import phg

script = Path("scene.phg").read_text(encoding="utf-8")
phg.visualize(script, mode="vis")
```

PNG render:

```python
from pathlib import Path
from phg.visphg import image

script = Path("scene.phg").read_text(encoding="utf-8")
image(script, "scene.png")
```

Inline script:

```python
import phg

script = """
{
  sample{
    md:cylinder 0.25 3;
    rgb:120,180,255;
  }
}
setup();
draw('/sample');
"""

phg.visualize(script, mode="vis")
```

## PHG Syntax Requirements

Use one anonymous root block:

```phg
{
  scene{
    part{md:cylinder 0.25 3;}
  }
}
setup();
draw('/scene/part');
```

Avoid putting a named node directly at file root:

```phg
scene{
  part{md:cylinder 0.25 3;}
}
setup();
draw('scene');
```

Use spaces for `md:` parameters and commas for vectors:

```phg
{
  part{
    md:cylinder 0.25 3;
    xyz:1,2,3;
  }
}
```

## Path Nodes

PHG supports path-style node names:

```phg
{
  a/b/c{
    md:sphere 0.2;
    xyz:0,0,0;
  }
}
setup();
draw('/a/b/c');
```

Rules:

- `a/b/c{...}` creates or reuses the parent-child chain `a -> b -> c`.
- `/a/b/c` is an absolute path from the PHG root.
- `a/b/c` without a leading slash is relative to the current scope.
- `/` is a path separator unless it starts `//` or `/* ... */`.
- Use ASCII path segments for portable scripts.
- Do not use disk paths as node names. Put disk paths in quoted property values or function arguments.

## Local-First Node References

Node references are resolved from the local scope first, then upward through parent scopes.

This allows independent parent nodes to reuse child names safely:

```phg
{
  A{
    a{md:cylinder 0.3 1.0;}
    b{md:box 0.6 0.6 0.6;}
    u{md:bool union a b;}
  }

  B{
    a{md:cylinder 0.3 1.0; xyz:2,0,0;}
    b{md:box 0.6 0.6 0.6; xyz:2,0,0;}
    d{md:bool diff a b;}
  }
}
setup();
draw('/A/u');
draw('/B/d');
```

In `A/u`, `a` and `b` resolve under `A`. In `B/d`, `a` and `b` resolve under `B`.

Use absolute paths for intentional cross-scope references:

```phg
{
  shared{
    cutter{md:cylinder 0.2 2.0;}
  }

  part{
    body{md:box 1 1 1;}
    cut{md:bool diff body /shared/cutter;}
  }
}
setup();
draw('/part/cut');
```

## Boolean Script Guidance

Boolean nodes should reference stable geometry nodes that already exist in the relevant scope.

Recommended abstract form:

```phg
result{md:bool <op> <left_node> <right_node>;}
```

Recommended operation names:

- `union` / `add`
- `diff` / `sub`
- `intersect` / `int`

For large scenes, group boolean operands under their owner node. Avoid a flat global namespace with many repeated names.

## Inline PHG Expressions

Node bodies may contain inline PHG execution blocks:

```phg
{
  part{
    (r = 0.25;)
    md:cylinder 0.25 1.0;
  }
}
setup();
draw('/part');
```

Guidance:

- Inline expressions execute in the current node scope.
- Keep expression blocks small.
- Do not put long-running procedural modeling algorithms in PHG expressions.
- Final normalized node properties should still be constants.

## VIS Viewer Behavior

The canonical viewer executable is:

```text
vis.exe
```

Do not depend on temporary names such as `vis_fixed.exe`.

Dragpad behavior:

1. Attempts the configured VIS host.
2. If the remote host is unavailable within the short probe window, switches to local mode.
3. Starts local `vis.exe` if needed.
4. Waits for local VIS startup before sending PHG content.
5. Reads files through Unicode-safe paths.

Default Dragpad configuration:

```ini
[Paths]
ServerPath=vis.exe
ScenePath=./dat

[Network]
IpAddress=127.0.0.1
```

## Configuration

### `phg/vis/config.ini`

```ini
[Paths]
rvmReader=
wlkxReader=
meshRoot=./
```

Reader paths are blank by default. Configure them at deployment time.

### `phg/vis/vis.ini`

```ini
AUTO_FOCUS=true
CONSOLE=true
COORD_HAND=LH
COORD_MIRROR_Z=false
COORD_UP=YUP
ENABLE_DUAL_SCREEN=false
HOSTIP=127.0.0.1
LAST_MESH_PATH=./
RECORD_FPS=12
SCREENSHOT_PATH=
meshRoot=./
```

Blank `SCREENSHOT_PATH` uses the viewer runtime default.

## Diagnostics

Two diagnostic layers may be enabled in the bundled runtime.

VIS-side log:

```text
vis_phg_diagnostics.log
```

Typical phases:

```text
enter
doPHG_begin
doPHG_end
setup_mesh_begin
setup_mesh_end
focus_begin
focus_end
done
```

ScePHG/GCU-side log:

```text
scephg_diagnostics.log
```

Typical phases:

```text
doPHG_enter
lock_acquired
init_done
auto_clear_begin
auto_clear_end
runtime_state_clear
script_ready
dostring_begin
dostring_end
doPHG_leave
```

Build-time diagnostic switches:

```cpp
VIS_ENABLE_PHG_DIAGNOSTICS
SCEPHG_ENABLE_DIAGNOSTICS
```

Set them to `0` in a production build to compile the diagnostic functions as no-ops.

## Remote And Local Viewer Use

For a running VIS server:

```bash
curl -X POST http://127.0.0.1:5088/phg --data-binary @scene.phg
```

For scripted Python use, prefer:

```python
import phg
phg.visualize(script, mode="vis")
```

## AI Bridge Configuration

The optional AI bridge does not ship with a machine-specific default path.

Configure it with:

```bash
set PHG_AI_ROOT=<path-to-ai-phg-root>
```

or pass `ai_root=` explicitly:

```python
phg.visualize(script, mode="web", ai=True, ai_root="path/to/ai/phg")
```

The optional natural-language service reads:

```bash
set PHG_NL_AI_PATH=<path-to-intelligent-modeling-ai-src>
```

If this variable is not set, the service falls back to its built-in simple parser path where available.

## Regression PHG Scripts

Use these minimal scripts after runtime updates.

Basic:

```phg
{
  a{
    md:sphere 0.2;
    xyz:0,0,0;
  }
}
setup();
draw('/a');
```

Path node:

```phg
{
  a/b/c{
    md:sphere 0.2;
    xyz:0,0,0;
  }
}
setup();
draw('/a/b/c');
```

Path-node parse only:

```phg
{
  a/b/c{
    md:sphere 0.2;
    xyz:0,0,0;
  }
};
```

Expected result:

```text
VIS stays responsive.
VIS diagnostics reach done.
ScePHG diagnostics reach doPHG_leave.
```

## Packaging Rules

- Package `vis.exe`, `GCU.dll`, `dragpad.exe`, and required runtime DLLs together.
- Do not package local log files as release evidence.
- Do not package user-specific paths.
- Use environment variables for optional external tools.
- Keep `setup.py` version and `phg.__version__` synchronized.

## License

MIT
