yapcad package

Subpackages

Submodules

yapcad.analytic_surfaces module

Analytic surface definitions for yapCAD.

This module provides native analytic surface representations that store parametric definitions rather than (or in addition to) tessellated meshes. These surfaces can be evaluated at arbitrary (u, v) parameters and tessellated on demand.

Surface types: - PlaneSurface: infinite plane defined by point and normal - SphereSurface: sphere defined by center and radius - CylinderSurface: cylinder defined by axis, radius, and height bounds - ConeSurface: cone defined by apex, axis, half-angle, and height bounds - TorusSurface: torus defined by center, axis, major/minor radii

Each surface stores: - Parameter domain (u, v bounds) - Local coordinate system (origin, axis) - Geometric parameters (radii, angles, etc.) - Optional tessellation cache

Copyright (c) 2025 Richard DeVaul MIT License

yapcad.analytic_surfaces.bspline_surface(control_points, u_knots, v_knots, u_degree, v_degree, *, weights=None, u_range=None, v_range=None)[source]

Create a NURBS/B-spline surface.

The surface is defined by a grid of control points, knot vectors in both parameter directions, and optional weights (for rational B-splines).

Parameters:
  • control_points (list of list of points) – 2D grid of control points [v_rows][u_cols]. Each point is [x, y, z] or [x, y, z, w].

  • u_knots (list of float) – Knot vector in u direction.

  • v_knots (list of float) – Knot vector in v direction.

  • u_degree (int) – Degree of the B-spline in u direction.

  • v_degree (int) – Degree of the B-spline in v direction.

  • weights (list of list of float, optional) – Weights for rational B-splines. If None, all weights are 1.0 (non-rational).

  • u_range (tuple, optional) – Parameter range in u direction. Defaults to (min(u_knots), max(u_knots)).

  • v_range (tuple, optional) – Parameter range in v direction. Defaults to (min(v_knots), max(v_knots)).

Returns:

B-spline surface definition: [‘bspline_surface’, control_points, metadata_dict]

Return type:

list

yapcad.analytic_surfaces.bspline_surface_normal(surf, u, v, delta=1e-06)[source]

Return the normal vector at (u, v) on a B-spline surface.

Computed via finite differences of partial derivatives.

yapcad.analytic_surfaces.cone_surface(apex, axis_direction, half_angle, *, u_range=(0.0, 6.283185307179586), v_range=(0.0, 1.0))[source]

Create an analytic cone surface.

The cone is parameterized as: - u: angular position around the axis (0 to 2*pi) - v: distance from apex along the surface

Parameters:
  • apex (point) – Apex (tip) of the cone.

  • axis_direction (vector) – Direction of the cone axis (from apex, will be normalized).

  • half_angle (float) – Half-angle of the cone in radians.

  • u_range (tuple, optional) – Angular parameter range (default (0, 2*pi)).

  • v_range (tuple, optional) – Distance parameter range from apex (default (0, 1)).

Returns:

Cone surface definition.

Return type:

list

yapcad.analytic_surfaces.cone_surface_normal(surf, u, v)[source]

Return the outward normal vector at (u, v) on a cone surface.

yapcad.analytic_surfaces.cylinder_surface(axis_point, axis_direction, radius, *, u_range=(0.0, 6.283185307179586), v_range=(0.0, 1.0))[source]

Create an analytic cylinder surface.

The cylinder is parameterized as: - u: angular position around the axis (0 to 2*pi) - v: position along the axis (0 to 1 maps to v_range)

Parameters:
  • axis_point (point) – A point on the cylinder axis.

  • axis_direction (vector) – Direction of the cylinder axis (will be normalized).

  • radius (float) – Radius of the cylinder.

  • u_range (tuple, optional) – Angular parameter range (default (0, 2*pi)).

  • v_range (tuple, optional) – Height parameter range (default (0, 1)).

Returns:

Cylinder surface definition.

Return type:

list

yapcad.analytic_surfaces.cylinder_surface_normal(surf, u, v)[source]

Return the outward normal vector at (u, v) on a cylinder surface.

yapcad.analytic_surfaces.evaluate_bspline_surface(surf, u, v)[source]

Evaluate a point on a B-spline surface at parameters (u, v).

Parameters:
  • surf (bspline_surface) – The B-spline surface.

  • u (float) – Parameter values.

  • v (float) – Parameter values.

Returns:

The point on the surface.

Return type:

point

yapcad.analytic_surfaces.evaluate_cone_surface(surf, u, v)[source]

Evaluate a point on a cone surface at parameters (u, v).

Parameters:
  • surf (cone_surface) – The cone surface.

  • u (float) – Angular position (radians).

  • v (float) – Distance from apex along surface.

Returns:

The point on the surface.

Return type:

point

yapcad.analytic_surfaces.evaluate_cylinder_surface(surf, u, v)[source]

Evaluate a point on a cylinder surface at parameters (u, v).

Parameters:
  • surf (cylinder_surface) – The cylinder surface.

  • u (float) – Angular position (radians).

  • v (float) – Axial position.

Returns:

The point on the surface.

Return type:

point

yapcad.analytic_surfaces.evaluate_plane_surface(surf, u, v)[source]

Evaluate a point on a plane surface at parameters (u, v).

Parameters:
  • surf (plane_surface) – The plane surface.

  • u (float) – Parameter values.

  • v (float) – Parameter values.

Returns:

The point on the surface.

Return type:

point

yapcad.analytic_surfaces.evaluate_sphere_surface(surf, u, v)[source]

Evaluate a point on a sphere surface at parameters (u, v).

Parameters:
  • surf (sphere_surface) – The sphere surface.

  • u (float) – Longitude angle (radians).

  • v (float) – Latitude angle (radians).

Returns:

The point on the surface.

Return type:

point

yapcad.analytic_surfaces.evaluate_surface(surf, u, v)[source]

Evaluate a point on an analytic surface at parameters (u, v).

This is a generic dispatcher for all analytic surface types.

yapcad.analytic_surfaces.evaluate_tessellated_surface(surf, u, v)[source]

Evaluate a point on a tessellated surface at parameters (u, v).

Since the surface is pre-tessellated, this uses bilinear interpolation over the bounding box as an approximation.

yapcad.analytic_surfaces.evaluate_torus_surface(surf, u, v)[source]

Evaluate a point on a torus surface at parameters (u, v).

Parameters:
  • surf (torus_surface) – The torus surface.

  • u (float) – Major angle (radians).

  • v (float) – Minor angle (radians).

Returns:

The point on the surface.

Return type:

point

yapcad.analytic_surfaces.is_analytic_surface(obj)[source]

Return True if obj is any type of analytic surface.

yapcad.analytic_surfaces.is_bspline_surface(obj)[source]

Return True if obj is a B-spline surface.

yapcad.analytic_surfaces.is_cone_surface(obj)[source]

Return True if obj is a cone surface.

yapcad.analytic_surfaces.is_cylinder_surface(obj)[source]

Return True if obj is a cylinder surface.

yapcad.analytic_surfaces.is_plane_surface(obj)[source]

Return True if obj is a plane surface.

yapcad.analytic_surfaces.is_sphere_surface(obj)[source]

Return True if obj is a sphere surface.

yapcad.analytic_surfaces.is_tessellated_surface(obj)[source]

Return True if obj is a pre-tessellated surface.

yapcad.analytic_surfaces.is_torus_surface(obj)[source]

Return True if obj is a torus surface.

yapcad.analytic_surfaces.plane_surface(origin, normal, *, u_range=(-1.0, 1.0), v_range=(-1.0, 1.0))[source]

Create an analytic plane surface.

Parameters:
  • origin (point) – A point on the plane.

  • normal (vector) – Normal vector to the plane (will be normalized).

  • u_range (tuple, optional) – Parameter range in u direction (default (-1, 1)).

  • v_range (tuple, optional) – Parameter range in v direction (default (-1, 1)).

Returns:

Plane surface definition: [‘plane_surface’, origin, metadata_dict]

Return type:

list

yapcad.analytic_surfaces.plane_surface_normal(surf, u, v)[source]

Return the normal vector at (u, v) on a plane surface.

For a plane, the normal is constant everywhere.

yapcad.analytic_surfaces.sphere_surface(center, radius, *, u_range=(0.0, 6.283185307179586), v_range=(-1.5707963267948966, 1.5707963267948966))[source]

Create an analytic sphere surface.

The sphere is parameterized as: - u: longitude angle (0 to 2*pi) - v: latitude angle (-pi/2 to pi/2)

Parameters:
  • center (point) – Center of the sphere.

  • radius (float) – Radius of the sphere.

  • u_range (tuple, optional) – Longitude parameter range (default (0, 2*pi)).

  • v_range (tuple, optional) – Latitude parameter range (default (-pi/2, pi/2)).

Returns:

Sphere surface definition: [‘sphere_surface’, center, metadata_dict]

Return type:

list

yapcad.analytic_surfaces.sphere_surface_normal(surf, u, v)[source]

Return the outward normal vector at (u, v) on a sphere surface.

yapcad.analytic_surfaces.surface_normal(surf, u, v)[source]

Return the normal vector at (u, v) on an analytic surface.

This is a generic dispatcher for all analytic surface types.

yapcad.analytic_surfaces.tessellate_surface(surf, *, u_divisions=16, v_divisions=16)[source]

Convert an analytic surface to a tessellated mesh surface.

Parameters:
  • surf (analytic surface) – Any analytic surface type.

  • u_divisions (int) – Number of divisions in u parameter.

  • v_divisions (int) – Number of divisions in v parameter.

Returns:

Tessellated surface: [‘surface’, vertices, normals, faces, boundary, holes]

Return type:

list

yapcad.analytic_surfaces.tessellated_surface(vertices, normals, faces, *, u_range=(0.0, 1.0), v_range=(0.0, 1.0))[source]

Create a pre-tessellated surface (fallback for non-analytic geometry).

This surface type stores an already-tessellated mesh. It cannot be re-tessellated at different resolutions but provides a consistent interface with other analytic surfaces.

Parameters:
  • vertices (list of points) – List of vertex positions.

  • normals (list of vectors) – List of normal vectors (one per vertex or one per face).

  • faces (list of [i, j, k]) – Triangle indices into vertices.

  • u_range (tuple, optional) – Nominal parameter range in u direction.

  • v_range (tuple, optional) – Nominal parameter range in v direction.

Returns:

Tessellated surface definition.

Return type:

list

yapcad.analytic_surfaces.tessellated_surface_normal(surf, u, v)[source]

Return a nominal normal for a tessellated surface.

Returns average of all normals as an approximation.

yapcad.analytic_surfaces.torus_surface(center, axis_direction, major_radius, minor_radius, *, u_range=(0.0, 6.283185307179586), v_range=(0.0, 6.283185307179586))[source]

Create an analytic torus surface.

The torus is parameterized as: - u: angle around the major circle (0 to 2*pi) - v: angle around the minor circle (0 to 2*pi)

Parameters:
  • center (point) – Center of the torus.

  • axis_direction (vector) – Direction of the torus axis (will be normalized).

  • major_radius (float) – Major radius (distance from center to tube center).

  • minor_radius (float) – Minor radius (tube radius).

  • u_range (tuple, optional) – Major angle parameter range (default (0, 2*pi)).

  • v_range (tuple, optional) – Minor angle parameter range (default (0, 2*pi)).

Returns:

Torus surface definition.

Return type:

list

yapcad.analytic_surfaces.torus_surface_normal(surf, u, v)[source]

Return the outward normal vector at (u, v) on a torus surface.

yapcad.brep module

Core Boundary Representation (BREP) helpers for yapCAD.

These classes wrap pythonocc-core objects when that dependency is available. Importing this module on systems without pythonocc-core should not explode; instead, we raise a clear runtime error the first time a BREP feature is requested so users know to activate the conda environment.

class yapcad.brep.BrepEdge(shape: Any)[source]

Bases: object

A wrapper for a TopoDS_Edge.

property shape
class yapcad.brep.BrepFace(shape: Any)[source]

Bases: object

A wrapper for a TopoDS_Face.

property shape
class yapcad.brep.BrepSolid(shape)[source]

Bases: object

A wrapper for a TopoDS_Shape (Solid or Compound of Solids).

property shape
tessellate(deflection=0.5)[source]

Generate a faceted representation of the BREP model.

This method will use pythonocc-core’s meshing capabilities to generate a triangular mesh of the BREP model. The resulting faceted representation will be returned in the same format as yapcad.geom3d.poly2surface.

class yapcad.brep.BrepVertex(shape: Any)[source]

Bases: object

A wrapper for a TopoDS_Vertex.

property shape
yapcad.brep.attach_brep_to_solid(solid: list, brep: BrepSolid) None[source]

Embed serialized BREP data into the solid metadata and cache the shape.

yapcad.brep.brep_from_solid(solid: list) BrepSolid | None[source]

Return the cached BrepSolid for solid if metadata is present.

yapcad.brep.has_brep_data(solid: list) bool[source]
yapcad.brep.is_brep(obj)[source]

Check if an object is a yapCAD BREP object.

yapcad.brep.occ_available() bool[source]

Return True when pythonocc-core imports succeeded.

yapcad.brep.require_occ() None[source]

Raise a descriptive error if pythonocc-core is not installed/activated.

yapcad.combine module

class yapcad.combine.Boolean(type='union', polys=[], *, minang=5.0, minlen=0.25)[source]

Bases: Geometry

Boolean operations on Polygons

property geom

return yapcad.geom representation of figure

mirror(plane)[source]

apply a mirror operation to a figure. Currently, the following values of “plane” are allowed: ‘xz’, ‘yz’, xy’. Generalized arbitrary reflection plane specification will be added in the future.

If keepSign == True (default) the sign of the area will be maintained, meaning that if mirror is applied to a right-handed closed figure (a figure with positive area) the resulting mirrored figure will also have positive area. This is probably what you want, unless you are specifically turning a face into a hole, or vice-versa.

rotate(angle, cent=[0, 0, 0, 1], axis=[0, 0, 1, 1])[source]

apply a rotation to a figure

scale(sx, sy=False, sz=False, cent=[0, 0, 0, 1])[source]

apply a scaling to a figure

transform(m)[source]

apply an arbitrary transformation to a figure, as specified by a transformation matrix.

translate(delta)[source]

apply a translation to figure

property type
types = ('union', 'intersection', 'difference')

yapcad.drawable module

class yapcad.drawable.Drawable[source]

Bases: object

Base class for yapCAD drawables

