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.
@@ -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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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()