From 84d814116508b4c9314b5110319fb9643be7fc93 Mon Sep 17 00:00:00 2001 From: Val Erastov Date: Wed, 12 Apr 2017 16:56:22 -0700 Subject: [PATCH] nurbs surface --- package.json | 3 ++- web/app/3d/craft/brep/cut-extrude.js | 20 +++++++++++--- web/app/3d/craft/sketch/sketch-model.js | 35 +++++++++++++++++++++++++ web/app/brep/brep-builder.js | 7 +++++ web/app/brep/geom/curve.js | 1 + web/app/brep/geom/impl/line.js | 3 +++ web/app/brep/geom/impl/nurbs.js | 22 ++++++++++++++++ web/app/brep/geom/impl/uv.js | 7 +++++ web/app/math/l3space.js | 8 ++++++ 9 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 web/app/brep/geom/impl/nurbs.js create mode 100644 web/app/brep/geom/impl/uv.js diff --git a/package.json b/package.json index 1b26352a..73489555 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "json-loader": "0.5.4 ", "jquery": "2.1.0", "less": "2.7.1", - "libtess": "1.2.2" + "libtess": "1.2.2", + "verb-nurbs": "2.0.2" } } diff --git a/web/app/3d/craft/brep/cut-extrude.js b/web/app/3d/craft/brep/cut-extrude.js index 745578a8..85bb043b 100644 --- a/web/app/3d/craft/brep/cut-extrude.js +++ b/web/app/3d/craft/brep/cut-extrude.js @@ -6,6 +6,7 @@ import {BREPValidator} from '../../../brep/brep-validator' import * as stitching from '../../../brep/stitching' import {subtract, union} from '../../../brep/operations/boolean' import {Loop} from '../../../brep/topo/loop' +import {Line} from '../../../brep/geom/impl/line' import {Shell} from '../../../brep/topo/shell' import {CompositeCurve} from '../../../brep/geom/curve' import {ReadSketchContoursFromFace} from '../sketch/sketch-reader' @@ -103,17 +104,28 @@ export function getEncloseDetails(params, contours, sketchSurface, invert, force const lidPath = new CompositeCurve(); let lidPoints = basePath.points; - if (!math.equal(params.prism, 1)) { + var applyPrism = !math.equal(params.prism, 1); + if (applyPrism) { const _3D = sketchSurface.get3DTransformation(); const _2D = _3D.invert(); - lidPoints = math.polygonOffset(lidPoints.map(p => _2D.apply(p)) , params.prism).map(p => _3D._apply(p)); + lidPoints = math.polygonOffset(lidPoints.map(p => _2D.apply(p)) , params.prism).map(p => _3D._apply(p)); } - + lidPoints = lidPoints.map(p => p.plus(target)); for (let i = 0; i < basePath.points.length; ++i) { const curve = basePath.curves[i]; const point = lidPoints[i]; const group = basePath.groups[i]; - lidPath.add(curve.translate(target), point.plus(target), group); + let lidCurve; + if (curve.isLine) { + //TODO: breaks test_TR_OUT_TR_INNER + lidCurve = Line.fromSegment(point, lidPoints[(i + 1) % lidPoints.length]); + } else { + lidCurve = curve.translate(target); + if (applyPrism) { + lidCurve = lidCurve.offset(params.prism); + } + } + lidPath.add(lidCurve, point, group); } const lidSurface = baseSurface.translate(target).invert(); diff --git a/web/app/3d/craft/sketch/sketch-model.js b/web/app/3d/craft/sketch/sketch-model.js index 93349174..976b4823 100644 --- a/web/app/3d/craft/sketch/sketch-model.js +++ b/web/app/3d/craft/sketch/sketch-model.js @@ -1,9 +1,12 @@ import {CompositeCurve} from '../../../brep/geom/curve' import {ApproxCurve} from '../../../brep/geom/impl/approx' +import {NurbsCurve} from '../../../brep/geom/impl/nurbs' import {Point} from '../../../brep/geom/point' import {Line} from '../../../brep/geom/impl/Line' import {LUT} from '../../../math/bezier-cubic' import {isCCW} from '../../../math/math' +import {AXIS} from '../../../math/l3space' +import verb from 'verb-nurbs' const RESOLUTION = 20; @@ -28,6 +31,19 @@ class SketchPrimitive { isCurve() { return this.constructor.name != 'Segment'; } + + toNurbs(plane, _3dtr) { + const obj = this.inverted ? this.toInverted() : this; + return obj.toNurbsImpl(plane, _3dtr); + } + + toNurbsImpl(plane, _3dtr) { + throw 'not implemented' + } + + toInverted() { + throw 'not implemented' + } } export class Segment extends SketchPrimitive { @@ -76,6 +92,18 @@ export class Arc extends SketchPrimitive { points.push(bo); return points; } + + toInverted() { + return new Arc(-1, this.b, this.a, this.c); + } + + toNurbsImpl(plane, _3dtr) { + const basis = plane.basis(); + const startAngle = Math.atan2(this.a.y - this.c.y, this.a.x - this.c.x); + const endAngle = Math.atan2(this.b.y - this.c.y, this.b.x - this.c.x); + const arcCurve = new verb.geom.Arc(_3dtr(this.c).toArray(), basis[0].toArray(), basis[1].toArray(), this.r, startAngle, endAngle); + return new NurbsCurve(arcCurve); + } } export class BezierCurve extends SketchPrimitive { @@ -180,6 +208,10 @@ export class Ellipse extends SketchPrimitive { const USE_APPROX_FOR = new Set(); //USE_APPROX_FOR.add('Arc'); +const USE_NURBS_FOR = new Set(); +USE_NURBS_FOR.add('Arc'); + + export class Contour { constructor() { @@ -221,6 +253,9 @@ export class Contour { if (!forceApproximation && USE_APPROX_FOR.has(segment.constructor.name)) { cc.add(new ApproxCurve(approximation, segment), prev, segment); prev = approximation[n - 1]; + } else if (!forceApproximation && USE_NURBS_FOR.has(segment.constructor.name)) { + cc.add(segment.toNurbs(surface, tr), prev, segment); + prev = approximation[n - 1]; } else { for (let i = 1; i < n; ++i) { const curr = approximation[i]; diff --git a/web/app/brep/brep-builder.js b/web/app/brep/brep-builder.js index bb318644..07dc006a 100644 --- a/web/app/brep/brep-builder.js +++ b/web/app/brep/brep-builder.js @@ -5,12 +5,14 @@ import {Face} from './topo/face' import {HalfEdge, Edge} from './topo/edge' import {Line} from './geom/impl/line' import {ApproxCurve, ApproxSurface} from './geom/impl/approx' +import {NurbsSurface} from './geom/impl/nurbs' import {Plane} from './geom/impl/plane' import {Point} from './geom/point' import {BasisForPlane, Matrix3} from '../math/l3space' import {CompositeCurve} from './geom/curve' import * as cad_utils from '../3d/cad-utils' import * as math from '../math/math' +import verb from 'verb-nurbs' function isCCW(points, normal) { const tr2d = new Matrix3().setBasis(BasisForPlane(normal)).invert(); @@ -214,6 +216,11 @@ export function createFaceFromTwoEdges(e1, e2) { if (bothClassOf(e1.edge.curve, e2.edge.curve, 'Line')) { const normal = cad_utils.normalOfCCWSeq(loop.halfEdges.map(e => e.vertexA.point)); surface = createPlaneForLoop(normal, loop); + } else if (bothClassOf(e1.edge.curve, e2.edge.curve, 'NurbsCurve')) { + + const verbSurface = verb.geom.NurbsSurface.byLoftingCurves([e1.edge.curve.verb, e2.edge.curve.verb], 2); + surface = new NurbsSurface(verbSurface); + } else if (bothClassOf(e1.edge.curve, e2.edge.curve, 'ApproxCurve')) { const chunk1 = e1.edge.curve.getChunk(e1.vertexA.point, e1.vertexB.point); diff --git a/web/app/brep/geom/curve.js b/web/app/brep/geom/curve.js index 84c5c8a1..80167e26 100644 --- a/web/app/brep/geom/curve.js +++ b/web/app/brep/geom/curve.js @@ -2,6 +2,7 @@ export class Curve { constructor() { + this.isLine = false; } intersectCurve(curve) { diff --git a/web/app/brep/geom/impl/line.js b/web/app/brep/geom/impl/line.js index 51815390..a722a4cc 100644 --- a/web/app/brep/geom/impl/line.js +++ b/web/app/brep/geom/impl/line.js @@ -4,6 +4,7 @@ export class Line extends Curve { constructor(p0, v) { super(); + this.isLine = true; this.p0 = p0; this.v = v; this._pointsCache = new Map(); @@ -51,6 +52,8 @@ export class Line extends Curve { approximate(resolution, from, to, path) { } + + offset() {}; } Line.fromTwoPlanesIntersection = function(plane1, plane2) { diff --git a/web/app/brep/geom/impl/nurbs.js b/web/app/brep/geom/impl/nurbs.js new file mode 100644 index 00000000..18e7701b --- /dev/null +++ b/web/app/brep/geom/impl/nurbs.js @@ -0,0 +1,22 @@ +import verb from 'verb-nurbs' +import {Matrix3} from '../../../math/l3space' + +export class NurbsCurve { + + constructor(verbCurve) { + this.verb = verbCurve; + } + + translate(vector) { + const tr = new Matrix3().translate(vector.x, vector.y, vector.z).toArray(); + return new NurbsCurve(this.verb.transform(tr)); + } +} + +export class NurbsSurface { + + constructor(verbSurface) { + this.verb = verbSurface; + } + +} \ No newline at end of file diff --git a/web/app/brep/geom/impl/uv.js b/web/app/brep/geom/impl/uv.js new file mode 100644 index 00000000..9123a947 --- /dev/null +++ b/web/app/brep/geom/impl/uv.js @@ -0,0 +1,7 @@ +export class UV { + + constructor(u, v) { + this.u = u; + this.v = v; + } +} \ No newline at end of file diff --git a/web/app/math/l3space.js b/web/app/math/l3space.js index 7faa03ca..47e496a1 100644 --- a/web/app/math/l3space.js +++ b/web/app/math/l3space.js @@ -73,6 +73,14 @@ Matrix3.prototype.setMatrix = function(m) { return this; }; +Matrix3.prototype.toArray = function() { + return [ + [this.mxx, this.mxy, this.mxz, this.tx], + [this.myx, this.myy, this.myz, this.ty], + [this.mzx, this.mzy, this.mzz, this.tz] + ]; +}; + Matrix3.prototype.invert = function() { var det =