colordict = {'aliceblue': ([240, 248, 255], None), 'antiquewhite': ([250, 235, 215], None), 'aqua': ([0, 255, 255], 4), 'aquamarine': ([127, 255, 212], None), 'azure': ([240, 255, 255], None), 'beige': ([245, 245, 220], None), 'bisque': ([255, 228, 196], None), 'black': ([0, 0, 0], 0), 'blanchedalmond': ([255, 235, 205], None), 'blue': ([0, 0, 255], 5), 'blueviolet': ([138, 43, 226], None), 'brown': ([165, 42, 42], None), 'burlywood': ([222, 184, 135], None), 'cadetblue': ([95, 158, 160], None), 'chartreuse': ([127, 255, 0], None), 'chocolate': ([210, 105, 30], None), 'coral': ([255, 127, 80], None), 'cornflowerblue': ([100, 149, 237], None), 'cornsilk': ([255, 248, 220], None), 'crimson': ([220, 20, 60], None), 'cyan': ([0, 255, 255], None), 'darkblue': ([0, 0, 139], None), 'darkcyan': ([0, 139, 139], None), 'darkgoldenrod': ([184, 134, 11], None), 'darkgray': ([169, 169, 169], None), 'darkgreen': ([0, 100, 0], None), 'darkgrey': ([169, 169, 169], None), 'darkkhaki': ([189, 183, 107], None), 'darkmagenta': ([139, 0, 139], None), 'darkolivegreen': ([85, 107, 47], None), 'darkorange': ([255, 140, 0], None), 'darkorchid': ([153, 50, 204], None), 'darkred': ([139, 0, 0], None), 'darksalmon': ([233, 150, 122], None), 'darkseagreen': ([143, 188, 143], None), 'darkslateblue': ([72, 61, 139], None), 'darkslategray': ([47, 79, 79], None), 'darkslategrey': ([47, 79, 79], None), 'darkturquoise': ([0, 206, 209], None), 'darkviolet': ([148, 0, 211], None), 'deeppink': ([255, 20, 147], None), 'deepskyblue': ([0, 191, 255], None), 'dimgray': ([105, 105, 105], None), 'dimgrey': ([105, 105, 105], None), 'dodgerblue': ([30, 144, 255], None), 'firebrick': ([178, 34, 34], None), 'floralwhite': ([255, 250, 240], None), 'forestgreen': ([34, 139, 34], None), 'fuchsia': ([255, 0, 255], 6), 'gainsboro': ([220, 220, 220], None), 'ghostwhite': ([248, 248, 255], None), 'gold': ([255, 215, 0], None), 'goldenrod': ([218, 165, 32], None), 'gray': ([128, 128, 128], 8), 'gray0': ([0, 0, 0], None), 'gray1': ([3, 3, 3], None), 'gray10': ([26, 26, 26], None), 'gray100': ([255, 255, 255], None), 'gray11': ([28, 28, 28], None), 'gray12': ([31, 31, 31], None), 'gray13': ([33, 33, 33], None), 'gray14': ([36, 36, 36], None), 'gray15': ([38, 38, 38], None), 'gray16': ([41, 41, 41], None), 'gray17': ([43, 43, 43], None), 'gray18': ([46, 46, 46], None), 'gray19': ([48, 48, 48], None), 'gray2': ([5, 5, 5], None), 'gray20': ([51, 51, 51], None), 'gray21': ([54, 54, 54], None), 'gray22': ([56, 56, 56], None), 'gray23': ([59, 59, 59], None), 'gray24': ([61, 61, 61], None), 'gray25': ([64, 64, 64], None), 'gray26': ([66, 66, 66], None), 'gray27': ([69, 69, 69], None), 'gray28': ([71, 71, 71], None), 'gray29': ([74, 74, 74], None), 'gray3': ([8, 8, 8], None), 'gray30': ([76, 76, 76], None), 'gray31': ([79, 79, 79], None), 'gray32': ([82, 82, 82], None), 'gray33': ([84, 84, 84], None), 'gray34': ([87, 87, 87], None), 'gray35': ([89, 89, 89], None), 'gray36': ([92, 92, 92], None), 'gray37': ([94, 94, 94], None), 'gray38': ([97, 97, 97], None), 'gray39': ([99, 99, 99], None), 'gray4': ([10, 10, 10], None), 'gray40': ([102, 102, 102], None), 'gray41': ([105, 105, 105], None), 'gray42': ([107, 107, 107], None), 'gray43': ([110, 110, 110], None), 'gray44': ([112, 112, 112], None), 'gray45': ([115, 115, 115], None), 'gray46': ([117, 117, 117], None), 'gray47': ([120, 120, 120], None), 'gray48': ([122, 122, 122], None), 'gray49': ([125, 125, 125], None), 'gray5': ([13, 13, 13], None), 'gray50': ([128, 128, 128], None), 'gray51': ([130, 130, 130], None), 'gray52': ([133, 133, 133], None), 'gray53': ([135, 135, 135], None), 'gray54': ([138, 138, 138], None), 'gray55': ([140, 140, 140], None), 'gray56': ([143, 143, 143], None), 'gray57': ([145, 145, 145], None), 'gray58': ([148, 148, 148], None), 'gray59': ([150, 150, 150], None), 'gray6': ([15, 15, 15], None), 'gray60': ([153, 153, 153], None), 'gray61': ([156, 156, 156], None), 'gray62': ([158, 158, 158], None), 'gray63': ([161, 161, 161], None), 'gray64': ([163, 163, 163], None), 'gray65': ([166, 166, 166], None), 'gray66': ([168, 168, 168], None), 'gray67': ([171, 171, 171], None), 'gray68': ([173, 173, 173], None), 'gray69': ([176, 176, 176], None), 'gray7': ([18, 18, 18], None), 'gray70': ([178, 178, 178], None), 'gray71': ([181, 181, 181], None), 'gray72': ([184, 184, 184], None), 'gray73': ([186, 186, 186], None), 'gray74': ([189, 189, 189], None), 'gray75': ([191, 191, 191], None), 'gray76': ([194, 194, 194], None), 'gray77': ([196, 196, 196], None), 'gray78': ([199, 199, 199], None), 'gray79': ([201, 201, 201], None), 'gray8': ([20, 20, 20], None), 'gray80': ([204, 204, 204], None), 'gray81': ([207, 207, 207], None), 'gray82': ([209, 209, 209], None), 'gray83': ([212, 212, 212], None), 'gray84': ([214, 214, 214], None), 'gray85': ([217, 217, 217], None), 'gray86': ([219, 219, 219], None), 'gray87': ([222, 222, 222], None), 'gray88': ([224, 224, 224], None), 'gray89': ([227, 227, 227], None), 'gray9': ([23, 23, 23], None), 'gray90': ([230, 230, 230], None), 'gray91': ([232, 232, 232], None), 'gray92': ([235, 235, 235], None), 'gray93': ([237, 237, 237], None), 'gray94': ([240, 240, 240], None), 'gray95': ([242, 242, 242], None), 'gray96': ([245, 245, 245], None), 'gray97': ([247, 247, 247], None), 'gray98': ([250, 250, 250], None), 'gray99': ([252, 252, 252], None), 'green': ([0, 127, 0], 94), 'greenyellow': ([173, 255, 47], None), 'grey': ([128, 128, 128], None), 'grey0': ([0, 0, 0], None), 'grey1': ([3, 3, 3], None), 'grey10': ([26, 26, 26], None), 'grey100': ([255, 255, 255], None), 'grey11': ([28, 28, 28], None), 'grey12': ([31, 31, 31], None), 'grey13': ([33, 33, 33], None), 'grey14': ([36, 36, 36], None), 'grey15': ([38, 38, 38], None), 'grey16': ([41, 41, 41], None), 'grey17': ([43, 43, 43], None), 'grey18': ([46, 46, 46], None), 'grey19': ([48, 48, 48], None), 'grey2': ([5, 5, 5], None), 'grey20': ([51, 51, 51], None), 'grey21': ([54, 54, 54], None), 'grey22': ([56, 56, 56], None), 'grey23': ([59, 59, 59], None), 'grey24': ([61, 61, 61], None), 'grey25': ([64, 64, 64], None), 'grey26': ([66, 66, 66], None), 'grey27': ([69, 69, 69], None), 'grey28': ([71, 71, 71], None), 'grey29': ([74, 74, 74], None), 'grey3': ([8, 8, 8], None), 'grey30': ([76, 76, 76], None), 'grey31': ([79, 79, 79], None), 'grey32': ([82, 82, 82], None), 'grey33': ([84, 84, 84], None), 'grey34': ([87, 87, 87], None), 'grey35': ([89, 89, 89], None), 'grey36': ([92, 92, 92], None), 'grey37': ([94, 94, 94], None), 'grey38': ([97, 97, 97], None), 'grey39': ([99, 99, 99], None), 'grey4': ([10, 10, 10], None), 'grey40': ([102, 102, 102], None), 'grey41': ([105, 105, 105], None), 'grey42': ([107, 107, 107], None), 'grey43': ([110, 110, 110], None), 'grey44': ([112, 112, 112], None), 'grey45': ([115, 115, 115], None), 'grey46': ([117, 117, 117], None), 'grey47': ([120, 120, 120], None), 'grey48': ([122, 122, 122], None), 'grey49': ([125, 125, 125], None), 'grey5': ([13, 13, 13], None), 'grey50': ([128, 128, 128], None), 'grey51': ([130, 130, 130], None), 'grey52': ([133, 133, 133], None), 'grey53': ([135, 135, 135], None), 'grey54': ([138, 138, 138], None), 'grey55': ([140, 140, 140], None), 'grey56': ([143, 143, 143], None), 'grey57': ([145, 145, 145], None), 'grey58': ([148, 148, 148], None), 'grey59': ([150, 150, 150], None), 'grey6': ([15, 15, 15], None), 'grey60': ([153, 153, 153], None), 'grey61': ([156, 156, 156], None), 'grey62': ([158, 158, 158], None), 'grey63': ([161, 161, 161], None), 'grey64': ([163, 163, 163], None), 'grey65': ([166, 166, 166], None), 'grey66': ([168, 168, 168], None), 'grey67': ([171, 171, 171], None), 'grey68': ([173, 173, 173], None), 'grey69': ([176, 176, 176], None), 'grey7': ([18, 18, 18], None), 'grey70': ([178, 178, 178], None), 'grey71': ([181, 181, 181], None), 'grey72': ([184, 184, 184], None), 'grey73': ([186, 186, 186], None), 'grey74': ([189, 189, 189], None), 'grey75': ([191, 191, 191], None), 'grey76': ([194, 194, 194], None), 'grey77': ([196, 196, 196], None), 'grey78': ([199, 199, 199], None), 'grey79': ([201, 201, 201], None), 'grey8': ([20, 20, 20], None), 'grey80': ([204, 204, 204], None), 'grey81': ([207, 207, 207], None), 'grey82': ([209, 209, 209], None), 'grey83': ([212, 212, 212], None), 'grey84': ([214, 214, 214], None), 'grey85': ([217, 217, 217], None), 'grey86': ([219, 219, 219], None), 'grey87': ([222, 222, 222], None), 'grey88': ([224, 224, 224], None), 'grey89': ([227, 227, 227], None), 'grey9': ([23, 23, 23], None), 'grey90': ([230, 230, 230], None), 'grey91': ([232, 232, 232], None), 'grey92': ([235, 235, 235], None), 'grey93': ([237, 237, 237], None), 'grey94': ([240, 240, 240], None), 'grey95': ([242, 242, 242], None), 'grey96': ([245, 245, 245], None), 'grey97': ([247, 247, 247], None), 'grey98': ([250, 250, 250], None), 'grey99': ([252, 252, 252], None), 'honeydew': ([240, 255, 240], None), 'hotpink': ([255, 105, 180], None), 'indianred': ([205, 92, 92], None), 'indigo': ([75, 0, 130], None), 'ivory': ([255, 255, 240], None), 'khaki': ([240, 230, 140], None), 'lavender': ([230, 230, 250], None), 'lavenderblush': ([255, 240, 245], None), 'lawngreen': ([124, 252, 0], None), 'lemonchiffon': ([255, 250, 205], None), 'lightblue': ([173, 216, 230], None), 'lightcoral': ([240, 128, 128], None), 'lightcyan': ([224, 255, 255], None), 'lightgoldenrodyellow': ([250, 250, 210], None), 'lightgray': ([211, 211, 211], None), 'lightgreen': ([144, 238, 144], None), 'lightgrey': ([211, 211, 211], None), 'lightpink': ([255, 182, 193], None), 'lightsalmon': ([255, 160, 122], None), 'lightseagreen': ([32, 178, 170], None), 'lightskyblue': ([135, 206, 250], None), 'lightslategray': ([119, 136, 153], None), 'lightslategrey': ([119, 136, 153], None), 'lightsteelblue': ([176, 196, 222], None), 'lightyellow': ([255, 255, 224], None), 'lime': ([0, 255, 0], 3), 'limegreen': ([50, 205, 50], None), 'linen': ([250, 240, 230], None), 'magenta': ([255, 0, 255], None), 'maroon': ([127, 0, 0], 14), 'mediumaquamarine': ([102, 205, 170], None), 'mediumblue': ([0, 0, 205], None), 'mediumorchid': ([186, 85, 211], None), 'mediumpurple': ([147, 112, 219], None), 'mediumseagreen': ([60, 179, 113], None), 'mediumslateblue': ([123, 104, 238], None), 'mediumspringgreen': ([0, 250, 154], None), 'mediumturquoise': ([72, 209, 204], None), 'mediumvioletred': ([199, 21, 133], None), 'midnightblue': ([25, 25, 112], None), 'mintcream': ([245, 255, 250], None), 'mistyrose': ([255, 228, 225], None), 'moccasin': ([255, 228, 181], None), 'navajowhite': ([255, 222, 173], None), 'navy': ([0, 0, 128], 174), 'oldlace': ([253, 245, 230], None), 'olive': ([127, 127, 0], 54), 'olivedrab': ([107, 142, 35], None), 'orange': ([255, 165, 0], None), 'orangered': ([255, 69, 0], None), 'orchid': ([218, 112, 214], None), 'palegoldenrod': ([238, 232, 170], None), 'palegreen': ([152, 251, 152], None), 'paleturquoise': ([175, 238, 238], None), 'palevioletred': ([219, 112, 147], None), 'papayawhip': ([255, 239, 213], None), 'peachpuff': ([255, 218, 185], None), 'peru': ([205, 133, 63], None), 'pink': ([255, 192, 203], None), 'plum': ([221, 160, 221], None), 'powderblue': ([176, 224, 230], None), 'purple': ([128, 0, 128], 214), 'rebeccapurple': ([102, 51, 153], None), 'red': ([255, 0, 0], 1), 'rosybrown': ([188, 143, 143], None), 'royalblue': ([65, 105, 225], None), 'saddlebrown': ([139, 69, 19], None), 'salmon': ([250, 128, 114], None), 'sandybrown': ([244, 164, 96], None), 'seagreen': ([46, 139, 87], None), 'seashell': ([255, 245, 238], None), 'sienna': ([160, 82, 45], None), 'silver': ([192, 192, 192], 9), 'skyblue': ([135, 206, 235], None), 'slateblue': ([106, 90, 205], None), 'slategray': ([112, 128, 144], None), 'slategrey': ([112, 128, 144], None), 'snow': ([255, 250, 250], None), 'springgreen': ([0, 255, 127], None), 'steelblue': ([70, 130, 180], None), 'tan': ([210, 180, 140], None), 'teal': ([0, 127, 127], 134), 'thistle': ([216, 191, 216], None), 'tomato': ([255, 99, 71], None), 'turquoise': ([64, 224, 208], None), 'violet': ([238, 130, 238], None), 'wheat': ([245, 222, 179], None), 'white': ([255, 255, 255], 7), 'whitesmoke': ([245, 245, 245], None), 'yellow': ([255, 255, 0], 2), 'yellowgreen': ([154, 205, 50], None)}
colormapAUTOCAD = [[0, 0, 0], [255, 0, 0], [255, 255, 0], [0, 255, 0], [0, 255, 255], [0, 0, 255], [255, 0, 255], [255, 255, 255], [128, 128, 128], [192, 192, 192], [255, 0, 0], [255, 127, 127], [165, 0, 0], [165, 82, 82], [127, 0, 0], [127, 63, 63], [76, 0, 0], [76, 38, 38], [38, 0, 0], [38, 19, 19], [255, 63, 0], [255, 159, 127], [165, 41, 0], [165, 103, 82], [127, 31, 0], [127, 79, 63], [76, 19, 0], [76, 47, 38], [38, 9, 0], [38, 23, 19], [255, 127, 0], [255, 191, 127], [168, 82, 0], [165, 124, 82], [127, 63, 0], [127, 95, 63], [76, 38, 0], [76, 57, 38], [38, 19, 0], [38, 28, 19], [255, 191, 0], [255, 223, 127], [165, 124, 0], [165, 145, 82], [127, 95, 0], [127, 111, 63], [76, 57, 0], [76, 66, 38], [38, 28, 0], [38, 33, 19], [255, 255, 0], [255, 255, 127], [165, 165, 0], [165, 165, 82], [127, 127, 0], [127, 127, 63], [76, 76, 0], [76, 76, 38], [38, 38, 0], [38, 38, 19], [191, 255, 0], [223, 255, 127], [124, 165, 0], [145, 165, 82], [95, 127, 0], [111, 127, 63], [57, 76, 0], [66, 76, 38], [28, 38, 0], [33, 38, 19], [127, 255, 0], [191, 255, 127], [82, 165, 0], [124, 165, 82], [63, 127, 0], [95, 127, 63], [38, 76, 0], [57, 76, 38], [19, 38, 0], [28, 38, 19], [63, 255, 0], [159, 255, 127], [41, 165, 0], [103, 165, 82], [31, 127, 0], [79, 127, 63], [19, 76, 0], [47, 76, 38], [9, 38, 0], [23, 38, 19], [0, 255, 0], [127, 255, 127], [0, 165, 0], [82, 165, 82], [0, 127, 0], [63, 127, 63], [0, 76, 0], [38, 76, 38], [0, 38, 0], [19, 38, 19], [0, 255, 63], [127, 255, 159], [0, 165, 41], [82, 165, 103], [0, 127, 31], [63, 127, 79], [0, 76, 19], [38, 76, 47], [0, 38, 9], [19, 38, 23], [0, 255, 127], [127, 255, 191], [0, 165, 82], [82, 165, 124], [0, 127, 63], [63, 127, 95], [0, 76, 38], [38, 76, 57], [0, 38, 19], [19, 38, 28], [0, 255, 191], [127, 255, 223], [0, 165, 124], [82, 165, 145], [0, 127, 95], [63, 127, 111], [0, 76, 57], [38, 76, 66], [0, 38, 28], [19, 38, 33], [0, 255, 255], [127, 255, 255], [0, 165, 165], [82, 165, 165], [0, 127, 127], [63, 127, 127], [0, 76, 76], [38, 76, 76], [0, 38, 38], [19, 38, 38], [0, 191, 255], [127, 223, 255], [0, 124, 165], [82, 145, 165], [0, 95, 127], [63, 111, 127], [0, 57, 76], [38, 66, 76], [0, 28, 38], [19, 33, 38], [0, 127, 255], [127, 191, 255], [0, 82, 165], [82, 124, 165], [0, 63, 127], [63, 95, 127], [0, 38, 76], [38, 57, 76], [0, 19, 38], [19, 28, 38], [0, 63, 255], [127, 159, 255], [0, 41, 165], [82, 103, 165], [0, 31, 127], [63, 79, 127], [0, 19, 76], [38, 47, 76], [0, 9, 38], [19, 23, 38], [0, 0, 255], [127, 127, 255], [0, 0, 165], [82, 82, 165], [0, 0, 127], [63, 63, 127], [0, 0, 76], [38, 38, 76], [0, 0, 38], [19, 19, 38], [63, 0, 255], [159, 127, 255], [41, 0, 165], [103, 82, 165], [31, 0, 127], [79, 63, 127], [19, 0, 76], [47, 38, 76], [9, 0, 38], [23, 19, 38], [127, 0, 255], [191, 127, 255], [82, 0, 165], [124, 82, 165], [63, 0, 127], [95, 63, 127], [38, 0, 76], [57, 38, 76], [19, 0, 38], [28, 19, 38], [191, 0, 255], [223, 127, 255], [124, 0, 165], [145, 82, 165], [95, 0, 127], [111, 63, 127], [57, 0, 76], [66, 38, 76], [28, 0, 38], [33, 19, 38], [255, 0, 255], [255, 127, 255], [165, 0, 165], [165, 82, 165], [127, 0, 127], [127, 63, 127], [76, 0, 76], [76, 38, 76], [38, 0, 38], [38, 19, 38], [255, 0, 191], [255, 127, 223], [165, 0, 124], [165, 82, 145], [127, 0, 95], [127, 63, 111], [76, 0, 57], [76, 38, 66], [38, 0, 28], [38, 19, 33], [255, 0, 127], [255, 127, 191], [165, 0, 82], [165, 82, 124], [127, 0, 63], [127, 63, 95], [76, 0, 38], [76, 38, 57], [38, 0, 19], [38, 19, 28], [255, 0, 63], [255, 127, 159], [165, 0, 41], [165, 82, 103], [127, 0, 31], [127, 63, 79], [76, 0, 19], [76, 38, 47], [38, 0, 9], [38, 19, 23], [0, 0, 0], [45, 45, 45], [91, 91, 91], [137, 137, 137], [183, 183, 183], [179, 179, 179], False]
display()[source]
draw(x)[source]
draw_arc(p, r, start, end)[source]
draw_bbox(box, dim3=False)[source]
draw_circle(p, r)[source]
draw_ellipse(center, semi_major, semi_minor, rotation, start, end)[source]

Draw an ellipse or elliptical arc.

