Skip to content

API Reference

scadview.Color

Bases: Enum

Enum for common colors used in SCADview visualizations.

Source code in src/scadview/api/colors.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Color(Enum):
    """Enum for common colors used in SCADview visualizations."""

    RED = (1.0, 0.0, 0.0)
    GREEN = (0.0, 1.0, 0.0)
    BLUE = (0.0, 0.0, 1.0)
    YELLOW = (1.0, 1.0, 0.0)
    CYAN = (0.0, 1.0, 1.0)
    MAGENTA = (1.0, 0.0, 1.0)
    ORANGE = (1.0, 0.65, 0.0)
    PURPLE = (0.5, 0.0, 0.5)
    PINK = (1.0, 0.75, 0.8)
    BROWN = (0.6, 0.4, 0.2)
    GRAY = (0.5, 0.5, 0.5)
    BLACK = (0.0, 0.0, 0.0)
    WHITE = (1.0, 1.0, 1.0)
    NAVY = (0.0, 0.0, 0.5)
    TEAL = (0.0, 0.5, 0.5)
    OLIVE = (0.5, 0.5, 0.0)
    MAROON = (0.5, 0.0, 0.0)
    LIME = (0.75, 1.0, 0.0)
    INDIGO = (0.29, 0.0, 0.51)
    TURQUOISE = (0.25, 0.88, 0.82)
    GOLD = (1.0, 0.84, 0.0)
    SILVER = (0.75, 0.75, 0.75)
    BEIGE = (0.96, 0.96, 0.86)
    CORAL = (1.0, 0.5, 0.31)
    SALMON = (0.98, 0.5, 0.45)
    CRIMSON = (0.86, 0.08, 0.24)
    KHAKI = (0.76, 0.69, 0.57)
    LAVENDER = (0.9, 0.9, 0.98)
    MINT = (0.74, 1.0, 0.79)
    SKY_BLUE = (0.53, 0.81, 0.92)

scadview.set_mesh_color(mesh, color, alpha=1.0)

Set the color of a Trimesh object for SCADview visualization.

Parameters:

Name Type Description Default
mesh Trimesh

The input mesh to which the color will be applied.

required
color tuple[float, float, float] | list[float] | Color

The RGB color to set. Can be a tuple, list, or Color enum.

required
alpha float

The alpha transparency value for the color (0.0 to 1.0).

1.0

Returns:

Name Type Description
Trimesh Trimesh

The input mesh with updated color metadata.

Source code in src/scadview/api/colors.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def set_mesh_color(
    mesh: Trimesh,
    color: tuple[float, float, float] | list[float] | Color,
    alpha: float = 1.0,
) -> Trimesh:
    """Set the color of a Trimesh object for SCADview visualization.

    Args:
        mesh: The input mesh to which the color will be applied.
        color: The RGB color to set. Can be a tuple, list, or Color enum.
        alpha: The alpha transparency value for the color (0.0 to 1.0).

    Returns:
        Trimesh: The input mesh with updated color metadata.
    """
    if isinstance(color, Color):
        color = color.value
    for c in color:
        if not (0.0 <= c <= 1.0):
            raise ValueError("Color components must be in the range [0.0, 1.0]")
    if not (0.0 <= alpha <= 1.0):
        raise ValueError("Alpha value must be in the range [0.0, 1.0]")
    float_color = [float(c) for c in color]
    float_alpha = float(alpha)
    mesh.metadata["scadview"] = {
        "color": [float_color[0], float_color[1], float_color[2], float_alpha]
    }
    return mesh

scadview.surface(file, scale=(1.0, 1.0, 1.0), base=0.0, invert=False, binary_split=False, binary_split_value=0.5)

Create a 3D mesh on a base at z = 0.0 from a file containing heightmap data. The file can be a CSV, TSV, TXT, DAT, or an image file (PNG, JPEG, etc.). Image files are converted to grayscale and generate heights between 0.0 and 1.0

Parameters:

Name Type Description Default
file str

The file path to get the data from.

required
scale tuple[float, float, float]

A 3-tuple that scales in each dimension.

(1.0, 1.0, 1.0)
base float

The base height of the pedestal upon which the mesh will be placed.

0.0
invert bool

If True, inverts the heightmap values between min and max values.

False
binary_split bool

