2
Geom_CylindricalSurface,
5
} from "replicad-opencascadejs";
7
import { GCWithScope, localGC, WrappingObj } from "./register";
8
import { getOC } from "./oclib.js";
10
import { Edge, Face } from "./shapes";
11
import { Plane, makeAx2 } from "./geom";
12
import { axis2d, pnt, Point2D, vec, BoundingBox2d, Curve2D } from "./lib2d";
14
export const curvesBoundingBox = (curves: Curve2D[]): BoundingBox2d => {
16
const boundBox = new oc.Bnd_Box2d();
18
curves.forEach((c) => {
19
oc.BndLib_Add2dCurve.Add_3(c.wrapped, 1e-6, boundBox);
22
return new BoundingBox2d(boundBox);
25
export function curvesAsEdgesOnPlane(curves: Curve2D[], plane: Plane) {
26
const [r, gc] = localGC();
27
const ax = r(makeAx2(plane.origin, plane.zDir, plane.xDir));
31
const edges = curves.map((curve) => {
32
const curve3d = oc.GeomLib.To3d(ax, curve.wrapped);
33
return new Edge(new oc.BRepBuilderAPI_MakeEdge_24(curve3d).Edge());
40
export const curvesAsEdgesOnSurface = (
42
geomSurf: Handle_Geom_Surface
44
const [r, gc] = localGC();
47
const modifiedCurves = curves.map((curve) => {
48
const edgeBuilder = r(
49
new oc.BRepBuilderAPI_MakeEdge_30(curve.wrapped, geomSurf)
51
return new Edge(edgeBuilder.Edge());
55
return modifiedCurves;
58
export const transformCurves = (
60
transformation: gp_GTrsf2d | null
64
const modifiedCurves = curves.map((curve) => {
65
if (!transformation) return curve.clone();
66
return new Curve2D(oc.GeomLib.GTransform(curve.wrapped, transformation));
69
return modifiedCurves;
72
export class Transformation2D extends WrappingObj<gp_GTrsf2d> {
73
transformCurves(curves: Curve2D[]) {
74
return transformCurves(curves, this.wrapped);
78
export const stretchTransform2d = (
81
origin: Point2D = [0, 0]
82
): Transformation2D => {
84
const axis = axis2d(origin, direction);
85
const transform = new oc.gp_GTrsf2d_1();
86
transform.SetAffinity(axis, ratio);
89
return new Transformation2D(transform);
92
export const translationTransform2d = (
94
): Transformation2D => {
96
const [r, gc] = localGC();
98
const rotation = new oc.gp_Trsf2d_1();
99
rotation.SetTranslation_1(r(vec(translation)));
101
const transform = new oc.gp_GTrsf2d_2(rotation);
103
return new Transformation2D(transform);
106
export const mirrorTransform2d = (
107
centerOrDirection: Point2D,
108
origin: Point2D = [0, 0],
110
): Transformation2D => {
112
const [r, gc] = localGC();
114
const rotation = new oc.gp_Trsf2d_1();
115
if (mode === "center") {
116
rotation.SetMirror_1(r(pnt(centerOrDirection)));
118
rotation.SetMirror_2(r(axis2d(origin, centerOrDirection)));
121
const transform = new oc.gp_GTrsf2d_2(rotation);
123
return new Transformation2D(transform);
126
export const rotateTransform2d = (
128
center: Point2D = [0, 0]
129
): Transformation2D => {
131
const [r, gc] = localGC();
133
const rotation = new oc.gp_Trsf2d_1();
134
rotation.SetRotation(r(pnt(center)), angle);
136
const transform = new oc.gp_GTrsf2d_2(rotation);
138
return new Transformation2D(transform);
141
export const scaleTransform2d = (
143
center: Point2D = [0, 0]
144
): Transformation2D => {
146
const [r, gc] = localGC();
148
const scaling = new oc.gp_Trsf2d_1();
149
scaling.SetScale(r(pnt(center)), scaleFactor);
151
const transform = new oc.gp_GTrsf2d_2(scaling);
153
return new Transformation2D(transform);
156
export function faceRadius(face: Face): null | number {
158
const [r, gc] = localGC();
159
const geomSurf = r(oc.BRep_Tool.Surface_2(face.wrapped));
161
if (face.geomType !== "CYLINDRE") return null;
163
const cylinder = r((geomSurf.get() as Geom_CylindricalSurface).Cylinder());
164
const radius = cylinder.Radius();
169
export type ScaleMode = "original" | "bounds" | "native";
171
export function curvesAsEdgesOnFace(
174
scale: ScaleMode = "original"
176
const [r, gc] = localGC();
179
let geomSurf = r(oc.BRep_Tool.Surface_2(face.wrapped));
181
const bounds = face.UVBounds;
183
let transformation: null | gp_GTrsf2d = null;
184
const uAxis = r(axis2d([0, 0], [0, 1]));
185
const vAxis = r(axis2d([0, 0], [1, 0]));
187
if (scale === "original" && face.geomType !== "PLANE") {
188
if (face.geomType !== "CYLINDRE")
190
"Only planar and cylidrical faces can be unwrapped for sketching"
193
const cylinder = r((geomSurf.get() as Geom_CylindricalSurface).Cylinder());
194
if (!cylinder.Direct()) {
195
geomSurf = geomSurf.get().UReversed();
197
const radius = cylinder.Radius();
198
const affinity = stretchTransform2d(1 / radius, [0, 1]);
199
transformation = affinity.wrapped;
202
if (scale === "bounds") {
203
transformation = r(new oc.gp_GTrsf2d_1());
204
transformation.SetAffinity(uAxis, bounds.uMax - bounds.uMin);
206
if (bounds.uMin !== 0) {
207
const translation = r(new oc.gp_GTrsf2d_1());
208
translation.SetTranslationPart(new oc.gp_XY_2(0, -bounds.uMin));
209
transformation.Multiply(translation);
212
const vTransformation = r(new oc.gp_GTrsf2d_1());
213
vTransformation.SetAffinity(vAxis, bounds.vMax - bounds.vMin);
214
transformation.Multiply(vTransformation);
216
if (bounds.vMin !== 0) {
217
const translation = r(new oc.gp_GTrsf2d_1());
218
translation.SetTranslationPart(r(new oc.gp_XY_2(0, -bounds.vMin)));
219
transformation.Multiply(translation);
223
const modifiedCurves = transformCurves(curves, transformation);
224
const edges = curvesAsEdgesOnSurface(modifiedCurves, geomSurf);
230
export function edgeToCurve(e: Edge, face: Face): Curve2D {
232
const r = GCWithScope();
234
const adaptor = r(new oc.BRepAdaptor_Curve2d_2(e.wrapped, face.wrapped));
236
const trimmed = new oc.Geom2d_TrimmedCurve(
238
adaptor.FirstParameter(),
239
adaptor.LastParameter(),
244
if (e.orientation === "backward") {
248
return new Curve2D(new oc.Handle_Geom2d_Curve_2(trimmed));