Parameters:
  • center (point) – Center point of the ellipse.

  • semi_major (float) – Semi-major axis length.

  • semi_minor (float) – Semi-minor axis length.

  • rotation (float) – Rotation of major axis from x-axis in degrees.

  • start (float) – Start angle in degrees.

  • end (float) – End angle in degrees.

draw_line(p1, p2)[source]
draw_point(p)[source]
draw_text(text, location, align='left', attr={})[source]
draw_x(p, d)[source]
property fillcolor
property layer
property layerlist
property linecolor
property linetype
property linewidth
property pointsize
property pointstyle
property polystyle
print()[source]
str()[source]
thing2color(thing, convert='b', colormap=None, colordict=None)[source]

yapcad.ezdxf_drawable module

class yapcad.ezdxf_drawable.ezdxfDraw[source]

Bases: Drawable

display()[source]
draw_arc(p, r, start, end)[source]
draw_ellipse(center, semi_major, semi_minor, rotation, start, end)[source]

Draw an ellipse or elliptical arc to DXF.

DXF ellipse is defined by: - center point - major axis endpoint relative to center - ratio of minor to major axis - start/end parameters (0 to 2*pi)

draw_line(p1, p2)[source]
draw_text(text, location, align=TextEntityAlignment.LEFT, attr={'height': 0.75, 'style': 'LiberationMono'})[source]
property filename
property linetype

yapcad.ezdxf_exporter module

DXF export utilities for yapCAD geometry.

Provides functions to export 2D geometry (region2d, curves, polylines) to DXF format using the ezdxf library via yapCAD’s ezdxfDraw drawable class.

Copyright (c) 2024 yapCAD contributors All rights reserved (MIT License)

yapcad.ezdxf_exporter.is_2d_geometry(geom) bool[source]

Check if geometry is 2D (exportable to DXF as native entities).

Returns True for: - Points, lines, arcs, circles, ellipses - Polylines/polygons - Geometry lists (lists of the above) - Catmull-Rom and NURBS splines

Returns False for: - 3D solids - Surfaces - Unknown types

yapcad.ezdxf_exporter.write_dxf(geometry, output_path: str, layer: str = 'PATHS') bool[source]

Export 2D geometry to a DXF file.

Parameters:
  • geometry – yapCAD 2D geometry (region2d, curves, polylines, etc.)

  • output_path – Path to output DXF file (with or without .dxf extension)

  • layer – DXF layer name (default ‘PATHS’)

Returns:

True if export succeeded, False otherwise.

Supported geometry types: - point: Exported as point entity - line: Exported as LINE entity - arc: Exported as ARC or CIRCLE entity - ellipse: Exported as ELLIPSE entity - polyline/polygon: Exported as series of LINE entities - catmullrom: Sampled and exported as polyline - nurbs: Sampled and exported as polyline - geomlist (region2d): All elements exported

yapcad.ezdxf_exporter.write_dxf_multi(geometries: List[Any], output_path: str, layers: str | List[str] = 'PATHS') bool[source]

Export multiple geometry objects to a single DXF file.

Parameters:
  • geometries – List of yapCAD 2D geometry objects

  • output_path – Path to output DXF file

  • layers – Layer name or list of layer names (one per geometry)

Returns:

True if export succeeded, False otherwise.

yapcad.fasteners module

Parametric fastener helpers (threads + hex-cap screws).

class yapcad.fasteners.HexCapScrewSpec(diameter: float, thread_length: float, shank_length: float, head_height: float, head_flat_diameter: float, washer_thickness: float = 0.5, washer_diameter: float | None = None, shank_diameter: float | None = None, starts: int = 1, thread_arc_samples: int = 180, thread_samples_per_pitch: int = 6)[source]

Bases: object

Dimensions (all millimeters) for build_hex_cap_screw().

diameter: float
head_flat_diameter: float
head_height: float
shank_diameter: float | None = None
shank_length: float
starts: int = 1
thread_arc_samples: int = 180
thread_length: float
thread_samples_per_pitch: int = 6
washer_diameter: float | None = None
washer_thickness: float = 0.5
class yapcad.fasteners.HexNutSpec(diameter: 'float', pitch: 'float', width_flat: 'float', thickness: 'float', handedness: 'str' = 'right', starts: 'int' = 1, thread_arc_samples: 'int' = 180, thread_samples_per_pitch: 'int' = 6)[source]

Bases: object

diameter: float
handedness: str = 'right'
pitch: float
starts: int = 1
thickness: float
thread_arc_samples: int = 180
thread_samples_per_pitch: int = 6
width_flat: float
yapcad.fasteners.build_hex_cap_screw(profile: ThreadProfile, spec: HexCapScrewSpec)[source]

Create a watertight solid representing a hex cap screw.

Parameters:
  • profile – External thread profile describing nominal diameter/pitch.

  • spec – Geometry parameters (all millimeters).

yapcad.fasteners.build_hex_nut(profile: ThreadProfile, spec: HexNutSpec)[source]
yapcad.fasteners.metric_hex_cap_catalog()[source]
yapcad.fasteners.metric_hex_cap_screw(size: str, length: float, *, thread_length: float | None = None, starts: int = 1, thread_arc_samples: int = 180, thread_samples_per_pitch: int = 6)[source]

Return a hex screw for a metric size (e.g. 'M8').

yapcad.fasteners.metric_hex_nut(size: str, *, starts: int = 1, handedness: str = 'right', thread_arc_samples: int = 180, thread_samples_per_pitch: int = 6)[source]
yapcad.fasteners.metric_hex_nut_catalog()[source]
yapcad.fasteners.unified_hex_cap_catalog()[source]
yapcad.fasteners.unified_hex_cap_screw(size: str, length_in: float, *, thread_length_in: float | None = None, starts: int = 1, thread_arc_samples: int = 180, thread_samples_per_pitch: int = 6)[source]

Return a hex screw for a UNC/UNF imperial size (e.g. '1/4-20').

yapcad.fasteners.unified_hex_nut(size: str, *, starts: int = 1, handedness: str = 'right', thread_arc_samples: int = 180, thread_samples_per_pitch: int = 6)[source]
yapcad.fasteners.unified_hex_nut_catalog()[source]

yapcad.geom module

foundational computational geometry library for yapCAD

OVERVIEW

The yapcad.geom module provides foundational computational geometry functions for yapCAD. This includes operations for computing intersections, bounding boxes, inside-outside testing, etc., on both simple and compound geometry.

yapcad.geom geometric representations

The yapcad.geom module includes constants, scalar operations, vector operations, operations on non-compound geometry elements such as points, lines and arcs, as well as operations on compound geometry elements such as multi-vertex polylines and polygons, and arbitrary geometry lists.

constants

yapcad.geom provides the “constants” epsilon and pi2 (2*pi). Redefine these at your peril.

scalars

Scalar numbers in yapCAD are ordinary Python3 int or float numbers. This means that in general you will have ordinary double-precision floating point dynamic range and precision for your computational geometry operations. These precision limitations are reflected in the empirically-chosen value of epsilon of 5E-6.

vectors

vectors are defined as a list of four numbers, i.e. [x,y,z,w]

When vectors in yapCAD are interpreted as three-dimensional coordinates (as opposed to lists of parameters) the “extra” w coordinate is a normalization factor. This approach is sometimes referred to as generalized homogeneous coordinates or projective coordinates, and was popular with computer graphicists in the 1990s. See https://en.wikipedia.org/wiki/Homogeneous_coordinates

In this interpretation, the w coordinate is a normalization coordinate, and is either 1.0 or all coordinates are assumed to be scaled by 1/w. The inclusion of the w coordinate allows the general use of transformation matrices for affine transforms.

The exception to the above statement is direction vectors, such as the vector [1,0,0,0] that represents the direction of the x axis. Direction vectors live in the w=0.0 plane and are subject to rotation and scaling, but not translation.

There is a yapcad.geom convenience function, vect(), that will make a vector out of just about any plausible set of arguments. Unspecified w values are set to 1, and unspecified z values are set to 0.

yapcad.geom simple (non-compound) figures

points

Points are the simplest of the yapcad.geom figures. Ordinary yapCAD geometry is assumed to lie in the w=1 hyperplane, and when a vector lies in that plane it is usually interpreted as transformable coordinate, or point. Because we expect w=1 unless certain types of affine transforms have been applied, most yapCAD geometry operations do not look at the w coordinate, and operate as though w=1.

Any vector that lies in the w>0 half-space is a valid coordinate, or point. And in yapCAD, [x,y,z,w] corresponds to the same 3D coordinate as [x/w,y/w,z/w,1]

yapcad.geom provides the point() convenience function that operates much like vect(), except that point() enforces that w is always greater than zero.

All of the following are examples of a yapcad.geom point:

pnt1 = point(0,0)
pnt2 = point(2.0,-2.0,5.0)
pnt3 = vect(0,0,0,1)
pnt4 = [1.0, 2.0, 3.0, 1.0]

lines

Lines are Python3 lists of two points, e.g. the following are all lines:

line1 = line(point(0,0),point(1,1))
line2 = line(point(-5,-5,-5),point(5,5,5))
line3 = [point(x1,y1,z1),point(x2,y2,z2)]

Lines are paramaterized over the interval 0 <= u <= 1 where u=0 corresponds to the first point, and u=1 corresponds to the second. Points on the interval between 0 and 1 are considered to be “inside” the line segment, and points outside the interval are still on the line, but not inside the line segment. This distinction is important for intersection calculations, among other operations.

Lines support all standard yapcad.geom computational geometry operations. (see below)

bounding boxes

One special type of yapcad.geom line is a 3D bounding box. A bounding box is a line that spans the “left lower bottom” to “right upper top” of a figure, e.g. bbx = [[xmin,ymin,zmin,1],[xmax,ymax,zmax,1]]. Bounding boxes are used internally to speed up inside/outside testing and for a variety of other purposes.

arcs

In yapcad.geom, an arc or circle is defined by a center, a radius, a start angle, an end angle, and a normal that specifies the plane of the arc/circle. Here are some examples of yapcad.geom arcs:

circle1 = arc(point(5.0,5.0),5.0) # full circle implied
circle2 = arc(point(5.0,5.0),5.0,0,360) # special values for start and end
notCirc = arc(point(5.0,5.0),5.0,90.0,450.0) # zero-length arc due to mod 360.0
semicirc1 = arc(point(0,0),10.0,90.0,270.0)
arc2 = arc(point(-1,1,10),1.0,-45.0,45.0,point(0,0,1),samplereverse=True)

Angles are specified in degrees and are right-handed, which is to say a positive angle specifies a counter-clockwise sweep.

A full circle is specified through special values of start and end; If and only if start == 0 and end == 360 (both integer values) then the arc is a full circle. NOTE: Other values for start and end that span a 360 degree difference will actually produce a zero-length arc, which is probably not what you want.

Arcs are paramaterized over an interval 0 <= u <=1, where u=0 corresponds to the point on the arc at the start angle, and u=1 corresponds to the point on the arc at the end angle (unless samplereverse==True, see below). Parameters less than zero or greater than one correspond to point on the circle outside the angular interval between start and end. NOTE: In the special case of a circle, the point at u=0 and u=1 is the same. Parameters which correspond to angles greater than 360 degrees or less than zero degrees “wrap around” to the corresponding angle modulus 360.

An arc is is represented as a list of one or two vectors and a quasivector, e.g. [ center, [radius, start, end, -1 ], <normal>]. Most of the time, we assume that arcs lie in the x-y plane, which is to say yapCAD assumes normal = [0,0,1] if it’s not specified. NOTE: At present, yapCAD doesn’t support non-unit-z normal vectors for arcs, though it will not stop you from specifying one.

To mark that the second list element is a quasivector, we set the w component to a negative value. Since negative w values should never exist for points in our projective geometry system this should be a robust convention. For ordinary arcs, w=-1. For sample-reversed arcs (left-handed arcs, where u=0 begins at the end angle, and u=1 is the start angle) w=-2

NOTE: Sample-reverse arcs are left-handed with respect to the sampling parameter, not with respect to the specification of angles. This means that two arcs that are geometrically the same except for sampling order will have the beneficial property of having the same start and end values.

Arcs support all standard yapcad.geom computational geometry operations. (see below)

yapcad.geom compound figures

polylines/polygons

A polyline is specified as a list of three or more points which define a series of continuous line segments. A polygon is a list of four or more coplanar points, where the first and last points are coincident, i.e. dist(points[0],points[-1]) < epsilon. Here are some examples:

plyline1 =[point(-5,-5),point(5,-5),point(0,5),point(0,10)]
plygon1 =[point(-5,-5),point(5,-5),point(0,5),point(-5,-5)]

Polylines are parameterized in much the same way as lines. Values 0 <= u <=1 correspond to points along the polyline or polygon between the start and end points. In the case of the non-closed polyline, values of u<0 correspond to points on the line in the negative u parameter space of the first line segment, and values of u>1 correspond to points on the line in the u>1 space of the last line segment.

Polygons are parameterized in the same way, with the exception that, like circles, the value at u=0 and u=1 are the same, and u values outside the [1,0] interval “wrap around” (are subject to u % 1.0) and thus always return a point on the line segments that make up the polygon.

Polygons with positive area are defined in right-hand (counterclockwise) order. A polygon with left-hand point order has negative area, and implies a hole in a larger surface.

Polylines and polygons support all standard yapcad.geom computational geometry operations. (see below)

geometry lists

Geometry lists are pretty much exactly what they sound like, which is to say a Python3 list of other yapcad.geom elements. There is nothing enforcing continuity of elements in a geometry list, so if continuity, coplanar elements, a closed representation, etc. are required, these constraints must be checked or enforced by the functions that operate on them.

Even though there is no inherent continuity constraint, geometry lists do support element-ordered sampling, unsampling, and intersection, as well as bounding box calculation and even inside-outside testing, though the results of such testing will only make sense for geometry lists composed of closed elements.

Geometry lists are paramaterized a bit like polylines, except that there is no guarantee of continuity.

COMPUTATIONAL GEOMETRY OPERATIONS

The primary purpose of the yapcad.geom module is to support computational geometry operations on two-dimensional figures in three-dimensional space.

All of the yapcad.geom geometry representations, or figures, described here support the following operations:

  • length(x) – return the scalar length of figure x

  • center(x) – return the center point of figure x

  • bbox(x) – return the three-dimensional bounding box of x

  • sample(x,u) – parameterizing figure x over the closed interval [0,1], return the point on x corresponding to the parameter u.

  • unsample(x,p) – given a point p and figure x, parameterizing x over the closed interval [0,1], return the parameter u resulting in the point closest to p, or False if no point on x lies within epsilon of p. FIXME: Unsampling of geometry lists is currently unimplemented.

  • segment(x,u1,u2) – given a figure x and two scalar parameters u1 != u2 and u1 >= 0 and u2 >= 0 and u1 <= 1 and u2 <= 1, return a new figure sliced from the original figure spanning the specified sampling interval.

  • isinsideXY(x,p) – for figure x and point p that lie in the same XY plane, determine whether p lies within epsilon of the interior of figure x. In the case where x is a point, line, or polyline where there is no two-dimensional interior defined, determine if p lies on or within epsilon of the 0 <= u <=1 parameter domain of figure x.

  • intersectXY(g1,g2,inside=True,params=False) – Compute the intersections of the two figures g1 and g2 that lie in the same XY plane. If parameter inside == True, then the intersection is only considered valid if it lies within the parameter domain 0 <= u <= 1 for each figure. Return a list of intersection points, or the boolean value False if there are none. If params==True, then return a list of intersection parameter values for each figure, or False if there are no intersections.

In addition to the above, yapcad.geom supports following affine transformation operations for all figures:

  • scale(x,sx=1.0,sy=False,sz=False,cent=point(0,0)) – scale the figure x, either uniformly or by specified factors in x, y, and z. Returns a new scaled figure.

  • translate(x,delta) – translate the figure x by the specified delta vector. Returns a new translated figure.

  • rotate(x,ang,cent=point(0,0),axis=point(0,0,1.0)) – rotate the figure x by angle ang degrees about point cent and axis axis. Returns a new rotated figure.

  • mirror(x,plane) – mirror the figure x by the axis-aligned, origin-intersecting plane specified by the string plane in ['xy','yz','xz']. FIXME: Allow for the specification of an arbitrary plane described by an intersection point and a normal, or by three points in space. Return a new mirrored figure.

  • transform(x,m) – apply the arbitrary transformation specified by matrix m (see the documentation for yapcad.xform) to figure x. Return a new transformed figure.

specialized computational geometry operations

operations on points

Points are defined as vectors that lie in a positive, non-zero hyperplane, i.e. [x, y, z, w] such that w > 0. points are distinguished from quasivectors, such as the parameters to an arc, which don’t transform as vectors.

Quasivectors, by contrast, lie in a w < 0 hyperplane. For example, by convention right-handed arc parameters lie in the quasivector w=-1 hyperplane.

The yapcad.geom module provides a relatively full set of vector operations for adding, subtracting, computing inner and outer products, scaling, etc., including versions that treat yapcad.geom points/vectors as 3 vectors and versions that treat them as 4 vectors.

Other notable computational geometry operations on points:

  • barycentricXY(a,p1,p2,p3): – Given a point a and three vertices p1, p2, and p3, all of which fall into the same XY plane, compute the barycentric coordinates lam1, lam2, and lam3 and return them as a list.

operations on lines

There are several line-specific computational geometry operations, notably:

  • linePointXY(l,p,inside=True,distance=False,params=False) – For a point p and a line l that lie in the same XY plane, compute the point on l that is closest to p, and return that point. If inside is true, then return the closest distance point between the point and the line segment. If distance is true, return the closest distance, not the point. If params is true, return the sampling parameter value of the closest point.

  • linePointXYDist(l,p,inside=True) – Convenience function wrapping fast point-line distance calculation using linePointXY()

operations on arcs

In addition to the standard operations, there are several arc-specific computational geometry operations, notably:

  • lineArcIntersectXY(l,c,inside=True,params=False) – Value safe function to compute the intersection of a line l and an arc c that lie in the same XY plane. If inside == True only return intersections that lie within the line and arc segment, otherwise treat the line as infinite and the arc as a circle. Return a list of intersection points, or if params == True return a list of intersection parameters instead.

  • circleCircleTangentsXY(c0,c1) – Value-safe function to compute tangent lines to two coplanar circles c0 and c1 lying in the same XY plane. Function will either return two lines or False, if the center of the circles are too close together.