Converts the heightmap to 0s or 1s only. based on whether the height is below or equal (changes to 0) or above (changes to 1) the binary_split_value.

False
binary_split_value float

Only usedif binary_splt=ut it True.

0.5

Returns:

Name Type Description
Trimesh Trimesh

A 3d mesh object representing the surface on a pedestal.

Source code in src/scadview/api/surface.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
def surface(
    file: str,
    scale: tuple[float, float, float] = (1.0, 1.0, 1.0),
    base: float = 0.0,
    invert: bool = False,
    binary_split: bool = False,
    binary_split_value: float = 0.5,
) -> trimesh.Trimesh:
    """
    Create a 3D mesh on a base at z = 0.0 from a file containing heightmap data.
    The file can be a CSV, TSV, TXT, DAT, or an image file (PNG, JPEG, etc.).
    Image files are converted to grayscale and generate heights between 0.0 and 1.0

    Args:
        file: The file path to get the data from.
        scale: A 3-tuple that scales in each dimension.
        base: The base height of the pedestal upon which the mesh will be placed.
        invert: If True, inverts the heightmap values between min and max values.
        binary_split: Converts the heightmap to 0s or 1s only.
            based on whether the height is below or equal (changes to 0) or above (changes to 1) the
            binary_split_value.
        binary_split_value: Only usedif binary_splt=ut it True.


    Returns:
        Trimesh: A 3d mesh object representing the surface on a pedestal.

    """
    delimiter = None
    if file.endswith(".csv"):
        delimiter = ","
    elif file.endswith(".tsv"):
        delimiter = "\t"
    elif file.endswith(".txt") or format(file).endswith(".dat"):
        delimiter = " "
    if delimiter is not None:
        # Load heightmap from text file
        heightmap = np.loadtxt(file, delimiter=delimiter).astype(np.float32)
        return _solid_from_heightmap(
            heightmap,
            scale,
            base,
            invert,
            binary_split,
            binary_split_value,
        )
    else:
        # Assume it's an image file
        with open(file, "rb") as img_file:
            return _solid_from_image(
                img_file,
                scale,
                base,
                invert,
                binary_split,
                binary_split_value,
            )

scadview.mesh_from_heightmap(heightmap, scale=(1.0, 1.0, 1.0))

Create a 3D mesh from a heightmap.

Parameters:

Name Type Description Default
heightmap NDArray[float32]

A 2D numpy array representing the heightmap, where each value corresponds to the height at that point.

required
scale tuple[float, float, float]

A 3-tuple (X, Y, Z) to scale the mesh in the respective dimensions.

(1.0, 1.0, 1.0)

Returns:

Type Description
Trimesh

An object representing the 3D mesh.

Source code in src/scadview/api/surface.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
def mesh_from_heightmap(
    heightmap: NDArray[np.float32], scale: tuple[float, float, float] = (1.0, 1.0, 1.0)
) -> trimesh.Trimesh:
    """Create a 3D mesh from a heightmap.

    Args:
        heightmap: A 2D numpy array representing the heightmap, where each value corresponds to the height at that point.
        scale: A 3-tuple (X, Y, Z) to scale the mesh in the respective dimensions.

    Returns:
        An object representing the 3D mesh.
    """
    H, W = heightmap.shape
    # 1) grid coordinates
    xs = np.arange(W, dtype=np.float32) * scale[0]
    ys = np.arange(H, dtype=np.float32) * scale[1]
    xx, yy = np.meshgrid(xs, ys)

    # 2) vertices: (N,3) array
    verts = np.column_stack([xx.ravel(), yy.ravel(), heightmap.ravel() * scale[2]])

    # 3) faces: two triangles per grid square
    faces = np.empty((0, 3), dtype=np.int32)
    for i in range(H - 1):
        for j in range(W - 1):
            v0 = i * W + j
            v1 = v0 + 1
            v2 = v0 + W
            v3 = v2 + 1
            # triangle 1
            faces = np.append(faces, [[v0, v2, v1], [v1, v2, v3]], axis=0)
            # triangle 2
            # faces = np.append(faces, [[v1, v2, v3]], axis=0)
    # faces = np.array(faces)

    # 4) build mesh
    return trimesh.Trimesh(vertices=verts, faces=faces)

scadview.SIZE_MULTIPLIER = 1.374 module-attribute

