DeepSDFStruct 1.7.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.
- DeepSDFStruct/SDF.py +1734 -0
- DeepSDFStruct/__init__.py +66 -0
- DeepSDFStruct/deep_sdf/__init__.py +69 -0
- DeepSDFStruct/deep_sdf/create_screenshots_from_plyfiles.py +65 -0
- DeepSDFStruct/deep_sdf/data.py +258 -0
- DeepSDFStruct/deep_sdf/metrics/__init__.py +14 -0
- DeepSDFStruct/deep_sdf/metrics/mesh_to_analytical.py +24 -0
- DeepSDFStruct/deep_sdf/models.py +197 -0
- DeepSDFStruct/deep_sdf/networks/__init__.py +8 -0
- DeepSDFStruct/deep_sdf/networks/analytic_round_cross.py +105 -0
- DeepSDFStruct/deep_sdf/networks/deep_sdf_decoder.py +155 -0
- DeepSDFStruct/deep_sdf/networks/hierarchical_deep_sdf_decoder.py +139 -0
- DeepSDFStruct/deep_sdf/networks/hierarchical_positional_sdf_decoder.py +190 -0
- DeepSDFStruct/deep_sdf/networks/resnet_positional_sdf_decoder.py +108 -0
- DeepSDFStruct/deep_sdf/nn_utils.py +70 -0
- DeepSDFStruct/deep_sdf/plotting.py +143 -0
- DeepSDFStruct/deep_sdf/reconstruction.py +165 -0
- DeepSDFStruct/deep_sdf/training.py +840 -0
- DeepSDFStruct/deep_sdf/workspace.py +363 -0
- DeepSDFStruct/design_of_experiments.py +235 -0
- DeepSDFStruct/flexicubes/__init__.py +15 -0
- DeepSDFStruct/flexicubes/flexicubes.py +1005 -0
- DeepSDFStruct/flexicubes/tables.py +2338 -0
- DeepSDFStruct/flexisquares/__init__.py +15 -0
- DeepSDFStruct/flexisquares/flexisquares.py +967 -0
- DeepSDFStruct/flexisquares/tables.py +63 -0
- DeepSDFStruct/lattice_structure.py +254 -0
- DeepSDFStruct/local_shapes.py +226 -0
- DeepSDFStruct/mesh.py +1184 -0
- DeepSDFStruct/optimization.py +357 -0
- DeepSDFStruct/parametrization.py +215 -0
- DeepSDFStruct/pretrained_models.py +128 -0
- DeepSDFStruct/sampling.py +670 -0
- DeepSDFStruct/sdf_operations.py +990 -0
- DeepSDFStruct/sdf_primitives.py +1416 -0
- DeepSDFStruct/splinepy_unitcells/__init__.py +35 -0
- DeepSDFStruct/splinepy_unitcells/chi_3D.py +1617 -0
- DeepSDFStruct/splinepy_unitcells/cross_lattice.py +165 -0
- DeepSDFStruct/splinepy_unitcells/double_lattice_extruded.py +298 -0
- DeepSDFStruct/splinepy_unitcells/snappy_3d.py +544 -0
- DeepSDFStruct/torch_spline.py +446 -0
- DeepSDFStruct/trained_models/analytic_round_cross/LatentCodes/latest.pth +0 -0
- DeepSDFStruct/trained_models/analytic_round_cross/ModelParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/analytic_round_cross/OptimizerParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/analytic_round_cross/specs.json +45 -0
- DeepSDFStruct/trained_models/chi_and_cross/LatentCodes/latest.pth +0 -0
- DeepSDFStruct/trained_models/chi_and_cross/Logs.pth +0 -0
- DeepSDFStruct/trained_models/chi_and_cross/ModelParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/chi_and_cross/OptimizerParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/chi_and_cross/specs.json +76 -0
- DeepSDFStruct/trained_models/primitives/LatentCodes/latest.pth +0 -0
- DeepSDFStruct/trained_models/primitives/ModelParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/primitives/OptimizerParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/primitives/specs.json +46 -0
- DeepSDFStruct/trained_models/primitives_2d/LatentCodes/latest.pth +0 -0
- DeepSDFStruct/trained_models/primitives_2d/ModelParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/primitives_2d/OptimizerParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/primitives_2d/specs.json +46 -0
- DeepSDFStruct/trained_models/round_cross/LatentCodes/latest.pth +0 -0
- DeepSDFStruct/trained_models/round_cross/Logs.pth +0 -0
- DeepSDFStruct/trained_models/round_cross/ModelParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/round_cross/OptimizerParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/round_cross/specs.json +45 -0
- DeepSDFStruct/trained_models/test_experiment/LatentCodes/latent_code_data_map.json +106 -0
- DeepSDFStruct/trained_models/test_experiment/specs.json +45 -0
- DeepSDFStruct/trained_models/test_experiment/training_summary.json +10 -0
- DeepSDFStruct/trained_models/test_experiment_hierarchical/LatentCodes/latent_code_data_map.json +106 -0
- DeepSDFStruct/trained_models/test_experiment_hierarchical/specs.json +45 -0
- DeepSDFStruct/trained_models/test_experiment_hierarchical/training_summary.json +10 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/LatentCodes/latent_code_data_map.json +5006 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/LatentCodes/latest.pth +0 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/Logs.png +0 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/ModelParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/OptimizerParameters/latest.pth +0 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/specs.json +83 -0
- DeepSDFStruct/trained_models/test_experiment_homogenization/training_summary.json +10 -0
- DeepSDFStruct/utils.py +96 -0
- DeepSDFStruct/visualization/latent_viewer.py +211 -0
- DeepSDFStruct/visualization/latent_viewer_cli.py +8 -0
- benchmarks/generate_sdf_showcase.py +622 -0
- benchmarks/sdf_from_mesh_benchmark.py +52 -0
- benchmarks/sdf_from_mesh_comparison.md +33 -0
- benchmarks/sdf_showcase/operations/boolean/difference_sphere_box.png +0 -0
- benchmarks/sdf_showcase/operations/boolean/union_sphere_box.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/circular_array_sphere.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/dilate_sphere.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/mirror_sphere.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/repeat_sphere.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/revolve_circle.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/shell_sphere.png +0 -0
- benchmarks/sdf_showcase/operations/transformations/twist_torus.png +0 -0
- benchmarks/sdf_showcase/primitives/2D/circle.png +0 -0
- benchmarks/sdf_showcase/primitives/2D/equilateral_triangle.png +0 -0
- benchmarks/sdf_showcase/primitives/2D/hexagon.png +0 -0
- benchmarks/sdf_showcase/primitives/2D/polygon_pentagon.png +0 -0
- benchmarks/sdf_showcase/primitives/2D/rectangle.png +0 -0
- benchmarks/sdf_showcase/primitives/2D/rounded_rectangle.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/box.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/capped_cone.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/capped_cylinder.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/capsule.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/cone.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/corner_spheres.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/cross_ms.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/cylinder.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/dodecahedron.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/ellipsoid.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/icosahedron.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/octahedron.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/pyramid.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/rounded_box.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/rounded_cone.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/rounded_cylinder.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/sphere.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/tetrahedron.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/torus.png +0 -0
- benchmarks/sdf_showcase/primitives/3D/wireframe_box.png +0 -0
- deepsdfstruct-1.7.2.dist-info/METADATA +44 -0
- deepsdfstruct-1.7.2.dist-info/RECORD +165 -0
- deepsdfstruct-1.7.2.dist-info/WHEEL +5 -0
- deepsdfstruct-1.7.2.dist-info/licenses/LICENSE +208 -0
- deepsdfstruct-1.7.2.dist-info/licenses/NOTICE +67 -0
- deepsdfstruct-1.7.2.dist-info/scm_file_list.json +178 -0
- deepsdfstruct-1.7.2.dist-info/scm_version.json +8 -0
- deepsdfstruct-1.7.2.dist-info/top_level.txt +4 -0
- docs/Makefile +20 -0
- docs/api_reference.rst +6 -0
- docs/conf.py +60 -0
- docs/index.rst +136 -0
- docs/make.bat +35 -0
- docs/qr_code_github.png +0 -0
- docs/qr_code_paper.png +0 -0
- docs/readme_images/example_output_01.png +0 -0
- docs/readme_images/example_output_02.png +0 -0
- docs/readme_images/example_output_03.png +0 -0
- docs/readme_images/example_output_04.png +0 -0
- tests/data/chairs/1005.obj +282 -0
- tests/data/chairs/1024.obj +222 -0
- tests/data/chairs/README.md +1 -0
- tests/data/circular_balls_test_case.stl +0 -0
- tests/data/cone.stl +1794 -0
- tests/data/example_disconnectd_mesh.inp +1784 -0
- tests/data/example_line_mesh.vtk +0 -0
- tests/data/stanford_bunny.stl +0 -0
- tests/data/sweep_test_case.stl +0 -0
- tests/test_DOE.py +49 -0
- tests/test_elongate_sdf.py +195 -0
- tests/test_flexisquares.py +187 -0
- tests/test_generate_dataset.py +76 -0
- tests/test_lattice_evaluation.py +137 -0
- tests/test_mesh_export.py +137 -0
- tests/test_mesh_functions.py +49 -0
- tests/test_networks.py +71 -0
- tests/test_pretrained_models.py +40 -0
- tests/test_reconstruction.py +101 -0
- tests/test_sdf_from_mesh.py +52 -0
- tests/test_sdf_functions.py +117 -0
- tests/test_sdf_primitives.py +668 -0
- tests/test_sdf_trimesh_comparison.py +482 -0
- tests/test_splinepy_unitcells.py +64 -0
- tests/test_structural_optimization.py +178 -0
- tests/test_torch_spline.py +216 -0
- tests/test_train_model.py +110 -0
- tests/test_training_data_ids.py +41 -0
- tests/tmp_outputs/temp_file.txt +0 -0
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SDF Primitive and Operation Showcase
|
|
3
|
+
====================================
|
|
4
|
+
|
|
5
|
+
This script generates visual examples of all SDF primitives and operations
|
|
6
|
+
implemented in DeepSDFStruct, creating screenshots suitable for documentation.
|
|
7
|
+
|
|
8
|
+
The workflow:
|
|
9
|
+
1. Create an SDF (primitive or operation)
|
|
10
|
+
2. Generate a 3D mesh using create_3D_mesh()
|
|
11
|
+
3. Convert to gustaf format with .to_gus()
|
|
12
|
+
4. Create screenshots using vedo
|
|
13
|
+
5. Save to organized directory structure
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
uv run python benchmarks/generate_sdf_showcase.py
|
|
17
|
+
|
|
18
|
+
Output:
|
|
19
|
+
benchmarks/sdf_showcase/
|
|
20
|
+
├── primitives/
|
|
21
|
+
│ ├── 3D/
|
|
22
|
+
│ │ ├── sphere.png
|
|
23
|
+
│ │ ├── box.png
|
|
24
|
+
│ │ ├── ...
|
|
25
|
+
│ └── 2D/
|
|
26
|
+
│ ├── circle.png
|
|
27
|
+
│ ├── ...
|
|
28
|
+
└── operations/
|
|
29
|
+
├── boolean/
|
|
30
|
+
└── transformations/
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import sys
|
|
34
|
+
import os
|
|
35
|
+
import pathlib
|
|
36
|
+
import numpy as np
|
|
37
|
+
import torch
|
|
38
|
+
import vedo
|
|
39
|
+
import matplotlib.pyplot as plt
|
|
40
|
+
from typing import Optional, Tuple
|
|
41
|
+
|
|
42
|
+
# Add parent directory to import DeepSDFStruct
|
|
43
|
+
sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
|
|
44
|
+
|
|
45
|
+
from DeepSDFStruct.mesh import create_3D_mesh, create_2D_mesh
|
|
46
|
+
from DeepSDFStruct.sdf_primitives import (
|
|
47
|
+
# 3D Primitives
|
|
48
|
+
SphereSDF,
|
|
49
|
+
BoxSDF,
|
|
50
|
+
CylinderSDF,
|
|
51
|
+
ConeSDF,
|
|
52
|
+
TorusSDF,
|
|
53
|
+
PlaneSDF,
|
|
54
|
+
RoundedBoxSDF,
|
|
55
|
+
WireframeBoxSDF,
|
|
56
|
+
CapsuleSDF,
|
|
57
|
+
EllipsoidSDF,
|
|
58
|
+
PyramidSDF,
|
|
59
|
+
CornerSpheresSDF,
|
|
60
|
+
CrossMsSDF,
|
|
61
|
+
RoundedCylinderSDF,
|
|
62
|
+
CappedConeSDF,
|
|
63
|
+
RoundedConeSDF,
|
|
64
|
+
TetrahedronSDF,
|
|
65
|
+
OctahedronSDF,
|
|
66
|
+
DodecahedronSDF,
|
|
67
|
+
IcosahedronSDF,
|
|
68
|
+
# 2D Primitives
|
|
69
|
+
CircleSDF,
|
|
70
|
+
RectangleSDF,
|
|
71
|
+
LineSDF,
|
|
72
|
+
RoundedRectangleSDF,
|
|
73
|
+
EquilateralTriangleSDF,
|
|
74
|
+
HexagonSDF,
|
|
75
|
+
PolygonSDF,
|
|
76
|
+
)
|
|
77
|
+
from DeepSDFStruct.sdf_operations import (
|
|
78
|
+
ElongateSDF,
|
|
79
|
+
TwistSDF,
|
|
80
|
+
BendLinearSDF,
|
|
81
|
+
BendRadialSDF,
|
|
82
|
+
DilateSDF,
|
|
83
|
+
ErodeSDF,
|
|
84
|
+
ShellSDF,
|
|
85
|
+
RepeatSDF,
|
|
86
|
+
MirrorSDF,
|
|
87
|
+
CircularArraySDF,
|
|
88
|
+
RevolveSDF,
|
|
89
|
+
)
|
|
90
|
+
from DeepSDFStruct.SDF import UnionSDF, DifferenceSDF
|
|
91
|
+
|
|
92
|
+
# ==================== Configuration ====================
|
|
93
|
+
|
|
94
|
+
# Output directory structure
|
|
95
|
+
OUTPUT_DIR = pathlib.Path("benchmarks/sdf_showcase")
|
|
96
|
+
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
97
|
+
|
|
98
|
+
# Camera settings for consistent screenshots
|
|
99
|
+
CAMERA_SETTINGS = dict(
|
|
100
|
+
position=(2.5, 2.5, 2.5), focal_point=(0, 0, 0), viewup=(0, 0, 1)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ==================== Helper Functions ====================
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def create_screenshot(
|
|
108
|
+
sdf,
|
|
109
|
+
filename: str,
|
|
110
|
+
resolution: int = 64,
|
|
111
|
+
title: str = "",
|
|
112
|
+
background_color: Tuple[float, float, float] = (1.0, 1.0, 1.0),
|
|
113
|
+
mesh_color: str = "#6B9BD2",
|
|
114
|
+
) -> bool:
|
|
115
|
+
"""
|
|
116
|
+
Generate a screenshot from an SDF.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
sdf : SDFBase
|
|
121
|
+
The SDF to visualize
|
|
122
|
+
filename : str
|
|
123
|
+
Output filename (will be saved as .png)
|
|
124
|
+
resolution : int, optional
|
|
125
|
+
Mesh resolution (default: 64)
|
|
126
|
+
title : str, optional
|
|
127
|
+
Title for the visualization (shown as 2D text overlay)
|
|
128
|
+
background_color : tuple, optional
|
|
129
|
+
RGB background color (default: white)
|
|
130
|
+
mesh_color : str, optional
|
|
131
|
+
Hex color for the mesh (default: nice blue)
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
bool
|
|
136
|
+
True if successful, False otherwise
|
|
137
|
+
"""
|
|
138
|
+
try:
|
|
139
|
+
# Create 3D mesh from SDF
|
|
140
|
+
mesh, _ = create_3D_mesh(
|
|
141
|
+
sdf, N_base=resolution, mesh_type="surface", device="cpu"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Convert to gustaf format
|
|
145
|
+
gus_mesh = mesh.to_gus()
|
|
146
|
+
|
|
147
|
+
# Create vedo mesh
|
|
148
|
+
vedo_mesh = vedo.Mesh(
|
|
149
|
+
[gus_mesh.vertices.astype(np.float64), gus_mesh.faces.astype(np.int64)]
|
|
150
|
+
)
|
|
151
|
+
vedo_mesh.color(mesh_color).lighting("glossy")
|
|
152
|
+
|
|
153
|
+
# Setup plotter
|
|
154
|
+
plt = vedo.Plotter(interactive=False)
|
|
155
|
+
plt.offscreen = True # Don't open window
|
|
156
|
+
plt.background_color = background_color
|
|
157
|
+
|
|
158
|
+
# Create the scene
|
|
159
|
+
plt.show(vedo_mesh, camera=vedo.camera_from_dict(CAMERA_SETTINGS))
|
|
160
|
+
|
|
161
|
+
# Add title if provided
|
|
162
|
+
if title:
|
|
163
|
+
title_text = vedo.Text2D(
|
|
164
|
+
title, pos="top-left", font="Arial", s=0.05, c="black"
|
|
165
|
+
)
|
|
166
|
+
plt.show(title_text)
|
|
167
|
+
|
|
168
|
+
# Save screenshot
|
|
169
|
+
plt.screenshot(filename, scale=2.0) # Higher resolution
|
|
170
|
+
plt.close()
|
|
171
|
+
|
|
172
|
+
print(f" ✓ Created: {filename}")
|
|
173
|
+
return True
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
print(f" ✗ Failed: {filename} - {e}")
|
|
177
|
+
return False
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def create_2d_screenshot(
|
|
181
|
+
sdf,
|
|
182
|
+
filename: str,
|
|
183
|
+
resolution: int = 200,
|
|
184
|
+
title: str = "",
|
|
185
|
+
bounds: Optional[Tuple[float, float, float, float]] = None,
|
|
186
|
+
query_offset: Optional[Tuple[float, float]] = None,
|
|
187
|
+
interior_color: str = "#6B9BD2",
|
|
188
|
+
exterior_color: str = "#FFFFFF",
|
|
189
|
+
) -> bool:
|
|
190
|
+
"""
|
|
191
|
+
Generate a screenshot from a 2D SDF using matplotlib contour.
|
|
192
|
+
|
|
193
|
+
Parameters
|
|
194
|
+
----------
|
|
195
|
+
sdf : SDFBase (2D)
|
|
196
|
+
The 2D SDF to visualize
|
|
197
|
+
filename : str
|
|
198
|
+
Output filename (will be saved as .png)
|
|
199
|
+
resolution : int, optional
|
|
200
|
+
Grid resolution for sampling (default: 200)
|
|
201
|
+
title : str, optional
|
|
202
|
+
Title for the visualization
|
|
203
|
+
bounds : tuple, optional
|
|
204
|
+
Plot bounds (xmin, xmax, ymin, ymax). If None, uses SDF domain bounds.
|
|
205
|
+
query_offset : tuple, optional
|
|
206
|
+
Offset applied to sampling coordinates before SDF evaluation.
|
|
207
|
+
interior_color : str, optional
|
|
208
|
+
Hex color for interior region (default: nice blue)
|
|
209
|
+
exterior_color : str, optional
|
|
210
|
+
Hex color for exterior region (default: white)
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
bool
|
|
215
|
+
True if successful, False otherwise
|
|
216
|
+
"""
|
|
217
|
+
try:
|
|
218
|
+
# Get bounds if not provided
|
|
219
|
+
if bounds is None:
|
|
220
|
+
sdf_bounds = sdf._get_domain_bounds()
|
|
221
|
+
bounds = (
|
|
222
|
+
sdf_bounds[0, 0].item(),
|
|
223
|
+
sdf_bounds[1, 0].item(),
|
|
224
|
+
sdf_bounds[0, 1].item(),
|
|
225
|
+
sdf_bounds[1, 1].item(),
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# Create grid for sampling
|
|
229
|
+
x = np.linspace(bounds[0], bounds[1], resolution)
|
|
230
|
+
y = np.linspace(bounds[2], bounds[3], resolution)
|
|
231
|
+
X, Y = np.meshgrid(x, y)
|
|
232
|
+
|
|
233
|
+
# Sample SDF values
|
|
234
|
+
points = np.stack([X.ravel(), Y.ravel()], axis=1)
|
|
235
|
+
if query_offset is not None:
|
|
236
|
+
points_for_eval = points - np.asarray(query_offset, dtype=np.float32)
|
|
237
|
+
else:
|
|
238
|
+
points_for_eval = points
|
|
239
|
+
sdf_values = (
|
|
240
|
+
sdf(torch.tensor(points_for_eval, dtype=torch.float32))
|
|
241
|
+
.detach()
|
|
242
|
+
.numpy()
|
|
243
|
+
.reshape(X.shape)
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# Create plot
|
|
247
|
+
figsize = (6, 6) if not title else (6, 7)
|
|
248
|
+
if title:
|
|
249
|
+
return_list = [1]
|
|
250
|
+
else:
|
|
251
|
+
return_list = []
|
|
252
|
+
|
|
253
|
+
fig, axes = plt.subplots(figsize=figsize)
|
|
254
|
+
|
|
255
|
+
# Create filled contour plot (interior vs exterior)
|
|
256
|
+
# SDF < 0 is interior, SDF > 0 is exterior
|
|
257
|
+
contour = axes.contourf(
|
|
258
|
+
X,
|
|
259
|
+
Y,
|
|
260
|
+
sdf_values,
|
|
261
|
+
levels=[-100, 0, 100],
|
|
262
|
+
colors=[interior_color, exterior_color],
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Add contour line at SDF = 0 (boundary)
|
|
266
|
+
axes.contour(X, Y, sdf_values, levels=[0], colors="black", linewidths=2)
|
|
267
|
+
|
|
268
|
+
# Set plot properties
|
|
269
|
+
axes.set_aspect("equal")
|
|
270
|
+
axes.set_xlim(bounds[0], bounds[1])
|
|
271
|
+
axes.set_ylim(bounds[2], bounds[3])
|
|
272
|
+
axes.set_xlabel("X")
|
|
273
|
+
axes.set_ylabel("Y")
|
|
274
|
+
if title:
|
|
275
|
+
axes.set_title(title)
|
|
276
|
+
|
|
277
|
+
# Remove ticks for cleaner look
|
|
278
|
+
axes.set_xticks([])
|
|
279
|
+
axes.set_yticks([])
|
|
280
|
+
|
|
281
|
+
# Save figure
|
|
282
|
+
plt.tight_layout()
|
|
283
|
+
plt.savefig(filename, dpi=150, bbox_inches="tight")
|
|
284
|
+
plt.close(fig)
|
|
285
|
+
|
|
286
|
+
print(f" ✓ Created: {filename}")
|
|
287
|
+
return True
|
|
288
|
+
|
|
289
|
+
except Exception as e:
|
|
290
|
+
print(f" ✗ Failed: {filename} - {e}")
|
|
291
|
+
import traceback
|
|
292
|
+
|
|
293
|
+
traceback.print_exc()
|
|
294
|
+
return False
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# ==================== SDF Definitions ====================
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def create_sdf_primitives():
|
|
301
|
+
"""Create all SDF primitives and generate screenshots."""
|
|
302
|
+
|
|
303
|
+
# ======== 3D Primitives ========
|
|
304
|
+
output_dir = OUTPUT_DIR / "primitives" / "3D"
|
|
305
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
306
|
+
|
|
307
|
+
print("\n=== 3D Primitives ===")
|
|
308
|
+
|
|
309
|
+
# Sphere
|
|
310
|
+
print("Sphere")
|
|
311
|
+
sphere = SphereSDF(center=[0, 0, 0], radius=1.0)
|
|
312
|
+
create_screenshot(sphere, output_dir / "sphere.png", resolution=64)
|
|
313
|
+
|
|
314
|
+
# Box
|
|
315
|
+
print("Box")
|
|
316
|
+
box = BoxSDF(center=[0, 0, 0], extents=[1.5, 1.0, 0.8])
|
|
317
|
+
create_screenshot(box, output_dir / "box.png", resolution=64)
|
|
318
|
+
|
|
319
|
+
# Cone
|
|
320
|
+
|
|
321
|
+
# Cone
|
|
322
|
+
print("Cone")
|
|
323
|
+
cone = ConeSDF(apexpoint=[0, 0, -0.5], axis=[0, 0, 1], radius=0.4, height=1.0)
|
|
324
|
+
create_screenshot(cone, output_dir / "cone.png", resolution=64)
|
|
325
|
+
|
|
326
|
+
# Torus
|
|
327
|
+
print("Torus")
|
|
328
|
+
torus = TorusSDF(
|
|
329
|
+
center=[0, 0, 0], axis=[0, 0, 1], major_radius=0.5, minor_radius=0.15
|
|
330
|
+
)
|
|
331
|
+
create_screenshot(torus, output_dir / "torus.png", resolution=64)
|
|
332
|
+
|
|
333
|
+
# Rounded Box
|
|
334
|
+
print("Rounded Box")
|
|
335
|
+
rounded_box = RoundedBoxSDF(center=[0, 0, 0], extents=[1.0, 1.0, 1.0], radius=0.15)
|
|
336
|
+
create_screenshot(rounded_box, output_dir / "rounded_box.png", resolution=64)
|
|
337
|
+
|
|
338
|
+
# Wireframe Box
|
|
339
|
+
print("Wireframe Box")
|
|
340
|
+
wireframe_box = WireframeBoxSDF(
|
|
341
|
+
center=[0, 0, 0], extents=[1.0, 1.0, 1.0], thickness=0.08
|
|
342
|
+
)
|
|
343
|
+
create_screenshot(wireframe_box, output_dir / "wireframe_box.png", resolution=64)
|
|
344
|
+
|
|
345
|
+
# Capsule
|
|
346
|
+
print("Capsule")
|
|
347
|
+
capsule = CapsuleSDF(point_a=[0, 0, -0.5], point_b=[0, 0, 0.5], radius=0.25)
|
|
348
|
+
create_screenshot(capsule, output_dir / "capsule.png", resolution=64)
|
|
349
|
+
|
|
350
|
+
# Ellipsoid
|
|
351
|
+
print("Ellipsoid")
|
|
352
|
+
ellipsoid = EllipsoidSDF(center=[0, 0, 0], extents=[0.6, 0.8, 0.5])
|
|
353
|
+
create_screenshot(ellipsoid, output_dir / "ellipsoid.png", resolution=64)
|
|
354
|
+
|
|
355
|
+
# Pyramid
|
|
356
|
+
print("Pyramid")
|
|
357
|
+
pyramid = PyramidSDF(height=1.0)
|
|
358
|
+
create_screenshot(pyramid, output_dir / "pyramid.png", resolution=64)
|
|
359
|
+
|
|
360
|
+
# Corner Spheres
|
|
361
|
+
print("Corner Spheres")
|
|
362
|
+
corner_spheres = CornerSpheresSDF(radius=0.15, limit=0.8)
|
|
363
|
+
create_screenshot(corner_spheres, output_dir / "corner_spheres.png", resolution=64)
|
|
364
|
+
|
|
365
|
+
# Cross M
|
|
366
|
+
print("Cross M")
|
|
367
|
+
cross_ms = CrossMsSDF(radius=0.15)
|
|
368
|
+
create_screenshot(cross_ms, output_dir / "cross_ms.png", resolution=64)
|
|
369
|
+
|
|
370
|
+
# Cylinder
|
|
371
|
+
print("Cylinder")
|
|
372
|
+
cylinder = CylinderSDF(point_a=[0, 0, -0.5], point_b=[0, 0, 0.5], radius=0.3)
|
|
373
|
+
create_screenshot(cylinder, output_dir / "cylinder.png", resolution=64)
|
|
374
|
+
|
|
375
|
+
# Rounded Cylinder
|
|
376
|
+
print("Rounded Cylinder")
|
|
377
|
+
rounded_cyl = RoundedCylinderSDF(ra=0.3, rb=0.1, h=1.0)
|
|
378
|
+
create_screenshot(rounded_cyl, output_dir / "rounded_cylinder.png", resolution=64)
|
|
379
|
+
|
|
380
|
+
# Capped Cone
|
|
381
|
+
print("Capped Cone")
|
|
382
|
+
capped_cone = CappedConeSDF(
|
|
383
|
+
point_a=[0, 0, -0.5], point_b=[0, 0, 0.5], ra=0.1, rb=0.3
|
|
384
|
+
)
|
|
385
|
+
create_screenshot(capped_cone, output_dir / "capped_cone.png", resolution=64)
|
|
386
|
+
|
|
387
|
+
# Rounded Cone
|
|
388
|
+
print("Rounded Cone")
|
|
389
|
+
rounded_cone = RoundedConeSDF(r1=0.1, r2=0.3, h=1.0)
|
|
390
|
+
create_screenshot(rounded_cone, output_dir / "rounded_cone.png", resolution=64)
|
|
391
|
+
|
|
392
|
+
# Platonic Solids
|
|
393
|
+
print("Tetrahedron")
|
|
394
|
+
tetra = TetrahedronSDF(r=0.8)
|
|
395
|
+
create_screenshot(tetra, output_dir / "tetrahedron.png", resolution=64)
|
|
396
|
+
|
|
397
|
+
print("Octahedron")
|
|
398
|
+
octa = OctahedronSDF(r=0.8)
|
|
399
|
+
create_screenshot(octa, output_dir / "octahedron.png", resolution=64)
|
|
400
|
+
|
|
401
|
+
print("Dodecahedron")
|
|
402
|
+
dodeca = DodecahedronSDF(r=0.8)
|
|
403
|
+
create_screenshot(dodeca, output_dir / "dodecahedron.png", resolution=64)
|
|
404
|
+
|
|
405
|
+
print("Icosahedron")
|
|
406
|
+
icosa = IcosahedronSDF(r=0.8)
|
|
407
|
+
create_screenshot(icosa, output_dir / "icosahedron.png", resolution=64)
|
|
408
|
+
|
|
409
|
+
# ======== 2D Primitives ========
|
|
410
|
+
output_dir = OUTPUT_DIR / "primitives" / "2D"
|
|
411
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
412
|
+
unit_bounds = (0.0, 1.0, 0.0, 1.0)
|
|
413
|
+
|
|
414
|
+
print("\\n=== 2D Primitives ===")
|
|
415
|
+
|
|
416
|
+
# Circle
|
|
417
|
+
print("Circle")
|
|
418
|
+
circle = CircleSDF(center=[0.5, 0.5], radius=0.35)
|
|
419
|
+
create_2d_screenshot(
|
|
420
|
+
circle, output_dir / "circle.png", resolution=200, bounds=unit_bounds
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
# Rectangle
|
|
424
|
+
print("Rectangle")
|
|
425
|
+
rectangle = RectangleSDF(center=[0.5, 0.5], extents=[0.7, 0.55])
|
|
426
|
+
create_2d_screenshot(
|
|
427
|
+
rectangle, output_dir / "rectangle.png", resolution=200, bounds=unit_bounds
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
# Rounded Rectangle
|
|
431
|
+
print("Rounded Rectangle")
|
|
432
|
+
rounded_rect = RoundedRectangleSDF(
|
|
433
|
+
center=[0.5, 0.5], extents=[0.72, 0.56], radius=0.08
|
|
434
|
+
)
|
|
435
|
+
create_2d_screenshot(
|
|
436
|
+
rounded_rect,
|
|
437
|
+
output_dir / "rounded_rectangle.png",
|
|
438
|
+
resolution=200,
|
|
439
|
+
bounds=unit_bounds,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
# Equilateral Triangle
|
|
443
|
+
print("Equilateral Triangle")
|
|
444
|
+
triangle = EquilateralTriangleSDF(size=0.32)
|
|
445
|
+
create_2d_screenshot(
|
|
446
|
+
triangle,
|
|
447
|
+
output_dir / "equilateral_triangle.png",
|
|
448
|
+
resolution=200,
|
|
449
|
+
bounds=unit_bounds,
|
|
450
|
+
query_offset=(0.5, 0.5),
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
# Hexagon
|
|
454
|
+
print("Hexagon")
|
|
455
|
+
hexagon = HexagonSDF(size=0.28)
|
|
456
|
+
create_2d_screenshot(
|
|
457
|
+
hexagon,
|
|
458
|
+
output_dir / "hexagon.png",
|
|
459
|
+
resolution=200,
|
|
460
|
+
bounds=unit_bounds,
|
|
461
|
+
query_offset=(0.5, 0.5),
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
# Polygon (custom shape)
|
|
465
|
+
print("Polygon (Pentagon)")
|
|
466
|
+
pentagon = PolygonSDF(
|
|
467
|
+
[
|
|
468
|
+
[0.5, 0.86], # Top
|
|
469
|
+
[0.82, 0.62], # Top right
|
|
470
|
+
[0.7, 0.24], # Bottom right
|
|
471
|
+
[0.3, 0.24], # Bottom left
|
|
472
|
+
[0.18, 0.62], # Top left
|
|
473
|
+
]
|
|
474
|
+
)
|
|
475
|
+
create_2d_screenshot(
|
|
476
|
+
pentagon,
|
|
477
|
+
output_dir / "polygon_pentagon.png",
|
|
478
|
+
resolution=200,
|
|
479
|
+
bounds=unit_bounds,
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
# ======== Boolean Operations ========
|
|
483
|
+
output_dir = OUTPUT_DIR / "operations" / "boolean"
|
|
484
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
485
|
+
|
|
486
|
+
print("\n=== Boolean Operations ===")
|
|
487
|
+
|
|
488
|
+
# Union
|
|
489
|
+
print("Sphere + Box Union")
|
|
490
|
+
sphere = SphereSDF(center=[0.0, 0, 0], radius=0.5)
|
|
491
|
+
box = BoxSDF(center=[0.0, 0, 0], extents=[2.0, 0.3, 0.3])
|
|
492
|
+
union = sphere + box # UnionSDF is the + operator
|
|
493
|
+
create_screenshot(
|
|
494
|
+
union, output_dir / "union_sphere_box.png", resolution=64, title="Union"
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
# Difference
|
|
498
|
+
print("Sphere - Box Difference")
|
|
499
|
+
diff = DifferenceSDF(sphere, box)
|
|
500
|
+
create_screenshot(
|
|
501
|
+
diff,
|
|
502
|
+
output_dir / "difference_sphere_box.png",
|
|
503
|
+
resolution=64,
|
|
504
|
+
title="Difference",
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
# ======== Transformation Operations ========
|
|
508
|
+
output_dir = OUTPUT_DIR / "operations" / "transformations"
|
|
509
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
510
|
+
|
|
511
|
+
print("\n=== Transformation Operations ===")
|
|
512
|
+
|
|
513
|
+
# Twist
|
|
514
|
+
print("Twisted Torus")
|
|
515
|
+
base_torus = TorusSDF(
|
|
516
|
+
center=[0, 0, 0], axis=[0, 0, 1], major_radius=1.0, minor_radius=0.2
|
|
517
|
+
)
|
|
518
|
+
twist_params = np.pi / 2 # 90 degree twist
|
|
519
|
+
twisted_torus = TwistSDF(base_torus, k=twist_params)
|
|
520
|
+
create_screenshot(
|
|
521
|
+
twisted_torus, output_dir / "twist_torus.png", resolution=64, title="Twist"
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
# Dilate
|
|
525
|
+
print("Dilated Sphere")
|
|
526
|
+
base_sphere = SphereSDF(center=[0, 0, 0], radius=0.5)
|
|
527
|
+
dilated_sphere = DilateSDF(base_sphere, r=0.15)
|
|
528
|
+
create_screenshot(
|
|
529
|
+
dilated_sphere, output_dir / "dilate_sphere.png", resolution=64, title="Dilated"
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
# Shell
|
|
533
|
+
print("Sphere Shell")
|
|
534
|
+
shell_sphere = ShellSDF(base_sphere, thickness=0.1)
|
|
535
|
+
create_screenshot(
|
|
536
|
+
shell_sphere, output_dir / "shell_sphere.png", resolution=64, title="Shell"
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
# Repeat
|
|
540
|
+
print("Repeated Spheres (3x3x3)")
|
|
541
|
+
small_sphere = SphereSDF(center=[0, 0, 0], radius=0.2)
|
|
542
|
+
repeated_sphere = RepeatSDF(small_sphere, spacing=[0.6, 0.6, 0.6], count=3)
|
|
543
|
+
create_screenshot(
|
|
544
|
+
repeated_sphere,
|
|
545
|
+
output_dir / "repeat_sphere.png",
|
|
546
|
+
resolution=64,
|
|
547
|
+
title="Repeated (3x3x3)",
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
# Mirror
|
|
551
|
+
print("Mirrored Sphere")
|
|
552
|
+
off_center_sphere = SphereSDF(center=[0.5, 0, 0], radius=0.3)
|
|
553
|
+
mirrored_sphere = MirrorSDF(
|
|
554
|
+
off_center_sphere, plane_point=[0, 0, 0], plane_normal=[1, 0, 0]
|
|
555
|
+
)
|
|
556
|
+
create_screenshot(
|
|
557
|
+
mirrored_sphere,
|
|
558
|
+
output_dir / "mirror_sphere.png",
|
|
559
|
+
resolution=64,
|
|
560
|
+
title="Mirrored",
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
# Circular Array
|
|
564
|
+
print("Circular Array of Spheres")
|
|
565
|
+
arrayed_sphere = CircularArraySDF(off_center_sphere, count=6)
|
|
566
|
+
create_screenshot(
|
|
567
|
+
arrayed_sphere,
|
|
568
|
+
output_dir / "circular_array_sphere.png",
|
|
569
|
+
resolution=64,
|
|
570
|
+
title="Circular Array (6x)",
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
# Revolve (2D to 3D)
|
|
574
|
+
print("Revolved Circle")
|
|
575
|
+
circle_2d = CircleSDF(center=[0.8, 0], radius=0.15)
|
|
576
|
+
revolved_shape = RevolveSDF(
|
|
577
|
+
circle_2d, axis=torch.tensor([0, 0, 1], dtype=torch.float32)
|
|
578
|
+
)
|
|
579
|
+
create_screenshot(
|
|
580
|
+
revolved_shape,
|
|
581
|
+
output_dir / "revolve_circle.png",
|
|
582
|
+
resolution=64,
|
|
583
|
+
title="Revolved (Torus)",
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
# ==================== Main Script ====================
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
def main():
|
|
591
|
+
"""Generate all SDF showcase images."""
|
|
592
|
+
|
|
593
|
+
print("=" * 60)
|
|
594
|
+
print("SDF Primitive and Operation Showcase Generator")
|
|
595
|
+
print("=" * 60)
|
|
596
|
+
print(f"\nOutput directory: {OUTPUT_DIR.absolute()}")
|
|
597
|
+
|
|
598
|
+
try:
|
|
599
|
+
create_sdf_primitives()
|
|
600
|
+
|
|
601
|
+
print("\n" + "=" * 60)
|
|
602
|
+
print("✓ Showcase generation complete!")
|
|
603
|
+
print("=" * 60)
|
|
604
|
+
print(f"\nGenerated screenshots saved to: {OUTPUT_DIR.absolute()}")
|
|
605
|
+
print("\nThese images can be used for documentation and README.")
|
|
606
|
+
|
|
607
|
+
except KeyboardInterrupt:
|
|
608
|
+
print("\n\nGeneration interrupted by user.")
|
|
609
|
+
except Exception as e:
|
|
610
|
+
print(f"\n\n✗ Error during generation: {e}")
|
|
611
|
+
import traceback
|
|
612
|
+
|
|
613
|
+
traceback.print_exc()
|
|
614
|
+
return 1
|
|
615
|
+
|
|
616
|
+
return 0
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
if __name__ == "__main__":
|
|
620
|
+
import sys
|
|
621
|
+
|
|
622
|
+
sys.exit(main())
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import trimesh
|
|
3
|
+
import torch
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from DeepSDFStruct.SDF import SDFfromMesh
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def run_benchmark():
|
|
9
|
+
mesh_configs = {
|
|
10
|
+
"Sphere (Low)": trimesh.creation.icosphere(subdivisions=2),
|
|
11
|
+
"Sphere (Med)": trimesh.creation.icosphere(subdivisions=4),
|
|
12
|
+
"Bunny (High)": trimesh.load("tests/data/stanford_bunny.stl"),
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
query_sizes = [10**4, 10**5, 10**6]
|
|
16
|
+
backends = ["igl", "trimesh"]
|
|
17
|
+
results = []
|
|
18
|
+
|
|
19
|
+
print(f"{'Mesh':<15} | {'Points':<10} | {'Backend':<10} | {'Time (s)':<10}")
|
|
20
|
+
print("-" * 55)
|
|
21
|
+
|
|
22
|
+
for name, mesh in mesh_configs.items():
|
|
23
|
+
for n_points in query_sizes:
|
|
24
|
+
queries = torch.randn((n_points, 3))
|
|
25
|
+
|
|
26
|
+
for backend in backends:
|
|
27
|
+
sdf_gen = SDFfromMesh(mesh, backend=backend, scale=True)
|
|
28
|
+
|
|
29
|
+
start_time = time.perf_counter()
|
|
30
|
+
_ = sdf_gen(queries)
|
|
31
|
+
end_time = time.perf_counter()
|
|
32
|
+
|
|
33
|
+
elapsed = end_time - start_time
|
|
34
|
+
results.append(
|
|
35
|
+
{
|
|
36
|
+
"Mesh": name,
|
|
37
|
+
"Faces": len(mesh.faces),
|
|
38
|
+
"Points": n_points,
|
|
39
|
+
"Backend": backend,
|
|
40
|
+
"Time": elapsed,
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
print(f"{name:<15} | {n_points:<10} | {backend:<10} | {elapsed:.4f}")
|
|
44
|
+
|
|
45
|
+
return pd.DataFrame(results)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
df = run_benchmark()
|
|
49
|
+
summary = df.pivot_table(index=["Mesh", "Points"], columns="Backend", values="Time")
|
|
50
|
+
print("\nSpeedup (IGL vs Trimesh):")
|
|
51
|
+
summary["Speedup (x)"] = summary["trimesh"] / summary["igl"]
|
|
52
|
+
print(summary)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Mesh | Points | Backend | Time (s)
|
|
2
|
+
-------------------------------------------------------
|
|
3
|
+
Sphere (Low) | 10000 | igl | 0.0124
|
|
4
|
+
Sphere (Low) | 10000 | trimesh | 0.0155
|
|
5
|
+
Sphere (Low) | 100000 | igl | 0.0253
|
|
6
|
+
Sphere (Low) | 100000 | trimesh | 0.0732
|
|
7
|
+
Sphere (Low) | 1000000 | igl | 0.1554
|
|
8
|
+
Sphere (Low) | 1000000 | trimesh | 0.7333
|
|
9
|
+
Sphere (Med) | 10000 | igl | 0.0472
|
|
10
|
+
Sphere (Med) | 10000 | trimesh | 0.0399
|
|
11
|
+
Sphere (Med) | 100000 | igl | 0.0889
|
|
12
|
+
Sphere (Med) | 100000 | trimesh | 0.1181
|
|
13
|
+
Sphere (Med) | 1000000 | igl | 0.3624
|
|
14
|
+
Sphere (Med) | 1000000 | trimesh | 0.8615
|
|
15
|
+
Bunny (High) | 10000 | igl | 0.8877
|
|
16
|
+
Bunny (High) | 10000 | trimesh | 0.4823
|
|
17
|
+
Bunny (High) | 100000 | igl | 0.9768
|
|
18
|
+
Bunny (High) | 100000 | trimesh | 0.6239
|
|
19
|
+
Bunny (High) | 1000000 | igl | 1.6876
|
|
20
|
+
Bunny (High) | 1000000 | trimesh | 1.5953
|
|
21
|
+
|
|
22
|
+
Speedup (IGL vs Trimesh):
|
|
23
|
+
Backend igl trimesh Speedup (x)
|
|
24
|
+
Mesh Points
|
|
25
|
+
Bunny (High) 10000 0.887726 0.482313 0.543312
|
|
26
|
+
100000 0.976751 0.623863 0.638712
|
|
27
|
+
1000000 1.687581 1.595282 0.945307
|
|
28
|
+
Sphere (Low) 10000 0.012439 0.015542 1.249462
|
|
29
|
+
100000 0.025271 0.073200 2.896629
|
|
30
|
+
1000000 0.155364 0.733257 4.719598
|
|
31
|
+
Sphere (Med) 10000 0.047250 0.039910 0.844664
|
|
32
|
+
100000 0.088914 0.118088 1.328118
|
|
33
|
+
1000000 0.362449 0.861516 2.376932
|
|
Binary file
|
|
Binary file
|