operations on polylines and polygons

In addition to the standard operations, there are several polyline- and polygon-specific computational geometry operations, notably:

  • samplepoly(a,u) – Sample the poly a at parameter u, where u is mapped proportionally across the length of all line segments, and return the resulting point. If a is a closed polygon, then sample at u % 1.0, such that samples outside the [0,1] interval “wrap around”. If a is not closed and u<0, then samples are drawn from the first line in the u<0 paramter space of that line. If a is not closed and u>1, then samples are drawn from the last line in the u>1 paramter space of that line.

yapcad.geom.add(a, b)[source]

3 vector, a + b

yapcad.geom.add4(a, b)[source]

4 vector a + b

yapcad.geom.arc(c, rp=False, sn=False, e=False, n=False, samplereverse=False)[source]

Construct an arc by copying an eisting arc or specifying a center c and various optional parameters.

yapcad.geom.arcArcIntersectXY(c1, c2, inside=True, params=False)[source]

Value-safe function to compute the intersection of two arcs that lie in the same XY plane. If inside == True, only count intersections within the arc segments. If inside == False, then treat the arcs as circles for intersection calculation. Return a list of the intersection points, or if params==True return a list of the intersection parameters for each arc.

yapcad.geom.arcbbox(c)[source]

return bounding box for arc

yapcad.geom.arccenter(c)[source]

return the midpoint of an arc. In the special case of a complete circle, return the center of the circle.

yapcad.geom.arclength(c)[source]

return scalar length of an arc

yapcad.geom.barycentricXY(a, p1, p2, p3)[source]

Given a point a and three vertices p1, p2, and p3, all of which fall into the same XY plane, compute the barycentric coordinates lam1, lam2, and lam3

yapcad.geom.bbox(x)[source]

Given a figure x, return the three-dimensional bounding box of the figure.

yapcad.geom.catmullrom(points, closed=False, alpha=0.5)[source]

Return a Catmull-Rom spline definition.

yapcad.geom.center(x)[source]

Return the point corresponding to the center of figure x.

yapcad.geom.circleCircleTangentsXY(c0, c1)[source]

Value-safe function to compute tangent lines to two coplanar circles c0 and c1 lying in the same XY plane. Function will either return two lines or False, if the center of the circles are too close together.

yapcad.geom.close(a, b)[source]

are two scalars the same within epsilon

yapcad.geom.cross(a, b)[source]

Compute the cross generalized product of a x b, assuming that both fall into the w=1 hyperplane

yapcad.geom.dist(a, b)[source]

compute the euclidean disgtance between two 3 vector points a and b

yapcad.geom.dist4(a, b)[source]

4 vector distance calculation

yapcad.geom.dot(a, b)[source]

3 vector a dot b

yapcad.geom.dot4(a, b)[source]

4 vect dot product

yapcad.geom.ellipse(center, semi_major, semi_minor, *, rotation=0.0, start=0, end=360, normal=None)[source]

Return an ellipse curve definition.

Parameters:
  • center (point) – Center point of the ellipse.

  • semi_major (float) – Semi-major axis length (must be >= semi_minor).

  • semi_minor (float) – Semi-minor axis length.

  • rotation (float, optional) – Rotation of major axis from x-axis in degrees (default 0).

  • start (float, optional) – Start angle in degrees (default 0).

  • end (float, optional) – End angle in degrees (default 360 for full ellipse).

  • normal (point, optional) – Normal vector for 3D orientation (default [0,0,1,0]).

Returns:

Ellipse definition: ['ellipse', center, metadata_dict]

Return type:

list

Notes

The ellipse is parameterized so that angle=0 corresponds to the positive major axis direction. Angles increase counter-clockwise. When start=0 and end=360, a full ellipse is created.

yapcad.geom.ellipse_bbox(e, segments=36)[source]

Compute the bounding box of an ellipse.

Parameters:
  • e (ellipse) – The ellipse.

  • segments (int, optional) – Number of sample points (default 36).

Returns:

Bounding box as [min_point, max_point].

Return type:

list

yapcad.geom.ellipse_length(e, segments=100)[source]

Approximate the arc length of an ellipse using numerical integration.

Parameters:
  • e (ellipse) – The ellipse.

  • segments (int, optional) – Number of segments for approximation (default 100).

Returns:

Approximate arc length.

Return type:

float

yapcad.geom.ellipse_sample(e, u)[source]

Evaluate a point on an ellipse at parameter u in [0, 1].

Parameters:
  • e (ellipse) – The ellipse to sample.

  • u (float) – Parameter value in [0, 1].

Returns:

The point on the ellipse at parameter u.

Return type:

point

yapcad.geom.ellipse_tangent(e, u)[source]

Return the tangent vector at parameter u on an ellipse.

Parameters:
  • e (ellipse) – The ellipse.

  • u (float) – Parameter value in [0, 1].

Returns:

Unit tangent vector (direction, w=0).

Return type:

list

yapcad.geom.geomlistbbox(gl)[source]
yapcad.geom.homo(a)[source]

Homogenize, or project back to the w=1 plane by scaling all values by w

yapcad.geom.hyperbola(center, semi_major, semi_minor, *, rotation=0.0, start=-2.0, end=2.0, branch=1, normal=None)[source]

Return a hyperbola curve definition.

Parameters:
  • center (point) – Center point of the hyperbola.

  • semi_major (float) – Semi-major axis length (a), the distance from center to vertex.

  • semi_minor (float) – Semi-minor axis length (b), determines the opening angle.

  • rotation (float, optional) – Rotation of the major axis from the x-axis in degrees (default 0).

  • start (float, optional) – Start parameter value (default -2.0).

  • end (float, optional) – End parameter value (default 2.0).

  • branch (int, optional) – Which branch to use: 1 for right branch (+x), -1 for left branch (-x). Default is 1.

  • normal (point, optional) – Normal vector for 3D orientation (default [0,0,1,0]).

Returns:

Hyperbola definition: ['hyperbola', center, metadata_dict]

Return type:

list

Notes

The hyperbola is defined as: x² / a² - y² / b² = 1 Parametric form: x = a * cosh(t), y = b * sinh(t) The parameter t ranges from start to end. At t=0, the point is at (a, 0).

yapcad.geom.hyperbola_bbox(h, segments=50)[source]

Compute the bounding box of a hyperbola segment.

Parameters:
  • h (hyperbola) – The hyperbola.

  • segments (int, optional) – Number of sample points (default 50).

Returns:

Bounding box as [min_point, max_point].

Return type:

list

yapcad.geom.hyperbola_length(h, segments=100)[source]

Approximate the arc length of a hyperbola segment using numerical integration.

Parameters:
  • h (hyperbola) – The hyperbola.

  • segments (int, optional) – Number of segments for approximation (default 100).

Returns:

Approximate arc length.

Return type:

float

yapcad.geom.hyperbola_sample(h, u)[source]

Evaluate a point on a hyperbola at parameter u in [0, 1].

Parameters:
  • h (hyperbola) – The hyperbola to sample.

  • u (float) – Parameter value in [0, 1].

Returns:

The point on the hyperbola at parameter u.

Return type:

point

yapcad.geom.hyperbola_tangent(h, u)[source]

Return the tangent vector at parameter u on a hyperbola.

Parameters:
  • h (hyperbola) – The hyperbola.

  • u (float) – Parameter value in [0, 1].

Returns:

Unit tangent vector (direction, w=0).

Return type:

list

yapcad.geom.intersectGeomListXY(g, gl, inside=True, params=False)[source]
yapcad.geom.intersectSimplePolyXY(g, a, inside=True, params=False)[source]
yapcad.geom.intersectSimpleXY(g1, g2, inside=True, params=False)[source]

value-safe function that determines the intersection of two XY-coplanar non-compound geometric figures

yapcad.geom.intersectXY(g1, g2, inside=True, params=False)[source]

given two XY-coplanar figures, calculate the intersection of these two figures, and return a list of intersection points, or False if none. If inside == True, only return intersections that are within the 0 <= u <= 1.0 interval for both figures. If params == True, instead of returning a list of points, return two lists corresponding to the sampling parameter value of the intersections corresponding to each figure.

yapcad.geom.isCardinalPlanar(plane='xy', points=[])[source]

utility function to determine if a list of points lies in the specified # cardinal plane, one of XY, YZ, XZ

yapcad.geom.isInsideConvexPolyXY(a, poly)[source]
yapcad.geom.isInsideTriangleXY(a, poly)[source]
yapcad.geom.isXYPlanar(points=[])[source]

do all points in list lie in XY plane?

yapcad.geom.isXZPlanar(points=[])[source]

do all points in list lie in XZ plane?

yapcad.geom.isYZPlanar(points=[])[source]

do all points in list lie in YZ plane?

yapcad.geom.isarc(a)[source]

is it an arc?

yapcad.geom.iscatmullrom(obj)[source]

Return True if obj is a Catmull-Rom spline.

yapcad.geom.iscircle(a)[source]

is it a circle?

yapcad.geom.isclosedgeomlist(a)[source]

Determine if geometry list a is closed, which is to say determine if the geometry list is continuous and the distance between sample(a,0.0) and sample(a,1.0) is less than epsilon. NOTE: This test will not detemrine if this geometry list representes a simple closed figure as there could be any number of self intersections.

NOTE: The special case of a==[] will cause isclosedgeomlist(a) to return True, so that set operations such as intersection or difference operations which return an empty result will still be considered valid closed geometry for further operations.

yapcad.geom.iscontinuousgeomlist(a)[source]

deterine if geometry list a posesses C0 continuity over sampling interval [0.0,1.0].

yapcad.geom.isdirect(x)[source]
yapcad.geom.isdirectlist(xx)[source]
yapcad.geom.isellipse(obj)[source]

Return True if obj is an ellipse curve.

yapcad.geom.isfullellipse(obj)[source]

Return True if obj is a full (closed) ellipse.

yapcad.geom.isgeomlist(a)[source]

determine if argument a is a valid geometry list

yapcad.geom.isgeomlistXYPlanar(gl)[source]
yapcad.geom.isgoodnum(n)[source]

determine if an argument is actually a scalar number, and not boolean

yapcad.geom.ishyperbola(obj)[source]

Return True if obj is a hyperbola curve.

yapcad.geom.isinsideXY(x, p)[source]

for an XY-coplanar point and figure, determine if the point lies inside the figure. In the case of non-closed figures, such as lines, determine if the point lies within epsilon of one of the lines of the figure.

yapcad.geom.isinsidearcXY(c, p)[source]

Determine if point p lies on (within epsilon of) the arc ``c`. In the special case where c is a circle, determine if point p lies anywhere on or inside the circle.

yapcad.geom.isinsidebbox(bbox, p)[source]

does point p lie inside 3D bounding box bbox?

yapcad.geom.isinsidebbox2D(bbox, p)[source]

does point p lie inside 2D bounding box bbox?

yapcad.geom.isinsidegeomlistXY(a, p)[source]
yapcad.geom.isinsidelineXY(l, p)[source]

inside testing for line – only true of point lies on line, to within epsilon.

yapcad.geom.isinsidepointXY(x, p)[source]

inside testing for points. Only true if points are the same within epsilon

yapcad.geom.isinsidepolyXY(a, p)[source]

Determine if point p lies on (within epsilon of) the polyline ``a`. In the case where a is a closed polygon, determine if point p lies anywhere within the polygon by even-odd line intersection method.

yapcad.geom.isline(l)[source]

is it a line?

yapcad.geom.isnurbs(obj)[source]

Return True if obj is a NURBS curve.

yapcad.geom.isparabola(obj)[source]

Return True if obj is a parabola curve.

yapcad.geom.ispoint(x)[source]

is it a point?

yapcad.geom.ispoly(a)[source]

is a a poly?

yapcad.geom.ispolygon(a)[source]

is a a polygon?

yapcad.geom.ispolygonXY(a)[source]

is a an XY-coplanar polygon?

yapcad.geom.issimple(g)[source]

determine if the argument is a simple (non-compound) figure

yapcad.geom.istriangle(a)[source]
yapcad.geom.isvect(x)[source]

check to see if argument is a proper vector for our purposes

yapcad.geom.length(x)[source]

Return the scalar length of figure x.

yapcad.geom.line(p1, p2=False)[source]

Value-safe line creation

yapcad.geom.lineArcIntersectXY(l, c, inside=True, params=False)[source]

Value safe function to compute the intersection of a line l and an arc c that lie in the same XY plane. If inside == True only return intersections that lie within the line and arc segment, otherwise treat the line as infinite and the arc as a circle. Return a list of intersection points, or if params == True return a list of intersection parameters instead.

yapcad.geom.lineLineIntersectXY(l1, l2, inside=True, params=False)[source]

Compute the intersection of two lines that lie in the same XY plane. NOTE: It’s usually preferable to use the generalized intersectXY() function than this non-type-safe, line-specific one.

yapcad.geom.linePointXY(l, p, inside=True, distance=False, params=False)[source]

For a point p and a line l that lie in the same XY plane, compute the point on l that is closest to p, and return that point. If inside is true, then return the closest distance point between the point and the line segment. If distance is true, return the closest distance, not the point. If params is true, return the sampling parameter value of the closest point.

yapcad.geom.linePointXYDist(l, p, inside=True)[source]

Convenience function wrapping point-line distance calculation using linePointXY()

yapcad.geom.linebbox(l)[source]

compute 3D line bounding box

yapcad.geom.linecenter(l)[source]

return the center of a line

yapcad.geom.linelength(l)[source]

return the length of a line

yapcad.geom.mag(a)[source]

compute the magnitude of 3 vector a

yapcad.geom.mag4(a)[source]

4 vect magnitude calculation

yapcad.geom.mirror(x, plane)[source]

return a mirrored version of a figure. Currently, the following values of “plane” are allowed: ‘xz’, ‘yz’, xy’. Generalized arbitrary reflection plane specification will be added in the future.

NOTE: this operation will reverse the sign of the area of x if x is a closed polyline or geometry list

yapcad.geom.mul(a, b)[source]

component-wise 3 vector multiplication

yapcad.geom.mul4(a, b)[source]

component-wise 3 vector multiplication

yapcad.geom.nurbs(control_points, *, degree=3, weights=None, knots=None)[source]

Return a NURBS curve definition.

yapcad.geom.orthoXY(a)[source]

compute an orthogonal vector to vector a which lies in an XY plane by crossing [a1, a2, a3] with [0, 0, 1]

yapcad.geom.parabola(vertex, focal_length, *, rotation=0.0, start=-10.0, end=10.0, normal=None)[source]

Return a parabola curve definition.

Parameters:
  • vertex (point) – Vertex point of the parabola (the point closest to the focus).

  • focal_length (float) – Distance from vertex to focus (must be positive). The parabola opens in the positive x-direction (before rotation).

  • rotation (float, optional) – Rotation of the parabola axis from the x-axis in degrees (default 0).

  • start (float, optional) – Start parameter value (default -10.0).

  • end (float, optional) – End parameter value (default 10.0).

  • normal (point, optional) – Normal vector for 3D orientation (default [0,0,1,0]).

Returns:

Parabola definition: ['parabola', vertex, metadata_dict]

Return type:

list

Notes

The parabola is defined as: x = t²/(4p), y = t, where p is the focal length. The parameter t ranges from start to end. At t=0, the point is at the vertex. Positive t values move in the positive y-direction, negative in the negative.

yapcad.geom.parabola_bbox(p, segments=50)[source]

Compute the bounding box of a parabola segment.

Parameters:
  • p (parabola) – The parabola.

  • segments (int, optional) – Number of sample points (default 50).

Returns:

Bounding box as [min_point, max_point].

Return type:

list

yapcad.geom.parabola_length(p, segments=100)[source]

Approximate the arc length of a parabola segment using numerical integration.

Parameters:
  • p (parabola) – The parabola.

  • segments (int, optional) – Number of segments for approximation (default 100).

Returns:

Approximate arc length.

Return type:

float

yapcad.geom.parabola_sample(p, u)[source]

Evaluate a point on a parabola at parameter u in [0, 1].

Parameters:
  • p (parabola) – The parabola to sample.

  • u (float) – Parameter value in [0, 1].

Returns:

The point on the parabola at parameter u.

Return type:

point

yapcad.geom.parabola_tangent(p, u)[source]

Return the tangent vector at parameter u on a parabola.

Parameters:
  • p (parabola) – The parabola.

  • u (float) – Parameter value in [0, 1].

Returns:

Unit tangent vector (direction, w=0).

Return type:

list

yapcad.geom.point(x=False, y=False, z=False, w=False)[source]

Point creation from point or scalars

yapcad.geom.pointCircleTangentsXY(p, c1)[source]
yapcad.geom.pointbbox(x)[source]

compute 3D bounding box of point, which is 2 epsilon on a side. Note, this guarantees that two points that are wtihin epsilon of eachother will be within each other’s bbox

yapcad.geom.pointcenter(x)[source]

the center of a point is…. the same point

yapcad.geom.pointlength(x)[source]

an odd, completionist function that always returns zero

yapcad.geom.poly(*args)[source]

Make a polyline or polygon by copying an existing poly or from a list of points or individual points

yapcad.geom.polybbox(a)[source]

Compute the 3D bounding box of polyline/polygon a

yapcad.geom.polycenter(a)[source]

Compute center of poly a. If a is closed, return barycentric center of figure. If a is not closed, return sampling midpoint.

yapcad.geom.polylength(a)[source]

compute length of poly a

yapcad.geom.reverseGeomList(gl)[source]
yapcad.geom.rotate(x, ang, cent=[0, 0, 0, 1], axis=[0, 0, 1.0, 1], mat=False)[source]

return a rotated version of the figure

yapcad.geom.sample(x, u)[source]

Given a figure x and a parameter u, return the point on the figure corresponding to the specified sampling parameter.

yapcad.geom.samplearc(c, u, polar=False)[source]

sample the arc c at parameter u and return the resulting point. If polar is true, return polar coordinates of angle and radius with cartesian center.

yapcad.geom.samplegeomlist(gl, u)[source]
yapcad.geom.sampleline(l, u)[source]