Used to convert pt size to mesh units.

scadview.text(text, size=10.0, font=DEFAULT_FONT, halign='left', valign='baseline', spacing=0, direction='ltr', language='', script='')

Create a 3D mesh from the given text using the specified font and size. This is based on OpenSCAD's text() function.

Font Loading Time Warning: Loading fonts from the system can be time-consuming, especially if the font cache needs to be rebuilt. The first time this function is called, it may take several seconds to load the font information. Subsequent calls will be faster as the font data is cached.

Font Specification: The font parameter should be specified in the form "Family:style", e.g. "Arial:style=Bold". In SCADview, use Help > List System Fonts to see available fonts on your system, and copy the exact name / style string.

Parameters:

Name Type Description Default
text str

The text to convert to a 3D mesh.

required
size float

The size of the text in mesh units (per openSCAD).

10.0
font str

The font family name to use for the text. This is in the form "Family:style", e.g. "Arial:style=Bold".

DEFAULT_FONT
halign str

Horizontal alignment of the text ('left', 'center', 'right').

'left'
valign str

Vertical alignment of the text ('baseline', 'top', 'bottom', 'center').

'baseline'
spacing float

Spacing between characters in mesh units (not used in this implementtion).

0
direction str

Text direction (only 'ltr' and 'rtl' are is supported in this implementation).

'ltr'
language str

Language of the text (not used in this implementation).

''
script str

Script of the text (not used in this implementation).

''

Returns:

Type Description
Trimesh

An object representing the 3D mesh of the text.

Source code in src/scadview/api/text_builder.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
def text(
    text: str,
    size: float = 10.0,
    font: str = DEFAULT_FONT,
    halign: str = "left",
    valign: str = "baseline",
    spacing: float = 0,
    direction: str = "ltr",
    language: str = "",
    script: str = "",
) -> Trimesh:
    """
    Create a 3D mesh from the given text using the specified font and size.
    This is based on OpenSCAD's text() function.

    **Font Loading Time Warning**:
    Loading fonts from the system can be time-consuming, especially if the font cache
    needs to be rebuilt. The first time this function is called, it may take several seconds
    to load the font information. Subsequent calls will be faster as the font data is cached.

    **Font Specification**:
    The `font` parameter should be specified in the form "Family:style", e.g. "Arial:style=Bold".
    In SCADview, use Help > List System Fonts to see available fonts on your system,
    and copy the exact name / style string.


    Args:
        text: The text to convert to a 3D mesh.
        size: The size of the text in mesh units (per openSCAD).
        font: The font family name to use for the text.
            This is in the form "Family:style", e.g. "Arial:style=Bold".
        halign: Horizontal alignment of the text ('left', 'center', 'right').
        valign: Vertical alignment of the text ('baseline', 'top', 'bottom', 'center').
        spacing: Spacing between characters in mesh units (not used in this implementtion).
        direction: Text direction (only 'ltr' and 'rtl' are is supported in this implementation).
        language: Language of the text (not used in this implementation).
        script: Script of the text (not used in this implementation).

    Returns:
        An object representing the 3D mesh of the text.
    """
    if text.strip() == "":
        # If the text is empty or contains only spaces, return an empty mesh
        return trimesh.Trimesh(vertices=np.empty((0, 3)), faces=np.empty((0, 3)))
    polys = text_polys(
        text, size, font, halign, valign, spacing, direction, language, script
    )
    meshes = [extrude_polygon(poly, height=1.0) for poly in polys]
    return trimesh.util.concatenate(meshes)  # pyright: ignore[reportUnknownVariableType] - trimesh function

scadview.text_polys(text, size=10.0, font=DEFAULT_FONT, halign='left', valign='baseline', spacing=0, direction='ltr', language='', script='')

Create a list of Polygons from the given text using the specified font and size. This is based on OpenSCAD's text() function, but returns 2D polygons instead of a 3D mesh, suitable for extrusion or other operations.

Font Loading Time Warning: Loading fonts from the system can be time-consuming, especially if the font cache needs to be rebuilt. The first time this function is called, it may take several seconds to load the font information. Subsequent calls will be faster as the font data is cached.

Font Specification: The font parameter should be specified in the form "Family:style", e.g. "Arial:style=Bold". In SCADview, use Help > List System Fonts to see available fonts on your system, and copy the exact name / style string.

