Skip to content

Commit 9bad718

Browse files
Completed VTK support for materials
1 parent d1812ef commit 9bad718

13 files changed

+2186
-198
lines changed

cadquery/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
)
2222
from .occ_impl import exporters
2323
from .occ_impl import importers
24-
from .materials import Color, Material, CommonMaterial, PbrMaterial
24+
from .materials import Color, Material, SimpleMaterial, PbrMaterial
2525

2626
# these items are the common implementation
2727

@@ -49,7 +49,7 @@
4949
"Assembly",
5050
"Color",
5151
"Material",
52-
"CommonMaterial",
52+
"SimpleMaterial",
5353
"PbrMaterial",
5454
"Constraint",
5555
"plugins",

cadquery/cq_directive.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from json import dumps
99

10-
from cadquery import exporters, Assembly, Compound, Color, Sketch
10+
from cadquery import exporters, Assembly, Compound, Sketch
1111
from cadquery import cqgi
1212
from cadquery.occ_impl.assembly import toJSON
1313
from cadquery.occ_impl.jupyter_tools import DEFAULT_COLOR
@@ -299,9 +299,9 @@ def run(self):
299299
if isinstance(shape, Assembly):
300300
assy = shape
301301
elif isinstance(shape, Sketch):
302-
assy = Assembly(shape._faces, color=Color(*DEFAULT_COLOR))
302+
assy = Assembly(shape._faces, color=DEFAULT_COLOR)
303303
else:
304-
assy = Assembly(shape, color=Color(*DEFAULT_COLOR))
304+
assy = Assembly(shape, color=DEFAULT_COLOR)
305305
else:
306306
raise result.exception
307307

cadquery/materials.py

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,30 @@ def __init__(self, *args, **kwargs):
5353
self.b = 0.0
5454
self.a = 1.0
5555
elif len(args) == 1 and isinstance(args[0], str):
56-
from .occ_impl.assembly import color_from_name
57-
58-
# Handle color name case
59-
color = color_from_name(args[0])
60-
self.r = color.r
61-
self.g = color.g
62-
self.b = color.b
63-
self.a = color.a
56+
from cadquery.occ_impl.assembly import color_from_name
57+
from vtkmodules.vtkCommonColor import vtkNamedColors
58+
59+
# Try to get color from OCCT first, fall back to VTK if not found
60+
try:
61+
# Get color from OCCT
62+
color = color_from_name(args[0])
63+
self.r = color.r
64+
self.g = color.g
65+
self.b = color.b
66+
self.a = color.a
67+
except ValueError:
68+
# Check if color exists in VTK
69+
vtk_colors = vtkNamedColors()
70+
if not vtk_colors.ColorExists(args[0]):
71+
raise ValueError(f"Unsupported color name: {args[0]}")
72+
73+
# Get color from VTK
74+
color = vtk_colors.GetColor4d(args[0])
75+
self.r = color.GetRed()
76+
self.g = color.GetGreen()
77+
self.b = color.GetBlue()
78+
self.a = color.GetAlpha()
79+
6480
elif len(args) == 3:
6581
# Handle RGB case
6682
r, g, b = args
@@ -118,15 +134,14 @@ def __eq__(self, other: object) -> bool:
118134

119135

120136
@dataclass
121-
class CommonMaterial:
137+
class SimpleMaterial:
122138
"""
123139
Traditional material model matching OpenCascade's XCAFDoc_VisMaterialCommon.
124140
"""
125141

126142
ambient_color: Color
127143
diffuse_color: Color
128144
specular_color: Color
129-
emissive_color: Color
130145
shininess: float
131146
transparency: float
132147

@@ -145,21 +160,19 @@ def __hash__(self) -> int:
145160
self.ambient_color,
146161
self.diffuse_color,
147162
self.specular_color,
148-
self.emissive_color,
149163
self.shininess,
150164
self.transparency,
151165
)
152166
)
153167

154168
def __eq__(self, other: object) -> bool:
155169
"""Compare two CommonMaterial objects."""
156-
if not isinstance(other, CommonMaterial):
170+
if not isinstance(other, SimpleMaterial):
157171
return False
158172
return (
159173
self.ambient_color == other.ambient_color
160174
and self.diffuse_color == other.diffuse_color
161175
and self.specular_color == other.specular_color
162-
and self.emissive_color == other.emissive_color
163176
and self.shininess == other.shininess
164177
and self.transparency == other.transparency
165178
)
@@ -169,6 +182,8 @@ def __eq__(self, other: object) -> bool:
169182
class PbrMaterial:
170183
"""
171184
PBR material definition matching OpenCascade's XCAFDoc_VisMaterialPBR.
185+
186+
Note: Emission support will be added in a future version with proper texture support.
172187
"""
173188

174189
# Base color and texture
@@ -177,9 +192,6 @@ class PbrMaterial:
177192
roughness: float
178193
refraction_index: float
179194

180-
# Optional properties
181-
emissive_factor: Color = Color(0.0, 0.0, 0.0)
182-
183195
def __post_init__(self):
184196
"""Validate the material properties."""
185197
# Validate ranges
@@ -193,13 +205,7 @@ def __post_init__(self):
193205
def __hash__(self) -> int:
194206
"""Make PbrMaterial hashable."""
195207
return hash(
196-
(
197-
self.base_color,
198-
self.metallic,
199-
self.roughness,
200-
self.refraction_index,
201-
self.emissive_factor,
202-
)
208+
(self.base_color, self.metallic, self.roughness, self.refraction_index,)
203209
)
204210

205211
def __eq__(self, other: object) -> bool:
@@ -211,7 +217,6 @@ def __eq__(self, other: object) -> bool:
211217
and self.metallic == other.metallic
212218
and self.roughness == other.roughness
213219
and self.refraction_index == other.refraction_index
214-
and self.emissive_factor == other.emissive_factor
215220
)
216221

217222

@@ -228,12 +233,12 @@ class Material:
228233

229234
# Material representations
230235
color: Optional[Color] = None
231-
common: Optional[CommonMaterial] = None
236+
simple: Optional[SimpleMaterial] = None
232237
pbr: Optional[PbrMaterial] = None
233238

234239
def __post_init__(self):
235240
"""Validate that at least one representation is provided."""
236-
if not any([self.color, self.common, self.pbr]):
241+
if not any([self.color, self.simple, self.pbr]):
237242
raise ValueError("Material must have at least one representation defined")
238243

239244
def __hash__(self) -> int:
@@ -244,7 +249,7 @@ def __hash__(self) -> int:
244249
self.description,
245250
self.density,
246251
self.color,
247-
self.common,
252+
self.simple,
248253
self.pbr,
249254
)
250255
)
@@ -258,6 +263,6 @@ def __eq__(self, other: object) -> bool:
258263
and self.description == other.description
259264
and self.density == other.density
260265
and self.color == other.color
261-
and self.common == other.common
266+
and self.simple == other.simple
262267
and self.pbr == other.pbr
263268
)

0 commit comments

Comments
 (0)