Sample a parameterized line l. Values 0 <= u <= 1.0 will fall within the line segment, values u < 0 and u > 1 will fall outside the line segment.

yapcad.geom.samplepoint(x, u)[source]

whatever parameter you pass to sampling a point, you get the same point

yapcad.geom.samplepoly(a, u)[source]

Sample the poly a at parameter u and return the resulting point. If a is a closed polygon, then sample at u % 1.0. If a is not closed and u<0, then samples are drawn from the first line in the u<0 paramter space of that line. If a is not closed and u>1, then samples are drawn from the last line in the u>1 paramter space of that line.

yapcad.geom.scale(x, sx=1.0, sy=False, sz=False, cent=[0, 0, 0, 1], mat=False)[source]

return a scaled version of the figure

yapcad.geom.scale3(a, c)[source]

3 vector, vector ‘’a’’ times scalar c, a * c

yapcad.geom.scale4(a, c)[source]

4 vector a times scalar c

yapcad.geom.segment(x, u1, u2)[source]

given a figure x, create a new figure spanning the specified interval in the original figure

yapcad.geom.segmentarc(c, u1, u2)[source]

Given an arc paramaterized on a 0,1 interval, return a new arc with the same center and radius spanning the interval u1,u2

yapcad.geom.segmentgeomlist(gl, u1, u2, closed=False, reverse=False)[source]
yapcad.geom.segmentline(l, u1, u2)[source]

slice out a parameterized segment from a line and return this as a new line segment

yapcad.geom.segmentpoly(a, u1, u2)[source]

slice out a parameterized segment from polyline or polygon a and return this as a new polyline

yapcad.geom.sub(a, b)[source]

3 vector, a - b

yapcad.geom.sub4(a, b)[source]

4 vector a - b

yapcad.geom.transform(x, m)[source]

return a transformed version of the figure, as specified by the transformation matrix m

yapcad.geom.translate(x, delta)[source]

return a translated version of the figure

yapcad.geom.unsample(x, p)[source]

Invert the sampling operation: return the parameter corresponding to the closest point on the figure to p as long as the distance is less than epsilon.

yapcad.geom.unsamplearc(c, p)[source]

unsample the arc c at point p, which is to day given a point that is on the circle, return it’s corresponding sample parameter, or False if the point is more than epsilon from the circle.

yapcad.geom.unsamplegeomlist(gl, p)[source]

anlogous to the unsampleline() and unsamplearc() functions, given a point on a poly, return the corresponding sample parameter, or False if the point is more than epsilon away from any poly line segment

yapcad.geom.unsampleline(l, p)[source]

function to “unsample” a line – given a point on a line, provide the corresponding parametric value. Return False if the distance of the point from the line is greater than epsilon

yapcad.geom.unsamplepoly(a, p)[source]

anlogous to the unsampleline() and unsamplearc() functions, given a point on a poly, return the corresponding sample parameter, or False if the point is more than epsilon away from any poly line segment

yapcad.geom.vclose(a, b)[source]
yapcad.geom.vect(a=False, b=False, c=False, d=False)[source]

Convenience function for making a homogeneous coordinates 4 vector from practically anything

yapcad.geom.vstr(a)[source]

utility function for recursively checking and formatting lists

yapcad.geom3d module

yapcad.geom3d.addTri2Surface(tri, s, check=False, nfunc=<function normfunc>)[source]

Add triangle tri (a list of three points) to a surface s, returning the updated surface. NOTE: There is no enforcement of contiguousness or coplainarity – this function will add any triangle.

yapcad.geom3d.bbox(x)[source]

Given a figure, surface, or solid x, return the three-dimensional bounding box of that entity.

yapcad.geom3d.center(x)[source]

Return the point corresponding to the center of surface, solid, or figure x.

yapcad.geom3d.issolid(s, fast=True)[source]

Check to see if s is a solid. NOTE: this function only determines if th data structure is correct, it does not verify that the collection of surfaces completely bounds a volume of space without holes

yapcad.geom3d.issolidclosed(x)[source]

Check if solid x is topologically closed.

A solid is closed if and only if every edge is shared by exactly two faces across all surfaces. This ensures no holes or gaps exist in the solid’s boundary.

The function analyzes face adjacency by: 1. Building a global edge map using vertex positions (not indices) 2. Counting how many faces share each edge 3. Verifying that every edge is shared by exactly 2 faces

Parameters:

x – A solid data structure

Returns:

True if the solid is topologically closed, False otherwise

Raises:

ValueError – if x is not a valid solid

Example

>>> from yapcad.geom3d_util import prism, sphere
>>> cube = prism(2, 2, 2)
>>> issolidclosed(cube)
True
yapcad.geom3d.issurface(s, fast=True)[source]

Check to see if s is a valid surface.

yapcad.geom3d.linePlaneIntersect(lne, plane='xy', inside=True)[source]

Function to calculate the intersection of a line and a plane.

line is specified in the usual way as two points. plane is either specified symbolicly as one of ["xy","yz","xz"], a list of three points, or a planar coordinate system in the form of [p0,n,forward,reverse], where p0 specifies the origin in world coordinates, n is the normal (equivalent to the z vector), and forward and reverse are transformation matricies that map from world into local and local into world coordinates respectively.

Returns False if the line and plane do not intersect, or if inside==True and the point of intersection is outside the line interval. Returns the point of intersection otherwise.

NOTE: if plane is specified as three points, then setting inside=True will also force a check to see if the intersection point falls within the specified triangle.

yapcad.geom3d.mirror(x, plane)[source]

return a mirrored version of a figure. Currently, the following values of “plane” are allowed: ‘xz’, ‘yz’, xy’. Generalized arbitrary reflection plane specification will be added in the future.

NOTE: this operation will reverse the sign of the area of x if x is a closed polyline or geometry list

yapcad.geom3d.mirrorsolid(x, plane, preserveNormal=True)[source]
yapcad.geom3d.mirrorsurface(s, plane)[source]

return a mirrored version of a surface. Currently, the following values of “plane” are allowed: ‘xz’, ‘yz’, xy’. Generalized arbitrary reflection plane specification will be added in the future.

Note that this is a full surface geometry reflection, and not simply a normal reverser.

yapcad.geom3d.normfunc(tri)[source]

utility funtion to compute normals for a flat facet triangle

yapcad.geom3d.poly2surface(ply, holepolys=[], minlen=0.5, minarea=0.0001, checkclosed=False, basis=None)[source]

Given ply, a coplanar polygon, return the triangulated surface representation of that polygon and its boundary. If holepolys is not the empty list, treat each polygon in that list as a hole in ply. If checkclosed is true, make sure ply and all members of holepolys are a vaid, closed, coplanar polygons. if box exists, use it as the bounding box.

if basis exists, use it as the planar coordinate basis to transform the poly into the z=0 plane.

Returns surface and boundary

yapcad.geom3d.poly2surfaceXY(ply, holepolys=[], minlen=0.5, minarea=0.0001, checkclosed=False, box=None)[source]

Given ply, return a triangulated XY surface (holes supported).

yapcad.geom3d.reversesurface(s)[source]

return a nomal-reversed copy of the surface

yapcad.geom3d.rotate(x, ang, cent=[0, 0, 0, 1], axis=[0, 0, 1.0, 1], mat=False)[source]

return a rotated version of the surface, solid, or figure

yapcad.geom3d.rotatesolid(x, ang, cent=[0, 0, 0, 1], axis=[0, 0, 1.0, 1], mat=False)[source]
yapcad.geom3d.rotatesurface(s, ang, cent=[0, 0, 0, 1], axis=[0, 0, 1.0, 1], mat=False)[source]

return a rotated copy of the surface

yapcad.geom3d.scale(x, sx=1.0, sy=False, sz=False, cent=[0, 0, 0, 1])[source]

Return a scaled version of the surface, solid, or figure.

Parameters:
  • x (solid, surface, or figure) – The geometry to scale.

  • sx (float) – Scale factor for x-axis, or uniform scale if sy and sz are False.

  • sy (float or False) – Scale factor for y-axis, or False for uniform scaling.

  • sz (float or False) – Scale factor for z-axis, or False for uniform scaling.

  • cent (point) – Center point for scaling. Default is origin.

Returns:

A scaled copy of the input geometry.

Return type:

geometry

yapcad.geom3d.scalesolid(x, sx=1.0, sy=False, sz=False, cent=[0, 0, 0, 1])[source]

Return a scaled copy of the solid.

Parameters:
  • x (solid) – The solid to scale.

  • sx (float) – Scale factor for x-axis, or uniform scale if sy and sz are False.

  • sy (float or False) – Scale factor for y-axis, or False for uniform scaling.

  • sz (float or False) – Scale factor for z-axis, or False for uniform scaling.

  • cent (point) – Center point for scaling. Default is origin.

Returns:

A scaled copy of the input solid.

Return type:

solid

Notes

BREP data is only scaled for uniform scaling (sx == sy == sz). Non-uniform scaling will preserve the mesh but not the BREP representation.

yapcad.geom3d.scalesurface(s, sx=1.0, sy=False, sz=False, cent=[0, 0, 0, 1])[source]

Return a scaled copy of the surface.

Parameters:
  • s (surface) – The surface to scale.

  • sx (float) – Scale factor for x-axis, or uniform scale if sy and sz are False.

  • sy (float or False) – Scale factor for y-axis, or False for uniform scaling.

  • sz (float or False) – Scale factor for z-axis, or False for uniform scaling.

  • cent (point) – Center point for scaling. Default is origin.

Returns:

A scaled copy of the input surface.

Return type:

surface

yapcad.geom3d.signedFaceDistance(p, face)[source]

given a test point p and a three-point face face, determine the minimum signed distance of the test point from the face. Any point lying in the positive normal direction or on the surface of the plane will result in a zero or positive distace. Any point lying in the negative normal direction from the surface of the plane will result in a negative distance.

yapcad.geom3d.signedPlaneDistance(p, p0, n)[source]

Given a point on the plane p0, and the unit-length plane normal n, determine the signed distance to the plane.

yapcad.geom3d.solid(*args)[source]

given a solid or a list of solid parameters as arguments, return a conforming solid representation. Checks arguments for data-type correctness.

yapcad.geom3d.solid_boolean(a, b, operation, tol=1e-07, *, stitch=False, engine=None)[source]

Perform a boolean operation (union, intersection, difference) on two solids.

Engine selection: - If engine parameter or YAPCAD_BOOLEAN_ENGINE env var is set,

that engine is used explicitly (backward compatible behavior).

  • Otherwise, auto-selects OCC BREP engine when available and both solids have BREP metadata, falling back to mesh engine on failure or when BREP data is missing.

  • Fallback mesh engine is selectable via YAPCAD_MESH_BOOLEAN_ENGINE env var (defaults to ‘native’).

Environment variables: - YAPCAD_BOOLEAN_ENGINE: Force specific engine (‘native’, ‘trimesh’, ‘occ’) - YAPCAD_MESH_BOOLEAN_ENGINE: Fallback mesh engine (‘native’ or ‘trimesh’) - YAPCAD_TRIMESH_BACKEND: Backend for trimesh engine (e.g., ‘manifold’, ‘blender’)

yapcad.geom3d.solidbbox(sld)[source]
yapcad.geom3d.solids_intersect(a, b, tol=1e-07)[source]

geom3d – functional 3D geometry representation for yapCAD

The geometric representations of point, line, arc, poly, and geomlist provided by yapcad.geom are suitable for representing zero- or one-dimensional figures embedded in a three-dimensional space. And while there is no requirement that the representations provided by yapcad.geom (such as an arc, line, or polyline) lie in the XY plane, many of the functions in yapcad.geom are explicitly intended to perform computational geometry operations on XY-planar entities.

Further, while a closed figure described by yapcad.geom may implicitly bound a two-dimensional face, there is no direct support for working with two-dimensional surfaces provided by that module. There is no direct support of any kind for working with three-dimemnsional volumes in yapcad.geom.

In this module we specify representations for two-dimensional surfaces and bounded three-dimensional volumes, and provide tools for working with them in implicit, parametric form as well as in explicit, triangulated form.

The goal of the geom3d.yapcad module is to allow for the construction of two-dimensinal surfaces and three-dimensional geometry for the purposes of modeling, computational geometry, and rendering. Specifically, we wish to support the following:

(1) Support the implicit representation of three-dimensional geometry, and the performance of constructive solid geometry operations on this implicit geometry (union, intersection, difference) to produce more complex implicit three dimensional forms.

(2) Support the implicit representation of two dimensional surfaces, such as a planar surface specified by three points, or the surface of a three-dimensional object like a sphere, and allow for computational geometry operations on these surfaces, such as intersection operations, to produce explicit one-dimensional objects, such as lines, arcs, etc.

(3) support the conversion of an implicit two-dimensional surface to an explicit, teselated triangluar geometry that may be easily rendered using a conventional 3D graphics rendering pipline, such as OpenGL

(4) Support for the conversion of implicit three-dimenaional constructive solid geometry into an explicit, contiguous closed surface representation using the marching cubes algortihm, or any other user-specified conversion algoritm, for the purposes of interactive 3D rendering and conversion to 3D CAM formats, such as STL.

Structures for 2D/3D geometry

surfaces

surface = ['surface',vertices,normals,faces,boundary,holes], where:

vertices is a list of yapcad.geom points,

normals is a list of yapcad.geom direction vectors of the same length as vertices,

faces is the list of faces, which is to say lists of three indices that refer to the vertices of the triangle that represents each face,

boundary is a list of indices for the vertices that form the outer perimeter of the surface, or [] if the surface has no boundary, such as that of a torus or sphere

holes is a (potentially zero-length) list of lists of holes, each of which is a non-zero list of three or more indices of vertices that form the perimeter of any holes in the surface.

A surface has an inside and an outside. To deterine which side of a surface a point lies on, find the closest face and determine if the point lies on the positive or negative side of the face.

Solids

To represent a completely bounded space (a space for which any point can be unambiguously determined to be inside or outside) there is the solid representation. A solid is composed of zero or more surfaces, and may be completely empty, as empty solids are legal products of constructive solid geometry operations like intersection and difference.

The gurantee, which is not enforced by the representation, is that for any point inside the bounding box of the solid, and for any point chosen outside the bounding box of the solid, a line drawn between the two will have either even (or zero), or odd point intersections (as opposed to tangent intersections), regardless of the choice of the outside-the-bounding-box point.

Solids have optional associated metadata about the material properties of the solid and about how it was constructed.

For example, material properties might include OpenGL-type rendering data, mechanical properties, or a reference to a material dictionary that includes both.

Construction meta-data might include the model-file and material-file name from which the geometry was loaded, the polygon from which the solid was extruded (and associated extrusion parameters), or the function call with parameters for algorithmically-generated geometry.

solid = ['solid', surfaces, material, construction ], where:

surfaces is a list of surfaces with contiguous boundaries that completely encloses an interior space,

material is a list of domain-specific representation of the material properties of the solid, which may be empty. This information may be used for rendering or simulating the properties of the solid.

construction is a list that contains information about how the solid was constructed, and may be empty

Topology Analysis

Two key functions are provided for analyzing solid topology:

issolidclosed(solid) – Verifies that a solid is topologically closed by ensuring every edge is shared by exactly two faces across all surfaces. This is essential for determining if a solid properly encloses a volume without gaps or holes. Returns True if closed, False otherwise.

volumeof(solid) – Calculates the volume enclosed by a closed solid using the divergence theorem. Requires that the solid be topologically closed (verified by calling issolidclosed()). Returns the volume as a non-negative floating point number.

Example usage:

from yapcad.geom3d_util import prism
from yapcad.geom3d import issolidclosed, volumeof

cube = prism(2, 2, 2)
if issolidclosed(cube):
    vol = volumeof(cube)  # Returns 8.0
Assembly

Assemblies are lists of elements, which are solids or assemblies, in which each list has an associated geometric transformation.

assembly = ['assembly', transform, elementlist], where:

transform = [xformF, xformR], a pair of forward and inverse

transformation matricies such that xformF * xformR = the identity matrix.

elementlist = [element0, elememnt1, ... ], in which each

list element is either a valid solid or assembly.

yapcad.geom3d.surf2lines(surf)[source]

convert a surface representation to a non-redundant set of lines for line-based rendering purposes

yapcad.geom3d.surface(*args)[source]

given a surface or a list of surface parameters as arguments, return a conforming surface representation. Checks arguments for data-type correctness.

yapcad.geom3d.surfacearea(surf)[source]

given a surface, return the surface area

yapcad.geom3d.surfacebbox(s)[source]

return bounding box for surface

yapcad.geom3d.translate(x, delta)[source]

return a translated version of the surface, solid, or figure

yapcad.geom3d.translatesolid(x, delta)[source]
yapcad.geom3d.translatesurface(s, delta)[source]

return a translated copy of the surface

yapcad.geom3d.tri2p0n(face, basis=False)[source]

Given face, a non-degenrate poly of length 3, return the center point and normal of the face, otherwise known as the Hessian Normal Form: https://mathworld.wolfram.com/HessianNormalForm.html

In addition, if basis==True, calculate an orthnormal basis vectors implied by the triangle, with the x’ vector aligned with the p1-p2 edge, the z’ vector as the nornal vector, and the y’ vector as -1 * x’ x z’, and return the transformation matrix that will transform a point in world coordinates to a point in the orthonormal coordinate system with the origin at the center point. Return that transformation matrix and its inverse.

yapcad.geom3d.triTriIntersect(t1, t2, inside=True, inPlane=False, basis=None)[source]

Function to compute the intersection of two triangles. Returns False if no intersection, a line (a list of two points) if the planes do not overlap and there is a linear intersection, and a polygon (list of three or more points) if the triangles are co-planar and overlap.

If inside == True (default) return line-segment or poly intersection that falls inside both bounded triangles, otherwise return a line segment that lies on the infinite linear intersection of two planes, or False if planes are degenerate.

If inPlane==True, return the intersection as a poly in the planar coordinate system implied by t1, or in the planar coordinate system specified by basis

If basis is not False, it should be planar coordinate system in the form of [p0,n,forward,reverse], where p0 specifies the origin in world coordinates, n is the normal (equivalent to the z vector), and forward and reverse are transformation matricies that map from world into local and local into world coordinates respectively.