Parameters:

Name Type Description Default
text str

The text to convert to a polygons.

required
size float

The size of the text in mesh units.

10.0
font str

The font family name and style to use for the text. This is in the form "Family:style", e.g. "Arial:style=Bold".

DEFAULT_FONT
halign str

Horizontal alignment of the text ('left', 'center', 'right').

'left'
valign str

Vertical alignment of the text ('baseline', 'top', 'bottom', 'center').

'baseline'
spacing float

Spacing between characters in mesh units (not used in this implementtion).

0
direction str

Text direction (only 'ltr' and 'rtl' are is supported in this implementation).

'ltr'
language str

Language of the text (not used in this implementation).

''
script str

Script of the text (not used in this implementation).

''

Returns:

Type Description
list[Polygon]

A list of Polygons represnting the text. There may be multiple polygons per character.

Source code in src/scadview/api/text_builder.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def text_polys(
    text: str,
    size: float = 10.0,
    font: str = DEFAULT_FONT,
    halign: str = "left",
    valign: str = "baseline",
    spacing: float = 0,
    direction: str = "ltr",
    language: str = "",
    script: str = "",
) -> list[Polygon]:
    """
    Create a list of Polygons from the given text using the specified font and size.
    This is based on OpenSCAD's text() function,
    but returns 2D polygons instead of a 3D mesh,
    suitable for extrusion or other operations.

    **Font Loading Time Warning**:
    Loading fonts from the system can be time-consuming, especially if the font cache
    needs to be rebuilt. The first time this function is called, it may take several seconds
    to load the font information. Subsequent calls will be faster as the font data is cached.

    **Font Specification**:
    The `font` parameter should be specified in the form "Family:style", e.g. "Arial:style=Bold".
    In SCADview, use Help > List System Fonts to see available fonts on your system,
    and copy the exact name / style string.


    Args:
        text: The text to convert to a polygons.
        size: The size of the text in mesh units.
        font: The font family name and style to use for the text.
            This is in the form "Family:style", e.g. "Arial:style=Bold".
        halign: Horizontal alignment of the text ('left', 'center', 'right').
        valign: Vertical alignment of the text ('baseline', 'top', 'bottom', 'center').
        spacing: Spacing between characters in mesh units (not used in this implementtion).
        direction: Text direction (only 'ltr' and 'rtl' are is supported in this implementation).
        language: Language of the text (not used in this implementation).
        script: Script of the text (not used in this implementation).

    Returns:
        A list of Polygons represnting the text.  There may be multiple polygons per character.
    """
    if text.strip() == "":
        # If the text is empty or contains only spaces, return an empty mesh
        return [Polygon()]
    if direction == "ltr":
        ordered_text = text
    elif direction == "rtl":
        ordered_text = text[::-1]
    else:
        raise ValueError("direction must be ltr or rtl")
    if font == DEFAULT_FONT:
        font_path = DEFAULT_FONT_PATH
    else:
        font_path = list_system_fonts().get(font, None)
    if not font_path:
        logger.warning(
            f"Font '{font}' not found in system fonts. Using default font: {DEFAULT_FONT_PATH}"
        )
        # Use the default font if the specified font is not found
        font_path = DEFAULT_FONT_PATH
    loops = _loops_from_text(ordered_text, font_path, size, halign, valign)
    # polys = polygons_with_holes(loops, _is_loop_orientation_reversed(loops))
    return _make_polys(loops)

scadview.ProfileType = sg.Polygon | NDArray[np.float32] | list[tuple[float, float]] | list[tuple[float, float, float]] | list[list[float]] module-attribute

The type for the 2D profile for extrusion.

scadview.linear_extrude(profile, height, center=False, convexity=None, twist=0.0, slices=None, scale=1.0, fn=None)

OpenSCAD-like linear_extrude(project-to-XY first).

Signature & defaults mirror OpenSCAD: linear_extrude(height, center=false, convexity, twist=0, slices, scale)

Parameters:

Name Type Description Default
profile ProfileType

The 2D shape to extrude. Can be a shapely Polygon, Nx2 or Nx3 ndarray, or list of 2/3-float tuples/lists. If Nx3 or 3d elements in list, the Z values are ignored.

required
height float

