@richardmcquiston01/more-open-scad 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/csg/boolean.d.ts +22 -0
- package/dist/csg/boolean.d.ts.map +1 -0
- package/dist/csg/bsp-tree.d.ts +70 -0
- package/dist/csg/bsp-tree.d.ts.map +1 -0
- package/dist/csg/split-polygon.d.ts +62 -0
- package/dist/csg/split-polygon.d.ts.map +1 -0
- package/dist/geometry/plane.d.ts +31 -0
- package/dist/geometry/plane.d.ts.map +1 -0
- package/dist/geometry/polygon.d.ts +24 -0
- package/dist/geometry/polygon.d.ts.map +1 -0
- package/dist/geometry/solid.d.ts +41 -0
- package/dist/geometry/solid.d.ts.map +1 -0
- package/dist/geometry/triangulate.d.ts +16 -0
- package/dist/geometry/triangulate.d.ts.map +1 -0
- package/dist/geometry/vertex.d.ts +20 -0
- package/dist/geometry/vertex.d.ts.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1016 -0
- package/dist/io/manifold-check.d.ts +20 -0
- package/dist/io/manifold-check.d.ts.map +1 -0
- package/dist/io/stl-ascii.d.ts +14 -0
- package/dist/io/stl-ascii.d.ts.map +1 -0
- package/dist/io/stl-binary.d.ts +13 -0
- package/dist/io/stl-binary.d.ts.map +1 -0
- package/dist/io/triangulate-solid.d.ts +25 -0
- package/dist/io/triangulate-solid.d.ts.map +1 -0
- package/dist/math/epsilon.d.ts +10 -0
- package/dist/math/epsilon.d.ts.map +1 -0
- package/dist/math/mat4.d.ts +75 -0
- package/dist/math/mat4.d.ts.map +1 -0
- package/dist/math/vec3.d.ts +43 -0
- package/dist/math/vec3.d.ts.map +1 -0
- package/dist/primitives/cube.d.ts +21 -0
- package/dist/primitives/cube.d.ts.map +1 -0
- package/dist/primitives/cylinder.d.ts +32 -0
- package/dist/primitives/cylinder.d.ts.map +1 -0
- package/dist/primitives/polyhedron.d.ts +36 -0
- package/dist/primitives/polyhedron.d.ts.map +1 -0
- package/dist/primitives/sphere.d.ts +35 -0
- package/dist/primitives/sphere.d.ts.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Solid } from '../geometry/solid';
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether `solid` is manifold ("watertight"): every directed edge
|
|
4
|
+
* produced by triangulating the solid has exactly one occurrence, and its
|
|
5
|
+
* reverse-directed counterpart also has exactly one occurrence elsewhere
|
|
6
|
+
* in the mesh. This is the standard mesh-processing definition of a
|
|
7
|
+
* closed, consistently-wound 2-manifold surface — it catches both holes
|
|
8
|
+
* (a directed edge with no matching reverse partner) and winding
|
|
9
|
+
* inconsistencies (a directed edge duplicated in the same direction,
|
|
10
|
+
* which leaves its reverse missing).
|
|
11
|
+
*
|
|
12
|
+
* A solid with no triangles is defined as manifold (`true`): there are no
|
|
13
|
+
* edges to violate the watertightness property, so the check is
|
|
14
|
+
* vacuously satisfied rather than an error condition.
|
|
15
|
+
*
|
|
16
|
+
* @param solid - The solid to check.
|
|
17
|
+
* @returns `true` if `solid` is manifold, `false` otherwise.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isManifold(solid: Solid): boolean;
|
|
20
|
+
//# sourceMappingURL=manifold-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifold-check.d.ts","sourceRoot":"","sources":["../../src/io/manifold-check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAqC/C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAsChD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Solid } from '../geometry/solid';
|
|
2
|
+
/**
|
|
3
|
+
* Serializes `solid` to the standard ASCII STL text format.
|
|
4
|
+
*
|
|
5
|
+
* `name` (default `''`) is used as the identifier on both the opening
|
|
6
|
+
* `solid` line and the closing `endsolid` line, per the STL spec — when
|
|
7
|
+
* empty, the header/footer lines are emitted as bare `solid`/`endsolid`
|
|
8
|
+
* with no trailing space. Triangles are sourced from `triangulateSolid` and
|
|
9
|
+
* emitted in order, one `facet normal` / `outer loop` / `vertex` x3 /
|
|
10
|
+
* `endloop` / `endfacet` block per triangle. The result always ends with a
|
|
11
|
+
* trailing newline.
|
|
12
|
+
*/
|
|
13
|
+
export declare function toASCIISTL(solid: Solid, name?: string): string;
|
|
14
|
+
//# sourceMappingURL=stl-ascii.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stl-ascii.d.ts","sourceRoot":"","sources":["../../src/io/stl-ascii.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAkC/C;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,SAAK,GAAG,MAAM,CAiB1D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Solid } from '../geometry/solid';
|
|
2
|
+
/**
|
|
3
|
+
* Serializes `solid` to the binary STL file format.
|
|
4
|
+
*
|
|
5
|
+
* The output is exactly `80 + 4 + 50 * n` bytes, where `n` is the number of
|
|
6
|
+
* triangles `triangulateSolid(solid)` produces: an 80-byte header (arbitrary
|
|
7
|
+
* content, but not starting with `"solid"`), a little-endian `uint32`
|
|
8
|
+
* triangle count, then one 50-byte little-endian record per triangle (a
|
|
9
|
+
* `float32` facet normal, three `float32` vertex positions, and a `uint16`
|
|
10
|
+
* attribute byte count that is always `0`).
|
|
11
|
+
*/
|
|
12
|
+
export declare function toBinarySTL(solid: Solid): Uint8Array;
|
|
13
|
+
//# sourceMappingURL=stl-binary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stl-binary.d.ts","sourceRoot":"","sources":["../../src/io/stl-binary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAoB/C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,CAqCpD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Solid } from '../geometry/solid';
|
|
2
|
+
import type { Vec3 as Vec3Type } from '../math/vec3';
|
|
3
|
+
/**
|
|
4
|
+
* A single triangle in STL's flat, per-facet representation: one normal
|
|
5
|
+
* plus three vertex positions (STL has no notion of per-vertex smooth
|
|
6
|
+
* shading, unlike `Vertex`).
|
|
7
|
+
*/
|
|
8
|
+
export interface StlTriangle {
|
|
9
|
+
readonly normal: Vec3Type;
|
|
10
|
+
readonly vertices: readonly [Vec3Type, Vec3Type, Vec3Type];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Flattens `solid` into the list of triangles STL export needs: every
|
|
14
|
+
* polygon is fan-triangulated (reusing `geometry/triangulate`), and each
|
|
15
|
+
* resulting triangle's normal is (re)computed directly from its own three
|
|
16
|
+
* vertex positions via the right-hand rule — matching STL's convention
|
|
17
|
+
* that vertices are wound counter-clockwise when viewed from the side the
|
|
18
|
+
* normal points toward. Computing the normal per-triangle (rather than
|
|
19
|
+
* reusing the source polygon's plane or a vertex's smooth-shading normal)
|
|
20
|
+
* keeps every emitted triangle self-consistent, even for a polygon whose
|
|
21
|
+
* vertices aren't perfectly planar (e.g. a caller-supplied `polyhedron`
|
|
22
|
+
* face).
|
|
23
|
+
*/
|
|
24
|
+
export declare function triangulateSolid(solid: Solid): StlTriangle[];
|
|
25
|
+
//# sourceMappingURL=triangulate-solid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triangulate-solid.d.ts","sourceRoot":"","sources":["../../src/io/triangulate-solid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,EAAE,CAW5D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default tolerance used for floating-point comparisons throughout the
|
|
3
|
+
* geometry kernel (vector/matrix math, plane classification, CSG splitting).
|
|
4
|
+
*/
|
|
5
|
+
export declare const EPSILON = 1e-9;
|
|
6
|
+
/**
|
|
7
|
+
* Returns whether `a` and `b` are equal within `tolerance`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function almostEqual(a: number, b: number, tolerance?: number): boolean;
|
|
10
|
+
//# sourceMappingURL=epsilon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epsilon.d.ts","sourceRoot":"","sources":["../../src/math/epsilon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,OAAO,OAAO,CAAC;AAE5B;;GAEG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,SAAU,GAClB,OAAO,CAET"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type Vec3 } from './vec3';
|
|
2
|
+
/**
|
|
3
|
+
* The 16 elements of a `Mat4`, stored **column-major** (the same layout
|
|
4
|
+
* used by OpenGL/WebGL/three.js): `e[12]`, `e[13]`, `e[14]` hold the
|
|
5
|
+
* translation. `transformPoint`/`transformDirection` apply the matrix to a
|
|
6
|
+
* column vector, i.e. `v' = M * v`.
|
|
7
|
+
*/
|
|
8
|
+
export type Mat4Elements = readonly [
|
|
9
|
+
number,
|
|
10
|
+
number,
|
|
11
|
+
number,
|
|
12
|
+
number,
|
|
13
|
+
number,
|
|
14
|
+
number,
|
|
15
|
+
number,
|
|
16
|
+
number,
|
|
17
|
+
number,
|
|
18
|
+
number,
|
|
19
|
+
number,
|
|
20
|
+
number,
|
|
21
|
+
number,
|
|
22
|
+
number,
|
|
23
|
+
number,
|
|
24
|
+
number
|
|
25
|
+
];
|
|
26
|
+
/** An immutable 4x4 transformation matrix. */
|
|
27
|
+
export interface Mat4 {
|
|
28
|
+
readonly e: Mat4Elements;
|
|
29
|
+
}
|
|
30
|
+
/** The identity matrix. */
|
|
31
|
+
export declare const IDENTITY: Mat4;
|
|
32
|
+
/** A matrix translating by `v`. */
|
|
33
|
+
export declare function translation(v: Vec3): Mat4;
|
|
34
|
+
/** A matrix scaling each axis by the corresponding component of `v`. */
|
|
35
|
+
export declare function scaling(v: Vec3): Mat4;
|
|
36
|
+
/** A matrix rotating `radians` around the X axis (right-hand rule). */
|
|
37
|
+
export declare function rotationX(radians: number): Mat4;
|
|
38
|
+
/** A matrix rotating `radians` around the Y axis (right-hand rule). */
|
|
39
|
+
export declare function rotationY(radians: number): Mat4;
|
|
40
|
+
/** A matrix rotating `radians` around the Z axis (right-hand rule). */
|
|
41
|
+
export declare function rotationZ(radians: number): Mat4;
|
|
42
|
+
/**
|
|
43
|
+
* A matrix rotating `radians` around `axis` (right-hand rule), via the
|
|
44
|
+
* Rodrigues rotation formula. `axis` need not be pre-normalized.
|
|
45
|
+
*/
|
|
46
|
+
export declare function rotationAxisAngle(axis: Vec3, radians: number): Mat4;
|
|
47
|
+
/**
|
|
48
|
+
* A matrix reflecting points across the plane through the origin with
|
|
49
|
+
* (not necessarily unit) normal `normal` — the Householder reflection
|
|
50
|
+
* `I - 2 * n * nᵀ`. Reflections have determinant `-1`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function reflection(normal: Vec3): Mat4;
|
|
53
|
+
/** The matrix product `a * b` (i.e. "apply `b`, then `a`" to a point). */
|
|
54
|
+
export declare function multiply(a: Mat4, b: Mat4): Mat4;
|
|
55
|
+
/** The transpose of `m`. */
|
|
56
|
+
export declare function transpose(m: Mat4): Mat4;
|
|
57
|
+
/** The determinant of `m`. */
|
|
58
|
+
export declare function determinant(m: Mat4): number;
|
|
59
|
+
/**
|
|
60
|
+
* The inverse of `m`, or `null` if `m` is singular (not invertible within
|
|
61
|
+
* floating-point tolerance).
|
|
62
|
+
*/
|
|
63
|
+
export declare function invert(m: Mat4): Mat4 | null;
|
|
64
|
+
/** Whether `a` and `b` are equal within `tolerance` on every element. */
|
|
65
|
+
export declare function equals(a: Mat4, b: Mat4, tolerance?: number): boolean;
|
|
66
|
+
/** Applies `m` to point `v` (treats `v` as having an implicit `w = 1`). */
|
|
67
|
+
export declare function transformPoint(m: Mat4, v: Vec3): Vec3;
|
|
68
|
+
/**
|
|
69
|
+
* Applies `m` to direction `v` (treats `v` as having an implicit `w = 0`,
|
|
70
|
+
* so translation is ignored). Note: transforming a *normal* correctly under
|
|
71
|
+
* non-uniform scale requires the inverse-transpose of `m`, not `m` itself —
|
|
72
|
+
* callers responsible for normals should pass `transpose(invert(m))`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function transformDirection(m: Mat4, v: Vec3): Vec3;
|
|
75
|
+
//# sourceMappingURL=mat4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mat4.d.ts","sourceRoot":"","sources":["../../src/math/mat4.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAQ,MAAM,QAAQ,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS;IAClC,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACP,CAAC;AAEF,8CAA8C;AAC9C,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC;CAC1B;AAMD,2BAA2B;AAC3B,eAAO,MAAM,QAAQ,EAAE,IAErB,CAAC;AAEH,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAEzC;AAED,wEAAwE;AACxE,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAErC;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CA8BnE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CA2B7C;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CA2D/C;AAED,4BAA4B;AAC5B,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAqCvC;AAwED,8BAA8B;AAC9B,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CA2D3C;AAED,yEAAyE;AACzE,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,SAAU,GAAG,OAAO,CAErE;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAwBrD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAOzD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An immutable 3-component vector (or point).
|
|
3
|
+
*
|
|
4
|
+
* `Vec3` values are treated as immutable throughout the codebase — every
|
|
5
|
+
* function below returns a new `Vec3` rather than mutating its arguments.
|
|
6
|
+
*/
|
|
7
|
+
export interface Vec3 {
|
|
8
|
+
readonly x: number;
|
|
9
|
+
readonly y: number;
|
|
10
|
+
readonly z: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a `Vec3` from its components.
|
|
14
|
+
*/
|
|
15
|
+
export declare function vec3(x: number, y: number, z: number): Vec3;
|
|
16
|
+
/** The zero vector, `(0, 0, 0)`. */
|
|
17
|
+
export declare const ZERO: Vec3;
|
|
18
|
+
/** Component-wise addition: `a + b`. */
|
|
19
|
+
export declare function add(a: Vec3, b: Vec3): Vec3;
|
|
20
|
+
/** Component-wise subtraction: `a - b`. */
|
|
21
|
+
export declare function sub(a: Vec3, b: Vec3): Vec3;
|
|
22
|
+
/** Scales `v` by scalar `s`. */
|
|
23
|
+
export declare function scale(v: Vec3, s: number): Vec3;
|
|
24
|
+
/** Negates `v`, equivalent to `scale(v, -1)`. */
|
|
25
|
+
export declare function negate(v: Vec3): Vec3;
|
|
26
|
+
/** The dot product of `a` and `b`. */
|
|
27
|
+
export declare function dot(a: Vec3, b: Vec3): number;
|
|
28
|
+
/** The cross product `a × b`, following the right-hand rule. */
|
|
29
|
+
export declare function cross(a: Vec3, b: Vec3): Vec3;
|
|
30
|
+
/** The Euclidean length (magnitude) of `v`. */
|
|
31
|
+
export declare function length(v: Vec3): number;
|
|
32
|
+
/**
|
|
33
|
+
* Returns `v` scaled to unit length.
|
|
34
|
+
*
|
|
35
|
+
* The zero vector has no defined direction, so normalizing it returns the
|
|
36
|
+
* zero vector rather than producing `NaN`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function normalize(v: Vec3): Vec3;
|
|
39
|
+
/** Linearly interpolates from `a` to `b` by `t` (0 = `a`, 1 = `b`). */
|
|
40
|
+
export declare function lerp(a: Vec3, b: Vec3, t: number): Vec3;
|
|
41
|
+
/** Whether `a` and `b` are equal within `tolerance` on every component. */
|
|
42
|
+
export declare function equals(a: Vec3, b: Vec3, tolerance?: number): boolean;
|
|
43
|
+
//# sourceMappingURL=vec3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vec3.d.ts","sourceRoot":"","sources":["../../src/math/vec3.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,oCAAoC;AACpC,eAAO,MAAM,IAAI,EAAE,IAAoB,CAAC;AAExC,wCAAwC;AACxC,wBAAgB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAE1C;AAED,2CAA2C;AAC3C,wBAAgB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAE1C;AAED,gCAAgC;AAChC,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,iDAAiD;AACjD,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAEpC;AAED,sCAAsC;AACtC,wBAAgB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,CAE5C;AAED,gEAAgE;AAChE,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAM5C;AAED,+CAA+C;AAC/C,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAEtC;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAMvC;AAED,uEAAuE;AACvE,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,SAAU,GAAG,OAAO,CAMrE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Solid } from '../geometry/solid';
|
|
2
|
+
import type { Vec3 as Vec3Type } from '../math/vec3';
|
|
3
|
+
/** Options controlling how a `cube` is positioned relative to the origin. */
|
|
4
|
+
export interface CubeOptions {
|
|
5
|
+
/**
|
|
6
|
+
* When `true`, the cube is centered on the origin. When `false`
|
|
7
|
+
* (default), one corner sits at the origin and the cube extends in
|
|
8
|
+
* `+x`, `+y`, `+z`.
|
|
9
|
+
*/
|
|
10
|
+
readonly center?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates an axis-aligned box `Solid`, matching OpenSCAD's `cube()`.
|
|
14
|
+
*
|
|
15
|
+
* `size` may be a single number (equal width/depth/height on all three
|
|
16
|
+
* axes) or a `Vec3` giving independent width (x), depth (y), and height
|
|
17
|
+
* (z). By default one corner sits at the origin; pass `{ center: true }`
|
|
18
|
+
* to center the box on the origin instead.
|
|
19
|
+
*/
|
|
20
|
+
export declare function cube(size: number | Vec3Type, options?: CubeOptions): Solid;
|
|
21
|
+
//# sourceMappingURL=cube.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cube.d.ts","sourceRoot":"","sources":["../../src/primitives/cube.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAC;AAErD,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,KAAK,CAgE1E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Solid } from '../geometry/solid';
|
|
2
|
+
/** Options accepted by {@link cylinder}. */
|
|
3
|
+
export interface CylinderOptions {
|
|
4
|
+
/** Radius of both ends. Overridden by `r1`/`r2` when either is given. */
|
|
5
|
+
readonly r?: number;
|
|
6
|
+
/** Bottom (z = 0, or z = -h/2 when centered) radius. Defaults to `r`. */
|
|
7
|
+
readonly r1?: number;
|
|
8
|
+
/** Top (z = h, or z = h/2 when centered) radius. Defaults to `r`. */
|
|
9
|
+
readonly r2?: number;
|
|
10
|
+
/**
|
|
11
|
+
* When `true`, the cylinder is centered on the z-axis (`z` from `-h/2` to
|
|
12
|
+
* `h/2`); otherwise it spans `z` from `0` to `h`. Defaults to `false`.
|
|
13
|
+
*/
|
|
14
|
+
readonly center?: boolean;
|
|
15
|
+
/** Number of segments around the circumference. Defaults to `32`. */
|
|
16
|
+
readonly fn?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a cylinder (or, with unequal radii, a cone/frustum) solid
|
|
20
|
+
* centered on the z-axis, matching OpenSCAD's `cylinder()` semantics.
|
|
21
|
+
*
|
|
22
|
+
* Side faces are always emitted as triangles (2 per segment, or 1 at a
|
|
23
|
+
* degenerate zero-radius end) so every `Polygon` stays exactly planar even
|
|
24
|
+
* when tapered; top/bottom caps are single flat n-gons.
|
|
25
|
+
*
|
|
26
|
+
* @param h - Height along the z-axis. Must be `> 0`.
|
|
27
|
+
* @param options - Radius, taper, centering, and tessellation options.
|
|
28
|
+
* @throws {Error} If `h <= 0`, either radius is negative, both radii are
|
|
29
|
+
* zero, or `fn < 3`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function cylinder(h: number, options?: CylinderOptions): Solid;
|
|
32
|
+
//# sourceMappingURL=cylinder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cylinder.d.ts","sourceRoot":"","sources":["../../src/primitives/cylinder.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB;AAsBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,KAAK,CA+DxE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Solid } from '../geometry/solid';
|
|
2
|
+
import type { Vec3 } from '../math/vec3';
|
|
3
|
+
/**
|
|
4
|
+
* Builds an arbitrary-mesh `Solid` from a flat list of points and a list of
|
|
5
|
+
* faces, each face being a list of indices into `points`. This is the raw
|
|
6
|
+
* escape hatch for geometry that has no dedicated primitive, mirroring
|
|
7
|
+
* OpenSCAD's `polyhedron()`.
|
|
8
|
+
*
|
|
9
|
+
* **Winding convention — read this if porting `.scad` data**: OpenSCAD's own
|
|
10
|
+
* `polyhedron()` conventionally expects each face's indices listed
|
|
11
|
+
* *clockwise* when viewed from outside (a well-known historical OpenSCAD
|
|
12
|
+
* quirk). This library instead uses *counter-clockwise from outside*
|
|
13
|
+
* consistently everywhere, matching `Plane.fromPoints`'s right-hand-rule
|
|
14
|
+
* convention used by every other primitive. So **this function expects each
|
|
15
|
+
* face's indices ordered counter-clockwise when viewed from outside** — the
|
|
16
|
+
* opposite of raw OpenSCAD `.scad` polyhedron() code. Porting OpenSCAD data
|
|
17
|
+
* as-is will silently produce inside-out geometry (inward-facing normals);
|
|
18
|
+
* reverse each face's index order first.
|
|
19
|
+
*
|
|
20
|
+
* Each face is trusted to be planar and convex, same as the standard
|
|
21
|
+
* OpenSCAD polyhedron contract — this function does not validate or repair
|
|
22
|
+
* non-planar/non-convex face data. It does validate structure: every face
|
|
23
|
+
* must have at least 3 indices, and every index must be in bounds for
|
|
24
|
+
* `points`.
|
|
25
|
+
*
|
|
26
|
+
* All vertices within a face share that face's flat-shading normal, derived
|
|
27
|
+
* from the face's own first three listed points via `Plane.fromPoints`.
|
|
28
|
+
*
|
|
29
|
+
* @param points - Flat list of point positions referenced by `faces`.
|
|
30
|
+
* @param faces - List of faces; each face is a list of indices into
|
|
31
|
+
* `points`, ordered counter-clockwise when viewed from outside.
|
|
32
|
+
* @throws {Error} If any face has fewer than 3 indices, or if any index is
|
|
33
|
+
* negative or `>= points.length`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function polyhedron(points: readonly Vec3[], faces: readonly (readonly number[])[]): Solid;
|
|
36
|
+
//# sourceMappingURL=polyhedron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyhedron.d.ts","sourceRoot":"","sources":["../../src/primitives/polyhedron.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,IAAI,EAAE,EACvB,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GACpC,KAAK,CA0BP"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Solid } from '../geometry/solid';
|
|
2
|
+
/** Options accepted by {@link sphere}. */
|
|
3
|
+
export interface SphereOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Controls tessellation density, mirroring OpenSCAD's `$fn`. Used
|
|
6
|
+
* directly as the number of longitude segments (segments running around
|
|
7
|
+
* the sphere, pole to pole to pole). The number of latitude rings
|
|
8
|
+
* (bands stacked from the north pole to the south pole) is derived as
|
|
9
|
+
* `fn / 2`, floored, with a minimum of 2 — matching the common
|
|
10
|
+
* approximation that a sphere's silhouette should have roughly as many
|
|
11
|
+
* horizontal bands as it does vertical wedges around the equator.
|
|
12
|
+
* Defaults to `32`.
|
|
13
|
+
*/
|
|
14
|
+
fn?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Builds a UV-sphere of radius `r`, centered at the origin.
|
|
18
|
+
*
|
|
19
|
+
* Every face is a triangle. A UV-sphere's "band" faces between two
|
|
20
|
+
* latitude rings are natural quads, but four points on a sphere's curved
|
|
21
|
+
* surface are only ever approximately coplanar — this codebase's
|
|
22
|
+
* `Polygon` is required to be *exactly* planar, so each band quad is
|
|
23
|
+
* split into 2 triangles (always exactly planar) instead of being kept
|
|
24
|
+
* as a quad. The polar caps are triangle fans connecting the pole point
|
|
25
|
+
* to the nearest latitude ring, which are triangles already.
|
|
26
|
+
*
|
|
27
|
+
* Vertex normals are the exact smooth-shading normals for a sphere
|
|
28
|
+
* centered at the origin: each vertex's own position, normalized.
|
|
29
|
+
*
|
|
30
|
+
* @param r - Sphere radius.
|
|
31
|
+
* @param options - See {@link SphereOptions}.
|
|
32
|
+
* @throws {Error} If `options.fn` is less than 3.
|
|
33
|
+
*/
|
|
34
|
+
export declare function sphere(r: number, options?: SphereOptions): Solid;
|
|
35
|
+
//# sourceMappingURL=sphere.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sphere.d.ts","sourceRoot":"","sources":["../../src/primitives/sphere.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;OASG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,CAuEhE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@richardmcquiston01/more-open-scad",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Framework agnostic TypeScript based package for generating STL files using commands similar to OpenSCAD.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Richard McQuiston",
|
|
9
|
+
"email": "richard.mcquiston01@gmail.com"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/RichardMcQuiston01/more-open-scad.git"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/RichardMcQuiston01/more-open-scad#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/RichardMcQuiston01/more-open-scad/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"openscad",
|
|
21
|
+
"stl",
|
|
22
|
+
"3d",
|
|
23
|
+
"csg",
|
|
24
|
+
"typescript"
|
|
25
|
+
],
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"CHANGELOG.md"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"lint": "eslint .",
|
|
45
|
+
"lint:file": "eslint",
|
|
46
|
+
"format": "prettier --write .",
|
|
47
|
+
"test": "bun test",
|
|
48
|
+
"test:file": "bun test",
|
|
49
|
+
"build:js": "bun build src/index.ts --outdir dist --target browser --format esm",
|
|
50
|
+
"build:types": "tsc --project tsconfig.build.json --emitDeclarationOnly",
|
|
51
|
+
"build": "bun run build:js && bun run build:types",
|
|
52
|
+
"prepublishOnly": "bun run build"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@eslint/js": "^9.17.0",
|
|
56
|
+
"@types/bun": "^1.1.14",
|
|
57
|
+
"eslint": "^9.17.0",
|
|
58
|
+
"prettier": "3.9.6",
|
|
59
|
+
"typescript": "^5.7.2",
|
|
60
|
+
"typescript-eslint": "^8.18.1"
|
|
61
|
+
}
|
|
62
|
+
}
|