NOTE: when basis is True and inPlane is False, it is assumed that basis is a planar basis computed by tri2p0n coplanar with t1.

yapcad.geom3d.volumeof(x)[source]

Calculate the volume enclosed by a solid.

Uses the divergence theorem to compute volume from the surface triangulation. For each triangular face with vertices (p0, p1, p2), the signed volume contribution is: V_i = (1/6) * dot(p0, cross(p1-p0, p2-p0))

The total volume is the sum of absolute values of all face contributions.

Parameters:

x – A solid data structure (must be topologically closed)

Returns:

The volume of the solid (always non-negative)

Return type:

float

Raises:

ValueError – if x is not a valid solid or is not closed

Example

>>> from yapcad.geom3d_util import prism
>>> cube = prism(2, 2, 2)
>>> abs(volumeof(cube) - 8.0) < 0.001
True

yapcad.geom3d_util module

yapcad.geom3d_util.addVertex(nv, nn, verts, normals)[source]

Utility function that takes a vertex and associated normal and a list of corresponding vertices and normals, and returns an index that corresponds to the given vertex/normal. If the vertex doesn’t exist in the list, the lists are updated to include it and the corresponding normal.

returns the index, and the (potentiall updated) lists

yapcad.geom3d_util.circleSurface(center, radius, angr=10, zup=True)[source]

make a circular surface centered at center lying in the XY plane with normals pointing in the positive z direction if zup == True, negative z otherwise

yapcad.geom3d_util.conic(baser, topr, height, center=[0, 0, 0, 1], angr=10)[source]

Make a conic frustum splid, center is center of first ‘base’ circle, main axis aligns with positive z. This function can be used to make a cone, a conic frustum, or a cylinder, depending on the parameters.

baser is the radius of the base, must be greater than zero (epsilon).

topr is the radius of the top, may be zero or positive. If 0 <= topr < epsilon, then the top is treated as a single point.

height is distance from base to top, must be greater than epsilon.

center is the location of the center of the base.

angr is the requested angular resolution in degrees for sampling circles. Actual angular resolution will be 360/round(360/angr)

yapcad.geom3d_util.conic_tube(bottom_outer_diameter, top_outer_diameter, wall_thickness, length, center=None, *, base_point=None, minang=5.0, include_caps=True)[source]

Create a conic tube with varying outer diameter.

base_point (or center legacy argument) marks the axial base of the frustum (the larger-diameter end when stacked).

yapcad.geom3d_util.contour(poly, distance, direction, samples, scalefunc=<function <lambda>>)[source]

take a closed polygon and apply a scaling function defined on the interval 0,1 that returns a tuple of x,y,z scaling values. For each of samples number of samples, translate in direction direction and scale the contour according to scalefunc(), producing a surface.

yapcad.geom3d_util.extrude(surf, distance, direction=[0, 0, 1, 0])[source]

Take a surface and extrude it in the specified direction to create a solid. Return the solid.

yapcad.geom3d_util.makeIcoPoints(center, radius)[source]

Procedure to generate the verticies of an icosohedron with the specified center and radius.

yapcad.geom3d_util.makeLoftSolid(lower_loop, upper_loop, *, metadata=None)[source]

Create a solid loft between two planar loops (matching vertex counts). Attempts to attach a native BREP when pythonocc-core is available, otherwise falls back to the tessellated representation.

yapcad.geom3d_util.makeRevolutionSolid(contour, zStart, zEnd, steps, arcSamples=36, metadata=None)[source]

Build a solid of revolution around the Z axis. When pythonocc-core is available, a native BREP is attached; otherwise we fall back to the tessellated representation.

yapcad.geom3d_util.makeRevolutionSurface(contour, zStart, zEnd, steps, arcSamples=36, *, return_brep=False)[source]

Generate a surface of revolution by sampling a contour function.

Parameters:
  • contour – callable mapping z to a radial distance

  • zStart – lower bound for the z interval

  • zEnd – upper bound for the z interval

  • steps – number of contour samples between zStart and zEnd

  • arcSamples – number of samples around the revolution arc

Returns:

['surface', vertices, normals, faces] list representing the surface

yapcad.geom3d_util.makeRevolutionThetaSamplingSurface(contour, zStart, zEnd, arcSamples=360, endcaps=False, degrees=True, *, return_brep=False)[source]

Generate a surface of revolution using a theta-dependent contour.

If return_brep is True and the contour is axisymmetric (identical for all theta and wrap_shift == 0), a native BREP solid is also returned; otherwise the second return value is None.

yapcad.geom3d_util.prism(length, width, height, center=[0, 0, 0, 1])[source]

make a rectangular prism solid composed of six independent faces

yapcad.geom3d_util.rectangularPlane(length, width, center=[0, 0, 0, 1])[source]

return a rectangular surface with the normals oriented in the positive z direction

yapcad.geom3d_util.sphere(diameter, center=[0, 0, 0, 1], depth=2)[source]
yapcad.geom3d_util.sphere2cartesian(lat, lon, rad)[source]

Convert spherical polar coordinates to Cartesian coordinates for a sphere centered at the origin.

Parameters:
  • lat – latitude in degrees

  • lon – longitude in degrees

  • rad – sphere radius

Returns:

yapcad.geom point in homogeneous coordinates

yapcad.geom3d_util.sphereSurface(diameter, center=[0, 0, 0, 1], depth=2)[source]
yapcad.geom3d_util.spherical_shell(outer_diameter, wall_thickness, solid_angle=12.566370614359172, center=[0, 0, 0, 1], *, minang=5.0, steps=24)[source]

Create a spherical shell or cap defined by a solid angle.

yapcad.geom3d_util.stack_solids(solids, *, axis='z', start=0.0, gap=0.0, align='center')[source]

Return translated copies of solids stacked along an axis.

yapcad.geom3d_util.subdivide(f, verts, normals, rad)[source]

Given a face (a list of three vertex indices), a list of vertices, normals, and a radius, subdivide that face into four new faces and update the lists of vertices and normals accordingly.

return the updated vertex and normal lists, and a list of the four new faces.

yapcad.geom3d_util.sweep_adaptive(profile, spine, *, inner_profiles=None, angle_threshold_deg=5.0, frame_mode='minimal_twist', up_samples=None, ruled=True, metadata=None)[source]

Sweep a profile along a path with adaptive tangent tracking.

The profile normal tracks the path tangent. New profile sections are generated whenever the tangent direction changes by more than the threshold angle. Uses BRepOffsetAPI_ThruSections to loft between sections.

Parameters:
  • profile – yapCAD region2d for outer boundary (in XY plane, centered at origin)

  • spine – path3d dict with line/arc segments

  • inner_profiles – Optional region2d or list of region2d for inner voids. Supports multiple voids (e.g., split pipe for heat exchanger). Creates hollow solids by boolean subtraction.

  • angle_threshold_deg – Angle change (degrees) that triggers new section (default 5.0)

  • frame_mode – One of: - ‘minimal_twist’: Profile ‘up’ stays consistent (default) - ‘frenet’: Natural Frenet frame (may twist at inflections) - ‘custom’: Use up_samples for interpolated orientation

  • up_samples – For frame_mode=’custom’, list of [t, [ux, uy, uz]] pairs where t in [0,1] is path parameter and [ux,uy,uz] is up vector. Vectors are normalized automatically.

  • ruled – If True (default), use ruled surfaces that preserve straight edges. If False, use smooth interpolation between sections.

  • metadata – Optional metadata dict

Returns:

yapCAD solid created by lofting between adapted sections

yapcad.geom3d_util.sweep_profile_along_path(profile, spine, *, inner_profile=None, metadata=None)[source]

Sweep a 2D profile along a 3D path (spine) to create a solid.

This uses OCC’s BRepOffsetAPI_MakePipe to create the swept solid. The profile should be a closed 2D region (list of line/arc segments in XZ plane). The spine is a path3d dict containing line and arc segments.

Parameters:
  • profile – A yapCAD region2d (list of 2D curve segments forming a closed loop) This is the OUTER boundary of the profile.

  • spine

    A path3d dict with format: {

    ’type’: ‘path3d’, ‘segments’: [

    {‘type’: ‘line’, ‘start’: [x,y,z], ‘end’: [x,y,z]}, {‘type’: ‘arc’, ‘center’: [x,y,z], ‘start’: [x,y,z], ‘end’: [x,y,z], ‘normal’: [nx,ny,nz]}, …

    ]

    }

  • inner_profile – Optional yapCAD region2d for the inner boundary (hole). If provided, creates a hollow profile (like a box girder).

  • metadata – Optional dict of metadata to attach

Returns:

A yapCAD solid representing the swept shape

yapcad.geom3d_util.tube(outer_diameter, wall_thickness, length, center=None, *, base_point=None, minang=5.0, include_caps=True)[source]

Create a cylindrical tube solid.

base_point (or legacy center argument) identifies the base of the cylindrical wall, i.e. the plane where z == base_point[2].

yapcad.geom_util module

yapcad.geom_util.combineglist(g1, g2, operation)[source]

function to perform set operations on geometry lists.

g1 and g2 are closed figure geometry lists. operation is one of ["union","intersection","difference"]

result is a potentially zero-length geometry list representing the result, which may or may not be simply connected, but should always be a closed figure.

yapcad.geom_util.geomlist2poly(gl, minang=5.0, minlen=0.25, checkcont=False)[source]
yapcad.geom_util.geomlist2poly_components(gl, minang=5.0, minlen=0.25, checkcont=False)[source]

Return a list of (outer, holes) tuples extracted from gl.

yapcad.geom_util.geomlist2poly_with_holes(gl, minang=5.0, minlen=0.25, checkcont=False)[source]
yapcad.geom_util.makeArcSpiral(center, turnRad, turns, dstep=45)[source]

given a center point, the increase in radius per turn, the number of turns, and the angular resolution of the approximation, generate an approximation of the spiral using circular arcs as segments instead of straightlines. Return a yapcqad.geom geomlist approximation of the spiral

yapcad.geom_util.makeLineSpiral(center, turnRad, turns, dstep=10.0, minlen=0.25)[source]

given a center point, the increase in radius per turn, the number of turns, and the angular resolution of the approximation, generate a yapcqad.geom poly approximation of the spiral

yapcad.geom_util.polarSampleArc(c, ang, inside=True)[source]

given an arc c , sample that arc at ang degrees from the start of the arc, proceeding clockwise. If samplereverse is true, sample the arc at -ang degrees from the end, proceeding counterclockwise. If c is not a complete circle and the specified ang falls outside the closed [start,end] interval and inside == True, return False, otherwise return the sampled value.

yapcad.geom_util.randomArc(bbox, minr=0.0, maxr=10.0, circle=False)[source]

given a bounding box and a minimum and maximum radius, generate an arc with random center and radius that falls within the bounding box. If circle==False, use randomly generated start and end angles, otherwise generate only full circles

yapcad.geom_util.randomCenterInBox(bbox, r)[source]

given a bounding box and a radius, generate a random center point such that a circle with the specified radius and center point falls completely inside the box

yapcad.geom_util.randomPoints(bbox, numpoints)[source]

Given a 3D bounding box and a number of points to generate, return a list of uniformly generated random points within the bounding box

yapcad.geom_util.randomPoly(bbox, numpoints=10, minr=1.0, maxr=10.0)[source]

given a bounding box, a number of vertices, and a minimum and maximum radius, generate a simple polygon that completely lies inside the bounding box, whose vertices are evenly spaced by angle around a center point, with randomly chosen radius between minr and maxr

yapcad.geom_util.triarea(p1, p2, p3)[source]

utility function to return the area of a triangle

yapcad.geometry module

object-oriented computational geometry figure classes for yapCAD

Overview

The yapcad.geometry module provides the Geometry class. At its most basic level, the Geometry class wrapps yapcad.geom figures and caches properties, such as the figure’s bounding box, length, center, etc., speeding certain computational geometry operations.

Why would I use yapcad.geometry vs. yapcad.geom

You might perfer the convenience and simplicity of the object-oriented interface as a way to access the underlying power of the yapcad.geom and associated modules. In addition, in many cases it is actually more efficient to use the Geometry class wrappers for figures rather than the yapcad.geom figures themselves because of the memoizing and caching feautres provided.

For examle, Geometry class provides wrappers around the yapcad.geom3d poly2surface() function for the triangulation of figures into triangle mesh surfaces, which is cached. This, in turn, provides the foundations for extrusions and the construction of 3D triangluated objects.

Likewise, for compound figures above a certain complexity threshold, the Geometry class implements an internal quadtree decomposition of the figure to speed intersection testing. This is done in a lazy way, which is to say that the quadtree is constructed the first time intersection calculation is requested, and persists for as long as the figure’s geometry remains unchanged. NOTE: Fixeme, quadtree-based intersection not yet implemented

object oriented vs. functional approch

The yapcad.geom module generally takes a functional programming approach, minimizing side effects. This comes at the cost of some redundant computation, as the representation of yapcad.geom figures are generally quite minimal, and properties such as centers, bounding boxes, lengths, etc., must be recomputed each time they are requested, unless the user has made their own explicit cache.

By contrast, the Geometry class caches these properties, and can provide higher efficiency for certain types of complex operations. In addition, derived classes provide representations and functionality absent from the underlying functional representations, such as “growable” polygons, boolean operations, etc..

yapcad.geometry conveneince functions

Convenience functions, such as Line(), Arc(), etc., operate analogously to their uncapitalized counterparts in yapcad.geom, creating Geometry class instances wrapping the corresponding figure.

yapcad.geometry.Arc(c, rp=False, sn=False, e=False, n=False, samplereverse=False)[source]
yapcad.geometry.Figure(*args)[source]
class yapcad.geometry.Geometry(a=False)[source]

Bases: object

generalized computational geometry base class, also acts as a wrapper around yapcad.geom elements.

Using Geometry subclass qinstances can be more effiient than workng with the corresponding yapcad.geom elements, as the Geometry instance uses lazy evaluation and caching to speed repeated evaluations of various properties.

property bbox

return 3D bounding box of figure

property center

return center of figure

property closed
property continuous
property derived
property elem
property geom

return yapcad.geom representation of figure

intersectXY(g, inside=True, params=False)[source]

given two XY-coplanar figures, this figure and g, calculate the intersection of these two figures, and return a list of intersection points, or False if none.

g must be an instance of IntersectGeometry, or a yapcad.geom figure.

If inside == True, only return intersections that are within the 0 <= u <= 1.0 interval for both figures. If params == True, instead of returning a list of points, return two lists corresponding to the sampling parameter value of the intersections corresponding to each figure.

property intersectable
isclosed()[source]

is the figure C0 continuous over the [0,1] interval and is self.sample(0.0) within epsilon of self.sample(1.0)

iscontinuous()[source]

is the figure C0 continuous over the interval [0,1]

isderived()[source]

is this an instance of a derived geometry subclass that computes self.geom from self.elem? Set only in constructors for derived geometry subclasses

isinsideXY(p)[source]

determine if a point is inside a figure. In the case of non-closed figures, such as lines, determine if the point lies within epsilon of one of the lines of the figure.

isintersectable()[source]

is the figure intersectable?

issampleable()[source]

is the figure sampleable?

property length

return length of figure

mirror(plane, keepSign=True)[source]

apply a mirror operation to a figure. Currently, the following values of “plane” are allowed: ‘xz’, ‘yz’, xy’. Generalized arbitrary reflection plane specification will be added in the future.

If keepSign == True (default) the sign of the area will be maintained, meaning that if mirror is applied to a right-handed closed figure (a figure with positive area) the resulting mirrored figure will also have positive area. This is probably what you want, unless you are specifically turning a face into a hole, or vice-versa.

rotate(ang, cent=[0, 0, 0, 1], axis=[0, 0, 1.0, 1])[source]

apply a rotation to a figure

sample(u)[source]

If the figure is sampleable, given a parameter u, return the point on the figure corresponding to the specified sampling parameter.

property sampleable
scale(sx=1.0, sy=False, sz=False, cent=[0, 0, 0, 1])[source]

apply a scaling to a figure

segment(u1, u2, reverse=False)[source]
surface(minang=5.0, minlen=0.5)[source]

Triangulate a closed polyline or geometry list and return a surface.

Parameters:
  • minang – minimum angular resolution (degrees) for sampling arcs

  • minlen – minimum distance between sampled points

Returns:

['surface', vertices, normals, faces]. vertices and normals are aligned lists of yapcad.geom points; faces is a list of index triples describing the triangular mesh.

transform(m)[source]

apply an arbitrary transformation to a figure, as specified by a transformation matrix.

translate(delta)[source]

apply a translation to figure

unsample(p)[source]

Invert the sampling operation: return the parameter corresponding to the closest point on the figure to p as long as the distance is less than epsilon.

property update
yapcad.geometry.Line(p1, p2=False)[source]
yapcad.geometry.Point(x=False, y=False, z=False, w=False)[source]

yapcad.geometry_checks module

Validation helpers for yapCAD geometry.

class yapcad.geometry_checks.CheckResult(ok: 'bool', warnings: 'List[str]')[source]

Bases: object

ok: bool
warnings: List[str]
yapcad.geometry_checks.faces_oriented(surface: Sequence) CheckResult[source]
yapcad.geometry_checks.is_closed_polygon(points: Sequence[Sequence[float]], tol: float = 5e-06) bool[source]

Return True if a polyline is closed within tol.

yapcad.geometry_checks.surface_watertight(surface: Sequence) CheckResult[source]

yapcad.geometry_utils module

Common geometric helpers shared across exporters and validators.

class yapcad.geometry_utils.Triangle(normal: Tuple[float, float, float], v0: Tuple[float, float, float], v1: Tuple[float, float, float], v2: Tuple[float, float, float])[source]

Bases: object

Immutable triangle representation in XYZ space.

normal: Tuple[float, float, float]
v0: Tuple[float, float, float]
v1: Tuple[float, float, float]
v2: Tuple[float, float, float]
yapcad.geometry_utils.orient_triangle(v0: Tuple[float, float, float], v1: Tuple[float, float, float], v2: Tuple[float, float, float], preferred_normal: Tuple[float, float, float]) Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]][source]

Ensure triangle winding aligns with preferred_normal.