The extrusion height.

required
center bool

If true, the solid is centered after extrusion.

False
convexity int | float | None

Accepted but ignored (OpenSCAD uses it for preview rays).

None
twist float

The extrusion twist in degrees.

0.0
scale float | tuple[float, float] | list[float] | NDArray[float32]

Scales the 2D shape by this value over the height of the extrusion. May be scalar or (sx, sy).

1.0
slices int | None

Similar to special variable $fn without being passed down to the child 2D shape.

None
fn int | None

If slices is None and fn is provided (>0), uses slices=fn. Otherwise defaults to 20 (a reasonable OpenSCAD-like fallback).

None

Returns:

Type Description
Trimesh

The extruded shape.

Source code in src/scadview/api/linear_extrude.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def linear_extrude(
    profile: ProfileType,
    height: float,
    center: bool = False,
    convexity: int | float | None = None,
    twist: float = 0.0,
    slices: int | None = None,
    scale: float | tuple[float, float] | list[float] | NDArray[np.float32] = 1.0,
    fn: int | None = None,  # mimic $fn fallback for slices
) -> trimesh.Trimesh:
    """
    OpenSCAD-like linear_extrude(project-to-XY first).

    Signature & defaults mirror OpenSCAD:
      linear_extrude(height, center=false, convexity, twist=0, slices, scale)

    Args:
        profile: The 2D shape to extrude. Can be a shapely Polygon, Nx2 or Nx3 ndarray, or list of 2/3-float tuples/lists.
            If Nx3 or 3d elements in list, the Z values are ignored.
        height: The extrusion height.
        center: If true, the solid is centered after extrusion.
        convexity: Accepted but ignored (OpenSCAD uses it for preview rays).
        twist: The extrusion twist in degrees.
        scale: Scales the 2D shape by this value over the height of the extrusion.
            May be scalar or (sx, sy).
        slices: Similar to special variable $fn without being passed down to the child 2D shape.
        fn: If `slices` is None and `fn` is provided (>0), uses `slices=fn`.
            Otherwise defaults to 20 (a reasonable OpenSCAD-like fallback).

    Returns:
        The extruded shape.

    """
    _raise_if_profile_incorrect_type(profile)
    slices = _determine_slice_value(slices, fn)
    final_scale = _determine_final_scale(scale)

    poly = _as_poly_2d(profile)
    poly = _orient_polygon_rings(poly)
    verts_2d, poly_faces = trimesh.creation.triangulate_polygon(poly)
    verts_2d = verts_2d.astype(np.float32)

    rings = _collect_rings(poly, verts_2d)
    verts_3d = _build_layers(
        verts_2d, rings, slices, height, twist, final_scale, poly.centroid
    )

    faces = _stitch_layers(verts_2d, poly_faces, rings, slices)

    mesh = trimesh.Trimesh(vertices=verts_3d, faces=faces)
    if center:
        mesh = mesh.apply_translation((0, 0, -height / 2))
    return mesh

scadview.manifold_to_trimesh(manifold)

Convert a manifold object to a Trimesh object. From Manifold

Parameters:

Name Type Description Default
manifold Manifold

A manifold object with vertex properties and triangle vertices.

required

Returns:

Type Description
Trimesh

trimesh.Trimesh: A Trimesh object representing the manifold.

Source code in src/scadview/api/utils.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def manifold_to_trimesh(manifold: manifold3d.Manifold) -> trimesh.Trimesh:
    """
    Convert a manifold object to a Trimesh object.
    From [Manifold](https://colab.research.google.com/drive/1VxrFYHPSHZgUbl9TeWzCeovlpXrPQ5J5?usp=sharing#scrollTo=xCHqkWeJXgmJ)

    Args:
        manifold: A manifold object with vertex properties and triangle vertices.

    Returns:
        trimesh.Trimesh: A Trimesh object representing the manifold.
    """
    mesh = manifold.to_mesh()

    if mesh.vert_properties.shape[1] > 3:
        vertices = mesh.vert_properties[:, :3]
        colors = (mesh.vert_properties[:, 3:] * 255).astype(np.uint8)
    else:
        vertices = mesh.vert_properties
        colors = None

    return trimesh.Trimesh(
        vertices=vertices, faces=mesh.tri_verts, vertex_colors=colors
    )