tcv-screenshots 0.3.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.
- tcv_screenshots-0.3.0/PKG-INFO +145 -0
- tcv_screenshots-0.3.0/README.md +132 -0
- tcv_screenshots-0.3.0/pyproject.toml +22 -0
- tcv_screenshots-0.3.0/setup.cfg +4 -0
- tcv_screenshots-0.3.0/tcv_screenshots/__init__.py +40 -0
- tcv_screenshots-0.3.0/tcv_screenshots/__main__.py +76 -0
- tcv_screenshots-0.3.0/tcv_screenshots/render.py +345 -0
- tcv_screenshots-0.3.0/tcv_screenshots/three-cad-viewer.css +1255 -0
- tcv_screenshots-0.3.0/tcv_screenshots/three-cad-viewer.js +91508 -0
- tcv_screenshots-0.3.0/tcv_screenshots/viewer.html +77 -0
- tcv_screenshots-0.3.0/tcv_screenshots.egg-info/PKG-INFO +145 -0
- tcv_screenshots-0.3.0/tcv_screenshots.egg-info/SOURCES.txt +13 -0
- tcv_screenshots-0.3.0/tcv_screenshots.egg-info/dependency_links.txt +1 -0
- tcv_screenshots-0.3.0/tcv_screenshots.egg-info/requires.txt +5 -0
- tcv_screenshots-0.3.0/tcv_screenshots.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tcv-screenshots
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Headless screenshot generator for three-cad-viewer
|
|
5
|
+
Author: Bernhard Walter
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: playwright>=1.40.0
|
|
10
|
+
Requires-Dist: ocp_tessellate
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: build; extra == "dev"
|
|
13
|
+
|
|
14
|
+
# tcv-screenshots
|
|
15
|
+
|
|
16
|
+
Headless screenshot generator for three-cad-viewer. Render 3D CAD models to PNG screenshots.
|
|
17
|
+
|
|
18
|
+
## Supported Platforms
|
|
19
|
+
|
|
20
|
+
- Linux (Intel, ARM)
|
|
21
|
+
- Windows (Intel)
|
|
22
|
+
- macOS (Intel, Apple Silicon)
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install tcv-screenshots
|
|
28
|
+
playwright install chromium
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If you use build123d for creating 3D objects, `build123d` neeeds to be installed, similar for CadQuery.
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Single file (output to current directory)
|
|
37
|
+
python -m tcv_screenshots -f example.py
|
|
38
|
+
|
|
39
|
+
# Single file with output folder
|
|
40
|
+
python -m tcv_screenshots -f example.py -o screenshots
|
|
41
|
+
|
|
42
|
+
# Directory of examples (requires -o)
|
|
43
|
+
python -m tcv_screenshots -d examples -o screenshots
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Options:**
|
|
47
|
+
|
|
48
|
+
- `-f, --file FILE` - Single Python example file to process
|
|
49
|
+
- `-d, --directory DIR` - Directory containing Python example files (requires -o)
|
|
50
|
+
- `-o, --output-folder DIR` - Output directory for PNG screenshots
|
|
51
|
+
- `--no-headless` - Show browser window (for debugging)
|
|
52
|
+
- `--pause` - Pause before each screenshot (for debugging)
|
|
53
|
+
- `--debug MODELS_DIR` - Save JSON model files to directory (for debugging)
|
|
54
|
+
|
|
55
|
+
## Writing Examples
|
|
56
|
+
|
|
57
|
+
Create a Python file with a `main()` function that uses `save_model` and returns `get_saved_models()`:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from build123d import *
|
|
61
|
+
|
|
62
|
+
model = Box(10, 20, 30)
|
|
63
|
+
|
|
64
|
+
def main():
|
|
65
|
+
from tcv_screenshots import save_model, get_saved_models
|
|
66
|
+
|
|
67
|
+
save_model(model, "box", {"cadWidth": 800, "height": 600})
|
|
68
|
+
return get_saved_models()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Multiple Models per Example
|
|
72
|
+
|
|
73
|
+
For incremental examples that need screenshots at different stages:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from build123d import *
|
|
77
|
+
|
|
78
|
+
# Step 1: Create base box
|
|
79
|
+
box = Box(10, 10, 10)
|
|
80
|
+
|
|
81
|
+
# Step 2: Add fillet
|
|
82
|
+
filleted = fillet(box.edges(), 1)
|
|
83
|
+
|
|
84
|
+
# Step 3: Add hole
|
|
85
|
+
final = filleted - Cylinder(2, 10)
|
|
86
|
+
|
|
87
|
+
def main():
|
|
88
|
+
from tcv_screenshots import save_model, get_saved_models
|
|
89
|
+
|
|
90
|
+
config = {"cadWidth": 500, "height": 375}
|
|
91
|
+
|
|
92
|
+
save_model(box, "step1_box", config)
|
|
93
|
+
save_model(filleted, "step2_fillet", config)
|
|
94
|
+
save_model(final, "step3_hole", {**config, "render_edges": False})
|
|
95
|
+
|
|
96
|
+
return get_saved_models()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
This generates `step1_box.png`, `step2_fillet.png`, and `step3_hole.png`.
|
|
100
|
+
|
|
101
|
+
### Available Config Options
|
|
102
|
+
|
|
103
|
+
See [VS Code CAD Viewer's show command](https://github.com/bernhard-42/vscode-ocp-cad-viewer/blob/main/docs/show.md)
|
|
104
|
+
|
|
105
|
+
#### Examples
|
|
106
|
+
|
|
107
|
+
**Display options:**
|
|
108
|
+
|
|
109
|
+
- `cadWidth` - Viewport width (default: 1200)
|
|
110
|
+
- `height` - Viewport height (default: 800)
|
|
111
|
+
- `treeWidth` - Tree panel width (default: 0)
|
|
112
|
+
- `theme` - 'light' or 'dark' (default: 'light')
|
|
113
|
+
- `glass` - Glass mode (default: True)
|
|
114
|
+
- `tools` - Show tools (default: False)
|
|
115
|
+
|
|
116
|
+
**Render options:**
|
|
117
|
+
|
|
118
|
+
- `ambientIntensity` - Ambient light intensity (default: 1.0)
|
|
119
|
+
- `directIntensity` - Direct light intensity (default: 1.1)
|
|
120
|
+
- `metalness` - Material metalness (default: 0.3)
|
|
121
|
+
- `roughness` - Material roughness (default: 0.65)
|
|
122
|
+
- `edgeColor` - Edge color as hex int (default: 0x707070)
|
|
123
|
+
- `render_edges` - Show edges (default: True)
|
|
124
|
+
- `render_faces` - Show faces (default: True)
|
|
125
|
+
|
|
126
|
+
**Viewer options:**
|
|
127
|
+
|
|
128
|
+
- `ortho` - Orthographic projection (default: True)
|
|
129
|
+
- `control` - Control type (default: 'trackball')
|
|
130
|
+
- `up` - Up axis: 'Z' or 'Y' (default: 'Z')
|
|
131
|
+
- `tab` - Active tab: 'tree', 'clip', 'material'
|
|
132
|
+
- `reset_camera` - Camera view: 'iso', 'front', 'rear', 'left', 'right', 'top', 'bottom'
|
|
133
|
+
|
|
134
|
+
## CI/CD
|
|
135
|
+
|
|
136
|
+
`tcv_screenshots` can be used in CI/CD workflows, an example can seen in [.github/workflows/screenshots.yml](.github/workflows/screenshots.yml)
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
Build the wheel:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pip install build
|
|
144
|
+
python -m build
|
|
145
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# tcv-screenshots
|
|
2
|
+
|
|
3
|
+
Headless screenshot generator for three-cad-viewer. Render 3D CAD models to PNG screenshots.
|
|
4
|
+
|
|
5
|
+
## Supported Platforms
|
|
6
|
+
|
|
7
|
+
- Linux (Intel, ARM)
|
|
8
|
+
- Windows (Intel)
|
|
9
|
+
- macOS (Intel, Apple Silicon)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install tcv-screenshots
|
|
15
|
+
playwright install chromium
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
If you use build123d for creating 3D objects, `build123d` neeeds to be installed, similar for CadQuery.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Single file (output to current directory)
|
|
24
|
+
python -m tcv_screenshots -f example.py
|
|
25
|
+
|
|
26
|
+
# Single file with output folder
|
|
27
|
+
python -m tcv_screenshots -f example.py -o screenshots
|
|
28
|
+
|
|
29
|
+
# Directory of examples (requires -o)
|
|
30
|
+
python -m tcv_screenshots -d examples -o screenshots
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Options:**
|
|
34
|
+
|
|
35
|
+
- `-f, --file FILE` - Single Python example file to process
|
|
36
|
+
- `-d, --directory DIR` - Directory containing Python example files (requires -o)
|
|
37
|
+
- `-o, --output-folder DIR` - Output directory for PNG screenshots
|
|
38
|
+
- `--no-headless` - Show browser window (for debugging)
|
|
39
|
+
- `--pause` - Pause before each screenshot (for debugging)
|
|
40
|
+
- `--debug MODELS_DIR` - Save JSON model files to directory (for debugging)
|
|
41
|
+
|
|
42
|
+
## Writing Examples
|
|
43
|
+
|
|
44
|
+
Create a Python file with a `main()` function that uses `save_model` and returns `get_saved_models()`:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from build123d import *
|
|
48
|
+
|
|
49
|
+
model = Box(10, 20, 30)
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
from tcv_screenshots import save_model, get_saved_models
|
|
53
|
+
|
|
54
|
+
save_model(model, "box", {"cadWidth": 800, "height": 600})
|
|
55
|
+
return get_saved_models()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Multiple Models per Example
|
|
59
|
+
|
|
60
|
+
For incremental examples that need screenshots at different stages:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from build123d import *
|
|
64
|
+
|
|
65
|
+
# Step 1: Create base box
|
|
66
|
+
box = Box(10, 10, 10)
|
|
67
|
+
|
|
68
|
+
# Step 2: Add fillet
|
|
69
|
+
filleted = fillet(box.edges(), 1)
|
|
70
|
+
|
|
71
|
+
# Step 3: Add hole
|
|
72
|
+
final = filleted - Cylinder(2, 10)
|
|
73
|
+
|
|
74
|
+
def main():
|
|
75
|
+
from tcv_screenshots import save_model, get_saved_models
|
|
76
|
+
|
|
77
|
+
config = {"cadWidth": 500, "height": 375}
|
|
78
|
+
|
|
79
|
+
save_model(box, "step1_box", config)
|
|
80
|
+
save_model(filleted, "step2_fillet", config)
|
|
81
|
+
save_model(final, "step3_hole", {**config, "render_edges": False})
|
|
82
|
+
|
|
83
|
+
return get_saved_models()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This generates `step1_box.png`, `step2_fillet.png`, and `step3_hole.png`.
|
|
87
|
+
|
|
88
|
+
### Available Config Options
|
|
89
|
+
|
|
90
|
+
See [VS Code CAD Viewer's show command](https://github.com/bernhard-42/vscode-ocp-cad-viewer/blob/main/docs/show.md)
|
|
91
|
+
|
|
92
|
+
#### Examples
|
|
93
|
+
|
|
94
|
+
**Display options:**
|
|
95
|
+
|
|
96
|
+
- `cadWidth` - Viewport width (default: 1200)
|
|
97
|
+
- `height` - Viewport height (default: 800)
|
|
98
|
+
- `treeWidth` - Tree panel width (default: 0)
|
|
99
|
+
- `theme` - 'light' or 'dark' (default: 'light')
|
|
100
|
+
- `glass` - Glass mode (default: True)
|
|
101
|
+
- `tools` - Show tools (default: False)
|
|
102
|
+
|
|
103
|
+
**Render options:**
|
|
104
|
+
|
|
105
|
+
- `ambientIntensity` - Ambient light intensity (default: 1.0)
|
|
106
|
+
- `directIntensity` - Direct light intensity (default: 1.1)
|
|
107
|
+
- `metalness` - Material metalness (default: 0.3)
|
|
108
|
+
- `roughness` - Material roughness (default: 0.65)
|
|
109
|
+
- `edgeColor` - Edge color as hex int (default: 0x707070)
|
|
110
|
+
- `render_edges` - Show edges (default: True)
|
|
111
|
+
- `render_faces` - Show faces (default: True)
|
|
112
|
+
|
|
113
|
+
**Viewer options:**
|
|
114
|
+
|
|
115
|
+
- `ortho` - Orthographic projection (default: True)
|
|
116
|
+
- `control` - Control type (default: 'trackball')
|
|
117
|
+
- `up` - Up axis: 'Z' or 'Y' (default: 'Z')
|
|
118
|
+
- `tab` - Active tab: 'tree', 'clip', 'material'
|
|
119
|
+
- `reset_camera` - Camera view: 'iso', 'front', 'rear', 'left', 'right', 'top', 'bottom'
|
|
120
|
+
|
|
121
|
+
## CI/CD
|
|
122
|
+
|
|
123
|
+
`tcv_screenshots` can be used in CI/CD workflows, an example can seen in [.github/workflows/screenshots.yml](.github/workflows/screenshots.yml)
|
|
124
|
+
|
|
125
|
+
## Development
|
|
126
|
+
|
|
127
|
+
Build the wheel:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pip install build
|
|
131
|
+
python -m build
|
|
132
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=80", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tcv-screenshots"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "Headless screenshot generator for three-cad-viewer"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
authors = [{ name = "Bernhard Walter" }]
|
|
13
|
+
dependencies = ["playwright>=1.40.0", "ocp_tessellate"]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
dev = ["build"]
|
|
17
|
+
|
|
18
|
+
[tool.setuptools.packages.find]
|
|
19
|
+
include = ["tcv_screenshots*"]
|
|
20
|
+
|
|
21
|
+
[tool.setuptools.package-data]
|
|
22
|
+
tcv_screenshots = ["*.html", "*.js", "*.css"]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Headless screenshot generator for three-cad-viewer."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
# Model collector for incremental examples
|
|
6
|
+
_saved_models = []
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def save_model(model, name: str, config: dict = None):
|
|
10
|
+
"""
|
|
11
|
+
Save a model for later export.
|
|
12
|
+
|
|
13
|
+
Call this at different points in your example code to capture
|
|
14
|
+
incremental states. Then have main() return get_saved_models().
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
model: CAD object to render
|
|
18
|
+
name: Unique name for this snapshot (used in filename)
|
|
19
|
+
config: Optional config overrides
|
|
20
|
+
"""
|
|
21
|
+
_saved_models.append((model, name, config or {}))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_saved_models() -> list:
|
|
25
|
+
"""
|
|
26
|
+
Get all saved models and clear the collector.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
List of (model, name, config) tuples
|
|
30
|
+
"""
|
|
31
|
+
global _saved_models
|
|
32
|
+
models = _saved_models.copy()
|
|
33
|
+
_saved_models = []
|
|
34
|
+
return models
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def clear_saved_models():
|
|
38
|
+
"""Clear the saved models collector."""
|
|
39
|
+
global _saved_models
|
|
40
|
+
_saved_models = []
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Entry point for python -m tcv_screenshots."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from .render import run
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
parser = argparse.ArgumentParser(
|
|
13
|
+
prog="tcv_screenshots",
|
|
14
|
+
description="Generate screenshots from CAD examples using three-cad-viewer"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Input source (mutually exclusive)
|
|
18
|
+
input_group = parser.add_mutually_exclusive_group(required=True)
|
|
19
|
+
input_group.add_argument(
|
|
20
|
+
"-f", "--file",
|
|
21
|
+
type=Path,
|
|
22
|
+
help="Single Python example file to process",
|
|
23
|
+
)
|
|
24
|
+
input_group.add_argument(
|
|
25
|
+
"-d", "--directory",
|
|
26
|
+
type=Path,
|
|
27
|
+
help="Directory containing Python example files (requires -o)",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"-o", "--output-folder",
|
|
32
|
+
type=Path,
|
|
33
|
+
help="Output directory for PNG screenshots",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--no-headless",
|
|
37
|
+
action="store_true",
|
|
38
|
+
help="Run browser in visible mode (for debugging)",
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--pause",
|
|
42
|
+
action="store_true",
|
|
43
|
+
help="Pause before each screenshot (for debugging)",
|
|
44
|
+
)
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--debug",
|
|
47
|
+
type=Path,
|
|
48
|
+
metavar="MODELS_DIR",
|
|
49
|
+
help="Save JSON model files to this directory (for debugging)",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
args = parser.parse_args()
|
|
53
|
+
|
|
54
|
+
# Validate: -d requires -o
|
|
55
|
+
if args.directory and not args.output_folder:
|
|
56
|
+
parser.error("-d/--directory requires -o/--output-folder")
|
|
57
|
+
|
|
58
|
+
# Determine input files and output directory
|
|
59
|
+
if args.file:
|
|
60
|
+
example_files = [args.file.resolve()]
|
|
61
|
+
screenshots_dir = args.output_folder.resolve() if args.output_folder else Path.cwd()
|
|
62
|
+
else:
|
|
63
|
+
example_files = args.directory.resolve()
|
|
64
|
+
screenshots_dir = args.output_folder.resolve()
|
|
65
|
+
|
|
66
|
+
run(
|
|
67
|
+
examples=example_files,
|
|
68
|
+
screenshots_dir=screenshots_dir,
|
|
69
|
+
headless=not args.no_headless,
|
|
70
|
+
pause=args.pause,
|
|
71
|
+
debug_models_dir=args.debug.resolve() if args.debug else None,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
main()
|