yapcad.geometry_utils.to_point(vec: Sequence[float]) Tuple[float, float, float, float][source]

Lift an XYZ tuple into yapCAD homogeneous point form.

yapcad.geometry_utils.to_vec3(point_like: Sequence[float]) Tuple[float, float, float][source]

Return the XYZ components of a yapCAD point/vector as a tuple.

yapcad.geometry_utils.to_vector(vec: Sequence[float]) Tuple[float, float, float, float][source]

Lift an XYZ tuple into yapCAD homogeneous vector form (w=0).

yapcad.geometry_utils.triangle_area(v0: Tuple[float, float, float], v1: Tuple[float, float, float], v2: Tuple[float, float, float]) float[source]

Return the area of a triangle.

yapcad.geometry_utils.triangle_centroid(v0: Tuple[float, float, float], v1: Tuple[float, float, float], v2: Tuple[float, float, float]) Tuple[float, float, float][source]

Return the centroid of a triangle.

yapcad.geometry_utils.triangle_is_degenerate(v0: Tuple[float, float, float], v1: Tuple[float, float, float], v2: Tuple[float, float, float], tol: float = 5e-06) bool[source]

Return True if a triangle collapses under the given tolerance.

yapcad.geometry_utils.triangle_normal(v0: Tuple[float, float, float], v1: Tuple[float, float, float], v2: Tuple[float, float, float]) Tuple[float, float, float] | None[source]

Return the unit normal of a triangle or None if degenerate.

yapcad.geometry_utils.triangles_from_mesh(mesh: Iterable[Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]]]) Iterable[Triangle][source]

Convert mesh_view output into Triangle instances.

yapcad.mesh module

Utilities for working with triangulated views of yapCAD surfaces.

yapcad.mesh.mesh_view(obj: Sequence) Iterator[Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]]][source]

Yield triangles for a surface or solid as (normal, v0, v1, v2).

Normals are unit vectors. Vertices are returned as (x, y, z) tuples. Faces with degenerate geometry (zero area) are skipped silently.

yapcad.metadata module

Metadata helpers for yapCAD geometry objects.

yapcad.metadata.ensure_solid_id(sld: list) str[source]
yapcad.metadata.ensure_surface_id(surface: list) str[source]
yapcad.metadata.get_solid_metadata(sld: list, create: bool = False) Dict[source]
yapcad.metadata.get_surface_metadata(surface: list, create: bool = False) Dict[source]
yapcad.metadata.set_solid_context(sld: list, context: Dict) list[source]
yapcad.metadata.set_solid_metadata(sld: list, metadata: Dict) list[source]
yapcad.metadata.set_surface_metadata(surface: list, metadata: Dict) list[source]
yapcad.metadata.set_surface_origin(surface: list, origin: str) list[source]
yapcad.metadata.set_surface_units(surface: list, units: str) list[source]

yapcad.native_brep module

Native BREP topology graph for yapCAD.

This module provides native (OCC-independent) BREP data structures for representing boundary representations of 3D solids. These structures can be used alongside or instead of OCC-based BREP data.

Topology hierarchy: - BrepVertex: point in 3D space with tolerance - BrepEdge: parametric curve segment bounded by vertices - BrepTrim: oriented edge reference with UV parameterization on a face - BrepLoop: closed sequence of trims forming a boundary - BrepFace: surface bounded by loops - BrepShell: connected set of faces - BrepSolid: collection of shells (outer + inner voids)

Design principle: Vertices are the source of truth for endpoint positions. Edges store curve type and parameters, not absolute endpoint coordinates. This ensures transformations only need to update vertex locations.

Copyright (c) 2025 Richard DeVaul MIT License

exception yapcad.native_brep.ShellClosureError(message, details=None)[source]

Bases: ValueError

Exception raised when shell closure validation fails.

exception yapcad.native_brep.SolidValidationError(message, details=None)[source]

Bases: ValueError

Exception raised when solid validation fails.

class yapcad.native_brep.TopologyGraph[source]

Bases: object

Container for a complete BREP topology graph.

This class manages the relationships between all topology entities (vertices, edges, trims, loops, faces, shells, solids) and provides lookup and traversal operations.

add_edge(edge)[source]

Add an edge to the graph.

add_face(face)[source]

Add a face to the graph.

add_loop(loop)[source]

Add a loop to the graph.

add_shell(shell, validate_closure=True)[source]

Add a shell to the graph.

Parameters:
  • shell (brep_shell) – The shell to add.

  • validate_closure (bool, optional) – If True (default), validate closure when shell.closed is True. If shell.closed is None, auto-detect and set the closure status.

Raises:

ShellClosureError – If shell.closed is True but the shell is not topologically closed.

add_solid(solid, validate=True, tolerance=1e-10)[source]

Add a solid to the graph.

Parameters:
  • solid (brep_solid) – The solid to add.

  • validate (bool, optional) – If True (default), validate the solid (shell closure, no intersections, proper containment hierarchy).

  • tolerance (float, optional) – Geometric tolerance for validation tests.

Raises:

SolidValidationError – If validation is enabled and the solid is invalid.

add_trim(trim)[source]

Add a trim to the graph.

add_vertex(vertex)[source]

Add a vertex to the graph.

compute_shell_closure(shell_id)[source]

Compute whether a shell is topologically closed.

A shell is closed if: 1. Every edge is used by exactly two faces (manifold condition) 2. The Euler characteristic V - E + F = 2 (for simple closed surfaces)

Parameters:

shell_id (str) – ID of the shell to check.

Returns:

(is_closed: bool, details: dict) details contains: - ‘edge_usage’: dict mapping edge_id -> list of face_ids - ‘boundary_edges’: list of edges used by only 1 face - ‘non_manifold_edges’: list of edges used by >2 faces - ‘euler_characteristic’: computed V - E + F - ‘vertex_count’: number of vertices - ‘edge_count’: number of edges - ‘face_count’: number of faces

Return type:

tuple

edge_faces(eid)[source]

Return all faces using an edge.

evaluate_edge(eid)[source]

Evaluate an edge to get its yapCAD curve geometry.

This constructs the actual curve from vertex positions and edge parameters.

face_edges(fid)[source]

Return all edges bounding a face.

get_edge(eid)[source]

Get an edge by ID.

get_face(fid)[source]

Get a face by ID.

get_loop(lid)[source]

Get a loop by ID.

get_shell(shid)[source]

Get a shell by ID.

get_solid(sid)[source]

Get a solid by ID.

get_trim(tid)[source]

Get a trim by ID.

get_vertex(vid)[source]

Get a vertex by ID.

invalidate_shell_octree(shell_id)[source]

Mark a shell’s octree as needing rebuild.

shell_bbox(shell_id)[source]

Compute bounding box for a shell from its face surfaces.

Returns:

(min_point, max_point) bounding box, or None if shell is empty.

Return type:

tuple or None

shell_contains_point(shell_id, p, tolerance=1e-10)[source]

Test if a point is inside a closed shell using ray casting.

Returns True if point is inside, False otherwise.

shell_edge_usage(shell_id)[source]

Compute edge usage counts for a shell.

Returns a dict mapping edge_id -> list of face_ids that use that edge within this shell.

shell_octree(shell_id, rebuild=False)[source]

Get or build an octree for a shell’s tessellated triangles.

The octree is cached in shell metadata for performance.

Returns:

Octree of shell triangles, or None if shell is empty.

Return type:

NTree or None

shell_vertices(shell_id)[source]

Get the set of vertex IDs used by a shell.

shells_bboxes_overlap(shell_id1, shell_id2, tolerance=0.0)[source]

Quick check if two shells’ bounding boxes overlap.

Returns False if boxes don’t overlap (shells definitely don’t intersect). Returns True if boxes overlap (shells might intersect).

shells_intersect(shell_id1, shell_id2, tolerance=1e-10)[source]

Test if two shells intersect using octree acceleration.

Returns True if shells share interior volume or surface intersection.

summary()[source]

Return a summary of the topology graph contents.

tessellate_shell(shell_id, u_divisions=16, v_divisions=16)[source]

Tessellate all faces in a shell into a single surface mesh.

Returns:

yapCAD surface [‘surface’, verts, normals, faces, …] or None.

Return type:

list or None

transform(transform_point_func)[source]

Transform the entire topology graph.

Parameters:
  • transform_point_func (callable) – Function that takes a point and returns the transformed point.

  • transforms (This)

  • locations (- All vertex)

  • centers (- All internal geometry points in edges (arc)

  • etc.)

  • handling (- Face surfaces would need separate)

validate_shell_closure(shell_id)[source]

Validate that a shell is topologically closed.

Parameters:

shell_id (str) – ID of the shell to validate.

Raises:

ShellClosureError – If the shell is not closed, with details about the failure.

Returns:

Closure details if validation passes.

Return type:

dict

validate_solid(solid_id, tolerance=1e-10)[source]

Validate a BREP solid.

Validates: 1. All shells are closed 2. Shells do not intersect each other 3. Void shells are contained within the outer shell

Parameters:
  • solid_id (str) – ID of the solid to validate.

  • tolerance (float) – Geometric tolerance for intersection tests.

Raises:

SolidValidationError – If validation fails, with details about the failure.

Returns:

Validation details if successful.

Return type:

dict

vertex_edges(vid)[source]

Return all edges incident to a vertex.

yapcad.native_brep.arc_edge(start_vertex, end_vertex, *, bulge=None, center=None, orientation=1, **kwargs)[source]

Create an arc edge between two vertices.

Specify either bulge OR center, not both.

Parameters:
  • bulge (float, optional) – Signed arc height factor. Positive = CCW, negative = CW.

  • center (point, optional) – Arc center point.

  • orientation (int, optional) – Arc direction: 1 for CCW, -1 for CW (used with center).

yapcad.native_brep.attach_native_brep_to_solid(yapcad_solid, native_brep_graph)[source]

Attach a native BREP topology graph to a yapCAD solid’s metadata.

Parameters:
  • yapcad_solid (list) – A yapCAD solid (from geom3d).

  • native_brep_graph (TopologyGraph) – The native BREP topology graph to attach.

Notes

This stores the serialized native BREP in the solid’s metadata under the ‘native_brep’ key. The format mirrors the OCC BREP storage pattern used in brep.py.

yapcad.native_brep.brep_edge(curve_type, start_vertex, end_vertex, *, curve_params=None, sense=True, tolerance=5e-06, tags=None)[source]

Create a BREP edge with parametric curve definition.

The edge stores curve type and parameters, NOT absolute endpoint coordinates. Endpoint positions are derived from the referenced vertices.

Parameters:
  • curve_type (str) – Type of curve: ‘line’, ‘arc’, ‘ellipse’, ‘nurbs’.

  • start_vertex (brep_vertex or str) – Start vertex or vertex ID.

  • end_vertex (brep_vertex or str) – End vertex or vertex ID.

  • curve_params (dict, optional) – Type-specific curve parameters (see module docstring).

  • sense (bool, optional) – True if edge direction agrees with curve direction.

  • tolerance (float, optional) – Geometric tolerance.

  • tags (dict, optional) – User metadata.

Returns:

Edge definition: [‘brep_edge’, curve_type, metadata_dict]

Return type:

list

yapcad.native_brep.brep_face(surface, loops, *, sense=True, tags=None)[source]

Create a BREP face.

Parameters:
  • surface (analytic_surface or tessellated surface) – The underlying surface geometry.

  • loops (list) – List of loops bounding the face (first is outer, rest are holes).

  • sense (bool, optional) – True if face normal agrees with surface normal.

  • tags (dict, optional) – User metadata.

Returns:

Face definition: [‘brep_face’, surface, metadata_dict]

Return type:

list

yapcad.native_brep.brep_loop(trims, *, loop_type='outer', tags=None)[source]

Create a BREP loop (closed boundary of a face).

Parameters:
  • trims (list) – Ordered list of trims forming the closed boundary.

  • loop_type (str, optional) – ‘outer’ for outer boundary, ‘inner’ for hole.

  • tags (dict, optional) – User metadata.

Returns:

Loop definition: [‘brep_loop’, trim_refs, metadata_dict]

Return type:

list

yapcad.native_brep.brep_shell(faces, *, shell_type='outer', closed=None, tags=None)[source]

Create a BREP shell.

Parameters:
  • faces (list) – List of faces forming the shell.

  • shell_type (str, optional) – ‘outer’ for outer shell, ‘void’ for inner void.

  • closed (bool or None, optional) – True if shell should be closed (validated when added to TopologyGraph). False if shell is explicitly open. None to auto-detect closure when added to TopologyGraph.

  • tags (dict, optional) – User metadata.

Returns:

Shell definition: [‘brep_shell’, face_refs, metadata_dict]

Return type:

list

Notes

Closure validation is performed when the shell is added to a TopologyGraph. A closed shell satisfies: - Every edge is used by exactly two faces - The Euler characteristic V - E + F = 2 (for simple closed surfaces)

yapcad.native_brep.brep_solid(shells, *, tags=None)[source]

Create a native BREP solid.

Parameters:
  • shells (list) – List of shells (first is outer, rest are voids).

  • tags (dict, optional) – User metadata.

Returns:

Solid definition: [‘brep_solid’, shell_refs, metadata_dict]

Return type:

list

yapcad.native_brep.brep_trim(edge, *, sense=True, uv_curve=None, tags=None)[source]

Create a BREP trim (oriented edge use on a face).

A trim represents the use of an edge on a particular face, with optional UV parameterization for trimmed surface representation.

Parameters:
  • edge (brep_edge or str) – The edge or edge ID being trimmed.

  • sense (bool, optional) – True if trim direction agrees with edge direction.

  • uv_curve (curve, optional) – Curve in the (u, v) parameter space of the face.

  • tags (dict, optional) – User metadata.

Returns:

Trim definition: [‘brep_trim’, edge_ref, metadata_dict]

Return type:

list

yapcad.native_brep.brep_vertex(location, *, tolerance=5e-06, tags=None)[source]

Create a BREP vertex.

Parameters:
  • location (point) – World-space position of the vertex.

  • tolerance (float, optional) – Geometric tolerance for coincidence tests.

  • tags (dict, optional) – User metadata.

Returns:

Vertex definition: [‘brep_vertex’, point, metadata_dict]

Return type:

list

yapcad.native_brep.bspline_edge(start_vertex, end_vertex, control_points, knots, degree, *, weights=None, t_start=None, t_end=None, **kwargs)[source]

Create a B-spline edge between two vertices.

Parameters:
  • start_vertex (brep_vertex) – The endpoints of the edge.

  • end_vertex (brep_vertex) – The endpoints of the edge.

  • control_points (list of points) – Control points for the B-spline.

  • knots (list of float) – Knot vector.

  • degree (int) – Degree of the B-spline.

  • weights (list of float, optional) – Weights for rational B-splines. If None, uniform weights (1.0).

  • t_start (float, optional) – Start parameter. Default is knots[degree].

  • t_end (float, optional) – End parameter. Default is knots[-degree-1].

yapcad.native_brep.circle_edge(start_vertex, end_vertex, center, axis, radius, *, t_start=0.0, t_end=None, **kwargs)[source]

Create a circular arc edge between two vertices.

Parameters:
  • start_vertex (brep_vertex) – The endpoints of the edge.

  • end_vertex (brep_vertex) – The endpoints of the edge.

  • center (point) – Center of the circle.

  • axis (vector) – Normal to the plane of the circle.

  • radius (float) – Radius of the circle.

  • t_start (float, optional) – Start parameter (angle in radians). Default 0.

  • t_end (float, optional) – End parameter (angle in radians). Default computed from endpoints.

yapcad.native_brep.clear_native_brep(yapcad_solid)[source]

Remove native BREP data from a yapCAD solid’s metadata.

Parameters:

yapcad_solid (list) – A yapCAD solid (from geom3d).

Notes

This is useful when the native BREP becomes stale (e.g., after modifications that don’t update the BREP).

yapcad.native_brep.deserialize_topology_graph(data)[source]

Reconstruct a TopologyGraph from serialized data.

Parameters:

data (dict) – Serialized topology graph data.

Returns:

Reconstructed topology graph.

Return type:

TopologyGraph

yapcad.native_brep.edge_curve_params(e)[source]

Return the curve parameters of an edge.

yapcad.native_brep.edge_curve_type(e)[source]

Return the curve type of an edge.

yapcad.native_brep.edge_id(e)[source]

Return the ID of an edge.

yapcad.native_brep.edge_vertices(e)[source]

Return (start_vertex_id, end_vertex_id) for an edge.

yapcad.native_brep.evaluate_edge_curve(edge, start_point, end_point)[source]

Construct a yapCAD curve from edge definition and vertex positions.

Parameters:
  • edge (brep_edge) – The edge definition.

  • start_point (point) – Position of start vertex.

  • end_point (point) – Position of end vertex.

Returns:

A yapCAD curve (line, arc, ellipse, etc.).

Return type:

curve

yapcad.native_brep.face_id(f)[source]

Return the ID of a face.

yapcad.native_brep.face_loops(f)[source]

Return the list of loop IDs in a face.

yapcad.native_brep.face_surface(f)[source]

Return the surface geometry of a face.

yapcad.native_brep.has_native_brep(yapcad_solid)[source]

Check if a yapCAD solid has native BREP data attached.

Parameters:

yapcad_solid (list) – A yapCAD solid (from geom3d).

Returns:

True if native BREP data is present.

Return type:

bool

yapcad.native_brep.is_brep_edge(obj)[source]

Return True if obj is a BREP edge.

yapcad.native_brep.is_brep_face(obj)[source]

Return True if obj is a BREP face.

yapcad.native_brep.is_brep_loop(obj)[source]

Return True if obj is a BREP loop.

yapcad.native_brep.is_brep_shell(obj)[source]

Return True if obj is a BREP shell.

yapcad.native_brep.is_brep_solid_native(obj)[source]

Return True if obj is a native BREP solid.

yapcad.native_brep.is_brep_trim(obj)[source]

Return True if obj is a BREP trim.

yapcad.native_brep.is_brep_vertex(obj)[source]

Return True if obj is a BREP vertex.

yapcad.native_brep.line_edge(start_vertex, end_vertex, **kwargs)[source]

Create a line edge between two vertices.

yapcad.native_brep.loop_id(loop)[source]

Return the ID of a loop.

yapcad.native_brep.loop_trims(loop)[source]

Return the list of trim IDs in a loop.

yapcad.native_brep.loop_type(loop)[source]

Return the loop type (‘outer’ or ‘inner’).

yapcad.native_brep.mirror_native_brep(yapcad_solid, plane)[source]

Apply a mirror transformation to native BREP data in a solid.

Parameters:
  • yapcad_solid (list) – A yapCAD solid with native BREP data.

  • plane (str) – Mirror plane: ‘xy’, ‘xz’, or ‘yz’.

yapcad.native_brep.native_brep_from_solid(yapcad_solid)[source]

Retrieve native BREP topology graph from a yapCAD solid’s metadata.

Parameters:

yapcad_solid (list) – A yapCAD solid (from geom3d).

Returns:

The deserialized topology graph, or None if not present.

Return type:

TopologyGraph or None

yapcad.native_brep.rotate_native_brep(yapcad_solid, ang, center, axis)[source]

Apply a rotation to native BREP data in a solid.

Parameters:
  • yapcad_solid (list) – A yapCAD solid with native BREP data.

  • ang (float) – Rotation angle in degrees.

  • center (point) – Center of rotation.

  • axis (point/vector) – Axis of rotation.

yapcad.native_brep.scale_native_brep(yapcad_solid, factor, center=None)[source]

Apply a uniform scale to native BREP data in a solid.

Parameters:
  • yapcad_solid (list) – A yapCAD solid with native BREP data.

  • factor (float) – Scale factor.

  • center (point, optional) – Center of scaling. Defaults to origin.

yapcad.native_brep.serialize_topology_graph(graph)[source]

Serialize a TopologyGraph to a JSON-serializable dict.

Parameters:

graph (TopologyGraph) – The topology graph to serialize.

Returns:

JSON-serializable dictionary containing all topology entities.

Return type:

dict

yapcad.native_brep.set_shell_closed(s, closed)[source]

Set the closure status of a shell.

yapcad.native_brep.set_vertex_location(v, location)[source]

Set the location of a vertex (for transformations).

yapcad.native_brep.shell_closed(s)[source]

Return the closure status of a shell.

Returns:

True if closed, False if open, None if not yet determined.

Return type:

bool or None

yapcad.native_brep.shell_faces(s)[source]

Return the list of face IDs in a shell.

yapcad.native_brep.shell_id(s)[source]

Return the ID of a shell.

yapcad.native_brep.solid_id(s)[source]

Return the ID of a solid.

yapcad.native_brep.solid_shells(s)[source]

Return the list of shell IDs in a solid.

yapcad.native_brep.transform_edge_params(edge, transform_point_func)[source]

Transform internal geometry points in edge curve parameters.

For edges with internal geometry (like arc centers), this function applies a transformation to those points. Call this after transforming the vertices.

Parameters:
  • edge (brep_edge) – The edge to transform (modified in place).

  • transform_point_func (callable) – Function that takes a point and returns transformed point.

yapcad.native_brep.transform_topology_graph(graph, transform_fn)[source]

Apply a transformation to all geometry in a TopologyGraph.

Parameters:
  • graph (TopologyGraph) – The topology graph to transform (modified in-place).

  • transform_fn (callable) – A function that takes a point and returns a transformed point.

Notes

This transforms: - All vertex locations - Edge curve parameters (centers, control points, axes) - Face surface parameters (origins, centers, normals, axes) - Invalidates cached octrees

yapcad.native_brep.translate_native_brep(yapcad_solid, delta)[source]

Apply a translation to native BREP data in a solid.

Parameters:
  • yapcad_solid (list) – A yapCAD solid with native BREP data.

  • delta (point/list) – Translation vector [dx, dy, dz].

yapcad.native_brep.trim_edge_id(t)[source]

Return the edge ID referenced by a trim.

yapcad.native_brep.trim_id(t)[source]

Return the ID of a trim.

yapcad.native_brep.vertex_id(v)[source]

Return the ID of a vertex.

yapcad.native_brep.vertex_location(v)[source]

Return the location point of a vertex.

yapcad.native_brep.vertices_coincident(v1, v2, tolerance=None)[source]

Return True if two vertices are coincident within tolerance.

yapcad.occ_native_convert module

OCC ↔ Native BREP conversion utilities.

This module provides bidirectional conversion between OCC (Open CASCADE) BREP representations and yapCAD native BREP representations.

The native BREP representation is the primary/canonical form for yapCAD geometry. OCC representations are derived and used for: - STEP file import/export - Boolean operations (when OCC engine is selected) - Complex surface operations

Conversion functions: - occ_surface_to_native: Convert OCC Geom_Surface to native analytic surface - occ_solid_to_native_brep: Convert OCC TopoDS_Solid to native BREP topology - native_surface_to_occ: Convert native analytic surface to OCC Geom_Surface - native_brep_to_occ: Convert native BREP topology to OCC TopoDS_Solid

Copyright (c) 2025 Richard DeVaul MIT License

yapcad.occ_native_convert.native_brep_to_occ(graph, fix_shape=True)[source]

Convert a native BREP TopologyGraph to an OCC TopoDS_Solid.

This function converts a complete native BREP representation back to an OCC solid, which can then be used for boolean operations or export.

Parameters:
  • graph (TopologyGraph) – The native BREP topology graph.

  • fix_shape (bool, optional) – If True, apply shape fixing to ensure a valid solid. Default True.

Returns:

The OCC solid (or shell if conversion to solid fails).

Return type:

TopoDS_Solid or TopoDS_Shell

yapcad.occ_native_convert.native_brep_to_occ_from_solid(yapcad_solid, fix_shape=True)[source]

Convert a yapCAD solid’s native BREP to OCC representation.

Convenience function that extracts the native BREP from a yapCAD solid and converts it to OCC format.

Parameters:
  • yapcad_solid (solid) – A yapCAD solid with native BREP data attached.

  • fix_shape (bool, optional) – If True, apply shape fixing to ensure a valid solid. Default True.

Returns:

The OCC shape, or None if no native BREP is attached.

Return type:

TopoDS_Solid or TopoDS_Shell or None

yapcad.occ_native_convert.native_edge_to_occ(edge, graph)[source]

Convert a native BREP edge to an OCC TopoDS_Edge.

Parameters:
  • edge (brep_edge) – The native edge to convert.

  • graph (TopologyGraph) – The topology graph containing the edge’s vertices.

Returns:

The OCC edge.

Return type:

TopoDS_Edge

yapcad.occ_native_convert.native_face_to_occ(face, graph, edge_cache=None)[source]

Convert a native BREP face to an OCC TopoDS_Face.

Parameters:
  • face (brep_face) – The native face to convert.

  • graph (TopologyGraph) – The topology graph containing the face’s loops.

  • edge_cache (dict, optional) – Cache of edge_id -> TopoDS_Edge for reuse.

Returns:

The OCC face, or None if conversion fails.

Return type:

TopoDS_Face

yapcad.occ_native_convert.native_loop_to_occ_wire(loop, graph, edge_cache=None)[source]

Convert a native BREP loop to an OCC TopoDS_Wire.

Parameters:
  • loop (brep_loop) – The native loop to convert.

  • graph (TopologyGraph) – The topology graph containing the loop’s edges.

  • edge_cache (dict, optional) – Cache of edge_id -> TopoDS_Edge for reuse.

Returns:

The OCC wire.

Return type:

TopoDS_Wire

yapcad.occ_native_convert.native_surface_to_occ(surf)[source]

Convert a native analytic surface to an OCC Geom_Surface.

Parameters:

surf (native surface) – A native analytic surface.

Returns:

The OCC surface, or None if conversion is not supported.

Return type:

Geom_Surface or None

yapcad.occ_native_convert.native_vertex_to_occ(vertex)[source]

Convert a native BREP vertex to an OCC TopoDS_Vertex.

Parameters:

vertex (brep_vertex) – The native vertex to convert.

Returns:

The OCC vertex.

Return type:

TopoDS_Vertex

yapcad.occ_native_convert.occ_available() bool[source]

Return True if OCC is available.

yapcad.occ_native_convert.occ_edge_to_native(edge: Any, vertex_map: dict = None)[source]

Convert an OCC edge to a native BREP edge.

Parameters:
  • edge (TopoDS_Edge) – The OCC edge to convert.

  • vertex_map (dict, optional) – Map from OCC vertex hash to native vertex, for topology consistency.

Returns:

(native_edge, start_vertex, end_vertex)

Return type:

tuple

yapcad.occ_native_convert.occ_solid_to_native_brep(shape: Any, tessellate_fallback: bool = True)[source]

Convert an OCC solid to native BREP representation.

Parameters:
  • shape (TopoDS_Shape) – The OCC shape (solid) to convert.

  • tessellate_fallback (bool) – If True, use tessellation for unsupported surface types.

Returns:

(native_solid, topology_graph) where native_solid is the BREP solid and topology_graph is the TopologyGraph containing all entities.

Return type:

tuple

yapcad.occ_native_convert.occ_surface_to_native(face: Any, tessellate_fallback: bool = True)[source]

Convert an OCC face’s surface to a native analytic surface.

Parameters:
  • face (TopoDS_Face) – The OCC face to convert.

  • tessellate_fallback (bool) – If True, fall back to tessellation for unsupported surface types.

Returns:

A native analytic surface representation, or None if conversion fails.

Return type:

native_surface

yapcad.occ_native_convert.require_occ() None[source]

Raise error if OCC is not available.

yapcad.octtree module

quadtree and octtree representations for yapCAD geometry

class yapcad.octtree.NTree(n=8, geom=None, center=None, mindim=None, maxdepth=None, octree_size=None)[source]

Bases: object

Generalized n-tree representation for yapCAD geometry

addElement(element, tag=None)[source]

add a geometry element to the collection, don’t update the tree – yet

property depth
getElements(bbox)[source]

return a list of geometry elements with bounding boxes that overalp the provided bounding box, or the empty list if none.

property maxdepth
property mindim
updateCenter(center=None)[source]

specify or compute new geometric center (or split poit) for tree, flag tree for rebuilding.

updateTree()[source]

build the tree from the current contents of the self.__geom list

yapcad.octtree.bbox2oct(bbx, refbox, center)[source]

Utility function to take a bounding box representation and assign it to zero or more octants.

box2oct(bbx,refbox,center)

bbx: 3D bounding box to assign refbox: reference 3D bounding box center: center point for purposes of assignment

returns (potentially empty) list of octants, numbered 0 to 7

yapcad.octtree.bbox2quad(bbx, refbox, center)[source]
Utility Function to take a bounding box representation and assign

to zero or more quads

box2quad(bbx,refbox,center)

bbx: 2D bounding box to assign refbox: reference 2D bounding box center: center point for purposes of assignment

returns (potentially empty) list of quadrants, numbered 0 to 3

yapcad.octtree.bboxdim(box)[source]

return length, width, and height of a bounding box

yapcad.octtree.box2boxes(bbox, center, n, type='centersplit', elm=[])[source]

Function to take a bounding box (2d or 3D) and return a quad- or octtree decomposition of the box based on the value of center point, the type of split, and (potentially) the list of bounding boxes to be divvied up.

yapcad.octtree.boxoverlap(bbx1, bbx2, dim3=True)[source]

determine if two bounding boxes overlap

yapcad.octtree.boxoverlap2(bbx1, bbx2, dim3=True)[source]

Determine if two bounding boxes overlap. if dim3==True, treat the bounding boxes as 3D, otherwise treat them as co-planar 2D boxes.

First, check to see if the maximum coordinates of one box are smaller than the minimum coordinates of the other, or vice versa. If so, no overlap is possible; return False

if overlap is possible by test #1, check for the box-in-box special case for each box. If so, return True

Finally, for the 2D case: determine if horizontal lines of box1 intersect with vertical lines of box2, and vice versa. If any intersections found, return True, else return False

For the 3D case, project the boxes into the XY, YZ, and XZ planes, and perform the 2D lines intersection check, as above. Return True if and only if intersections are reported for each projection, otherwise return False

yapcad.octtree.untag(tglist)[source]

remove the (optional) tags that can be associated with elements in a geometry list.

yapcad.poly module

yapcad.poly.Circle(center=[0, 0, 0, 1], radius=1.0)[source]
class yapcad.poly.Polygon(a=None)[source]

Bases: Geometry

Multi-element closed figure derived geometry class

addArc(element)[source]
addLine(element)[source]
addPoint(element)[source]
property geom

return yapcad.geom representation of figure

grow(r)[source]
remove(element)[source]
sample(u)[source]

If the figure is sampleable, given a parameter u, return the point on the figure corresponding to the specified sampling parameter.

setPoint(i, p)[source]
shrink(r)[source]
yapcad.poly.Rect(width, height, center=[0, 0, 0, 1])[source]
yapcad.poly.RoundRect(width, height, chamf, center=[0, 0, 0, 1])[source]
yapcad.poly.cullZeroLength(geom)[source]

yapcad.pyglet_drawable module

class yapcad.pyglet_drawable.GeomObject[source]

Bases: object

class yapcad.pyglet_drawable.Material(**kwargs)[source]

Bases: object

Representation of an OpenGL-style material

property ambient
property desc
property diffuse
property emission
property material
property shininess
property specular
class yapcad.pyglet_drawable.pygletDraw[source]

Bases: Drawable

yapCAD drawable subclass for OpenGL rendering with pyglet

addSurface(s, batch, group, offset, bbx)[source]
property cameradist
display()[source]
draw(x, name=None)[source]
draw_arc(p, r, start, end)[source]
draw_line(p1, p2, entity=None, c1=None, c2=None)[source]
draw_linestrip(points)[source]
draw_point(p)[source]
draw_solid(solid, name=None)[source]

Render a solid, either as part of the secene geometry

draw_surface(points, normals=None, faces=None, name=None)[source]

render a surface, either as part of default scene geometry (if name is not specified) or as a part of a named object.

draw_text(text, location, align='left', attr={'name': 'Times New Roman', 'size': 12})[source]
glSetup()[source]
property magnify
makeBatches()[source]
make_object(name, **kwargs)[source]

Create a new three-dmensional object with specified material properties and 6DOF in world-space that can be animated

property objectdict
register_immediate(func)[source]

register a function for immediate-mode drawing

property rx
property ry
upbb(pp, box, offset=[0, 0, 0, 1])[source]
window()[source]
yapcad.pyglet_drawable.vec(*args)[source]

yapcad.spline module

Spline helpers for yapCAD.

Provides evaluation and sampling routines for spline primitives defined in yapcad.geom, including Catmull-Rom and NURBS curves.

yapcad.spline.evaluate_catmullrom(curve, u: float) list[source]

Evaluate a Catmull-Rom spline at parameter u in [0, 1].

yapcad.spline.evaluate_nurbs(curve, u: float) list[source]

Evaluate a NURBS curve at parameter u in [0, 1].

yapcad.spline.is_catmullrom(curve) bool[source]

Return True if curve is a Catmull-Rom spline definition.

yapcad.spline.is_nurbs(curve) bool[source]

Return True if curve is a NURBS definition.

yapcad.spline.sample_catmullrom(curve, *, segments_per_span: int = 12) List[list][source]

Sample a Catmull-Rom spline into a list of point() values.

yapcad.spline.sample_nurbs(curve, *, samples: int = 64) List[list][source]

Sample a NURBS curve into point() values.

yapcad.threadgen module

Thread profile generator for yapCAD.

class yapcad.threadgen.ThreadProfile(D_nominal: 'float', P_pitch: 'float', thread_angle: 'float' = 60.0, crest_flat_ratio: 'float' = 0.125, root_flat_ratio: 'float' = 0.25, thread_depth_ratio: 'float' = 0.54127, handedness: 'str' = 'right', starts: 'int' = 1, internal: 'bool' = False, taper_ratio: 'float' = 0.0)[source]

Bases: object

D_nominal: float
P_pitch: float
crest_flat_ratio: float = 0.125
handedness: str = 'right'
internal: bool = False
lead() float[source]
root_flat_ratio: float = 0.25
starts: int = 1
taper_ratio: float = 0.0
thread_angle: float = 60.0
thread_depth_ratio: float = 0.54127
yapcad.threadgen.metric_profile(d_nominal_mm: float, pitch_mm: float, *, strts: int = 1, internal: bool = False) ThreadProfile[source]
yapcad.threadgen.sample_thread_profile(profile: ThreadProfile, x_start: float, x_end: float, theta_deg: float, *, samples_per_pitch: int = 1) tuple[List[List[float]], int][source]
yapcad.threadgen.unified_profile(d_nominal_in: float, tpi: float, *, strts: int = 1, internal: bool = False) ThreadProfile[source]

yapcad.triangulator module

Triangulation helpers for yapCAD surfaces.

We delegate to mapbox-earcut (the fast ear clipping implementation used by Mapbox GL) to keep the logic compact and reliable. The helper routine in this file simply normalises yapCAD polygon inputs into the format expected by earcut and converts the resulting indices back into triangle vertex tuples.

yapcad.triangulator.triangulate_polygon(outer: Sequence[Sequence[float]], holes: Iterable[Sequence[Sequence[float]]] | None = None) List[List[Tuple[float, float]]][source]

Return triangles covering outer minus any holes.

outer and each entry in holes is expected to be a sequence of XY-like points. Degenerate loops (fewer than three distinct points) are ignored. The returned triangles are lists of three (x, y) pairs. Downstream code is responsible for lifting the coordinates into 3D and enforcing winding to match the target surface normal.

yapcad.xform module

class yapcad.xform.Matrix(a=False, trans=False)[source]

Bases: object

4x4 transformation matrix class for transforming homogemenous 3D coordinates

get(i, j)[source]
getcol(j)[source]
getrow(i)[source]
mul(x)[source]

Return the product of this matrix and x.

x may be another Matrix, a 4D vector, or a scalar. In each case the appropriate matrix multiplication is performed. If x is none of these types, a ValueError is raised.

set(i, j, x)[source]
setcol(j, x)[source]
setrow(i, x)[source]
yapcad.xform.Rotation(axis, angle, inverse=False)[source]
yapcad.xform.Scale(x, y=False, z=False, inverse=False)[source]
yapcad.xform.Translation(delta, inverse=False)[source]

Module contents