diff --git a/web/app/brep/brep-builder.js b/web/app/brep/brep-builder.js index b8de05dd..deb07bf6 100644 --- a/web/app/brep/brep-builder.js +++ b/web/app/brep/brep-builder.js @@ -102,7 +102,7 @@ export function createBoundingSurface(points, plane) { return createBoundingSurfaceFrom2DPoints(points2d, plane); } -export function createBoundingSurfaceFrom2DPoints(points2d, plane, minWidth, minHeight, offset = 0, ) { +export function createBoundingSurfaceFrom2DPoints(points2d, plane, minWidth, minHeight, offset = 0) { let bBox = new BBox(); points2d.forEach(p => bBox.checkPoint(p)); diff --git a/web/app/brep/brep-primitives.js b/web/app/brep/brep-primitives.js index a00c7163..37aabcb6 100644 --- a/web/app/brep/brep-primitives.js +++ b/web/app/brep/brep-primitives.js @@ -3,6 +3,7 @@ import {Plane} from './geom/impl/plane' import {createPrism, enclose} from './brep-enclose' import {AXIS, Matrix3} from '../math/l3space' import {Circle} from '../cad/sketch/sketchModel' +import CSys from '../math/csys'; export function box(w, h, d, tr) { const wh = w * 0.5; @@ -22,7 +23,11 @@ export function box(w, h, d, tr) { export function cylinder(r, h, tr) { tr = tr || IDENTITY; - let circle1 = new Circle(-1, new Point(0,0,0), r).toNurbs( new Plane(tr.apply(AXIS.Z), h)); + let normal = tr.apply(AXIS.Z); + let plane = new Plane(normal, h); + let csys = CSys.fromNormalAndDir(normal.multiply(h), normal, plane.basis()[0]); + + let circle1 = new Circle(-1, new Point(0,0,0), r).toNurbs(csys); let circle2 = circle1.translate(tr.apply(new Point(0,0,-h))); return enclose([circle1], [circle2]); } diff --git a/web/app/brep/geom/surfaces/nurbsSurface.js b/web/app/brep/geom/surfaces/nurbsSurface.js index d77c23a1..00b652a5 100644 --- a/web/app/brep/geom/surfaces/nurbsSurface.js +++ b/web/app/brep/geom/surfaces/nurbsSurface.js @@ -40,7 +40,7 @@ export default class NurbsSurface { } eval(u, v, order) { - this.verb.derivatives(u, v, order); + return this.verb.derivatives(u, v, order); } normal(u, v) { diff --git a/web/app/cad/craft/cutExtrude/cutExtrude.js b/web/app/cad/craft/cutExtrude/cutExtrude.js index 16bab5c6..a4f1e400 100644 --- a/web/app/cad/craft/cutExtrude/cutExtrude.js +++ b/web/app/cad/craft/cutExtrude/cutExtrude.js @@ -19,32 +19,26 @@ export function doOperation(params, {cadRegistry, sketcher}, cut) { let sketch = sketcher.readSketch(face.id); if (!sketch) throw 'illegal state'; - let plane = face.surface.tangentPlane(0, 0); - const details = getEncloseDetails(params, sketch.fetchContours(), plane, !cut, false); + const details = getEncloseDetails(params, sketch.fetchContours(), face.csys, face.surface, !cut, false); const operand = combineShells(details.map(d => enclose(d.basePath, d.lidPath, d.baseSurface, d.lidSurface))); return BooleanOperation(face, solid, operand, cut ? 'subtract' : 'union'); } -export function getEncloseDetails(params, contours, sketchSurface, invert) { +export function getEncloseDetails(params, contours, csys, sketchSurface, invert) { let value = params.value; if (value < 0) { value = Math.abs(value); invert = !invert; } - const baseSurface = invert ? sketchSurface.invert() : sketchSurface; - - let target; + const targetDir = invert ? csys.z : csys.z.negate(); - let baseSurfaceNormal = baseSurface.normal; - - const targetDir = baseSurfaceNormal.negate(); + let target; if (params.rotation !== 0) { - const basis = sketchSurface.basis(); - target = Matrix3.rotateMatrix(params.rotation * Math.PI / 180, basis[0], ORIGIN).apply(targetDir); + target = Matrix3.rotateMatrix(params.rotation * Math.PI / 180, csys.x, ORIGIN).apply(targetDir); if (params.angle !== 0) { - target = Matrix3.rotateMatrix(params.angle * Math.PI / 180, basis[2], ORIGIN)._apply(target); + target = Matrix3.rotateMatrix(params.angle * Math.PI / 180, csys.z, ORIGIN)._apply(target); } target._multiply(value); } else { @@ -54,7 +48,7 @@ export function getEncloseDetails(params, contours, sketchSurface, invert) { let details = []; for (let contour of contours) { if (invert) contour.reverse(); - const basePath = contour.transferOnSurface(sketchSurface); + const basePath = contour.transferInCoordinateSystem(csys); if (invert) contour.reverse(); const lidPath = []; @@ -68,6 +62,7 @@ export function getEncloseDetails(params, contours, sketchSurface, invert) { lidPath.push(lidCurve); } + const baseSurface = sketchSurface.tangentPlane(0, 0); const lidSurface = baseSurface.translate(target).invert(); details.push({basePath, lidPath, baseSurface, lidSurface}); } diff --git a/web/app/cad/craft/cutExtrude/previewer.js b/web/app/cad/craft/cutExtrude/previewer.js index dc10222c..29b41cfa 100644 --- a/web/app/cad/craft/cutExtrude/previewer.js +++ b/web/app/cad/craft/cutExtrude/previewer.js @@ -14,7 +14,7 @@ export function createPreviewGeomProvider(inversed) { if (!face) return null; let sketch = face.sketch.fetchContours(); - const encloseDetails = getEncloseDetails(params, sketch, face.surface.tangentPlane(0, 0), !inversed); + const encloseDetails = getEncloseDetails(params, sketch, face.csys, face.surface, !inversed); const triangles = []; for (let {basePath, lidPath, baseSurface, lidSurface} of encloseDetails) { diff --git a/web/app/cad/craft/primitives/plane/PlaneWizard.jsx b/web/app/cad/craft/primitives/plane/PlaneWizard.jsx new file mode 100644 index 00000000..be08e525 --- /dev/null +++ b/web/app/cad/craft/primitives/plane/PlaneWizard.jsx @@ -0,0 +1,12 @@ +import React from 'react'; +import {Group} from '../../wizard/components/form/Form'; +import {NumberField, RadioButtonsField, ReadOnlyValueField} from '../../wizard/components/form/Fields'; +import SingleEntity from '../../wizard/components/form/SingleEntity'; +import {RadioButton} from 'ui/components/controls/RadioButtons'; + + +export default function PlaneWizard() { + return + + ; +} \ No newline at end of file diff --git a/web/app/cad/craft/primitives/plane/planeOpSchema.js b/web/app/cad/craft/primitives/plane/planeOpSchema.js new file mode 100644 index 00000000..1ea295c3 --- /dev/null +++ b/web/app/cad/craft/primitives/plane/planeOpSchema.js @@ -0,0 +1,6 @@ +export default { + datum: { + type: 'datum', + defaultValue: {type: 'selection'} + } +} \ No newline at end of file diff --git a/web/app/cad/craft/primitives/plane/planeOperation.js b/web/app/cad/craft/primitives/plane/planeOperation.js new file mode 100644 index 00000000..fd76c043 --- /dev/null +++ b/web/app/cad/craft/primitives/plane/planeOperation.js @@ -0,0 +1,52 @@ +import {createMeshGeometry} from 'scene/geoms'; +import {Plane} from '../../../../brep/geom/impl/plane'; +import Vector from 'math/vector'; +import PlaneWizard from './PlaneWizard'; +import {MOpenFaceShell} from '../../../model/mopenFace'; +import schema from './planeOpSchema'; +import {CSysPlaneSurfacePrototype} from '../../../model/surfacePrototype'; + +const WIDTH = 750; +const HEIGHT = 750; + +function createPlane(params, services) { + let mDatum = services.cadRegistry.findDatum(params.datum); + + return { + outdated: [mDatum], + created: [new MOpenFaceShell(new CSysPlaneSurfacePrototype(mDatum.csys), mDatum.csys)] + } +} + +function previewGeomProvider(params, services) { + let mDatum = services.cadRegistry.findDatum(params.datum); + + if (!mDatum) { + return null; + } + + let tr = mDatum.csys.outTransformation; + + const a = tr._apply(new Vector(0, 0, 0)); + const b = tr._apply(new Vector(WIDTH, 0, 0)); + const c = tr._apply(new Vector(WIDTH, HEIGHT, 0)); + const d = tr._apply(new Vector(0, HEIGHT, 0)); + + let trs = [[a, b, c], [a, c, d]]; + return createMeshGeometry(trs); +} + +export default { + id: 'PLANE_FROM_DATUM', + label: 'Plane', + icon: 'img/cad/plane', + info: 'creates new object plane off of datum', + paramsInfo: ({datum}) => `(${datum})`, + previewGeomProvider, + run: createPlane, + form: PlaneWizard, + schema +}; + + + diff --git a/web/app/cad/craft/primitives/PlaneWizard.jsx b/web/app/cad/craft/primitives/simplePlane/SimplePlaneWizard.jsx similarity index 66% rename from web/app/cad/craft/primitives/PlaneWizard.jsx rename to web/app/cad/craft/primitives/simplePlane/SimplePlaneWizard.jsx index 6ef03dd3..94ad4ca4 100644 --- a/web/app/cad/craft/primitives/PlaneWizard.jsx +++ b/web/app/cad/craft/primitives/simplePlane/SimplePlaneWizard.jsx @@ -1,7 +1,7 @@ import React from 'react'; -import {Group} from '../wizard/components/form/Form'; -import {NumberField, RadioButtonsField} from '../wizard/components/form/Fields'; -import SingleEntity from '../wizard/components/form/SingleEntity'; +import {Group} from '../../wizard/components/form/Form'; +import {NumberField, RadioButtonsField} from '../../wizard/components/form/Fields'; +import SingleEntity from '../../wizard/components/form/SingleEntity'; import {RadioButton} from 'ui/components/controls/RadioButtons'; diff --git a/web/app/cad/craft/primitives/planeOpSchema.js b/web/app/cad/craft/primitives/simplePlane/simplePlaneOpSchema.js similarity index 100% rename from web/app/cad/craft/primitives/planeOpSchema.js rename to web/app/cad/craft/primitives/simplePlane/simplePlaneOpSchema.js diff --git a/web/app/cad/craft/primitives/planeOperation.js b/web/app/cad/craft/primitives/simplePlane/simplePlaneOperation.js similarity index 80% rename from web/app/cad/craft/primitives/planeOperation.js rename to web/app/cad/craft/primitives/simplePlane/simplePlaneOperation.js index 50c371e3..52ada59d 100644 --- a/web/app/cad/craft/primitives/planeOperation.js +++ b/web/app/cad/craft/primitives/simplePlane/simplePlaneOperation.js @@ -1,11 +1,11 @@ import {createMeshGeometry} from 'scene/geoms'; -import {STANDARD_BASES} from '../../../math/l3space'; -import {Plane} from '../../../brep/geom/impl/plane'; +import {STANDARD_BASES} from '../../../../math/l3space'; +import {Plane} from '../../../../brep/geom/impl/plane'; import Vector from 'math/vector'; -import PlaneWizard from './PlaneWizard'; -import {MOpenFaceShell} from '../../model/mopenFace'; -import schema from './planeOpSchema'; -import {PlaneSurfacePrototype} from '../../model/surfacePrototype'; +import PlaneWizard from './SimplePlaneWizard'; +import {MOpenFaceShell} from '../../../model/mopenFace'; +import schema from './simplePlaneOpSchema'; +import {PlaneSurfacePrototype} from '../../../model/surfacePrototype'; function paramsToPlane({orientation, parallelTo, depth}, cadRegistry) { let face = null; diff --git a/web/app/cad/legacy/brep/revolve.js b/web/app/cad/legacy/brep/revolve.js index 7d53dffb..43c4415f 100644 --- a/web/app/cad/legacy/brep/revolve.js +++ b/web/app/cad/legacy/brep/revolve.js @@ -9,27 +9,27 @@ export function Revolve(app, params) { const surface = face.surface; const sketch = ReadSketchFromFace(app, face); - const pivot = evalPivot(params.pivot, sketch, surface); + const pivot = evalPivot(params.pivot, sketch, face.csys); const shells = []; const contours = sketch.fetchContours(); for (let contour of contours) { - const basePath = contour.transferOnSurface(surface); + const basePath = contour.transferInCoordinateSystem(face.csys); const shell = revolve(basePath, surface, pivot.p0, pivot.v, params.angle); shells.push(shell); } - const operand = combineShells(shells) + const operand = combineShells(shells); return BooleanOperation(face, solid, operand, 'union'); } -export function evalPivot(pivot, sketch, surface) { +export function evalPivot(pivot, sketch, csys) { const segment = sketch.findById(pivot); if (segment == null) { return null; } - const tr = surface.get3DTransformation(); + const tr = csys.outTransformation; const p0 = tr.apply(segment.a); - const v = tr.apply(segment.b).minus(p0)._normalize() + const v = tr.apply(segment.b).minus(p0)._normalize(); return {p0, v} } diff --git a/web/app/cad/model/mface.js b/web/app/cad/model/mface.js index 49f52788..69a3ce79 100644 --- a/web/app/cad/model/mface.js +++ b/web/app/cad/model/mface.js @@ -10,40 +10,63 @@ export class MFace extends MObject { static TYPE = 'face'; - constructor(id, shell, surface) { + constructor(id, shell, surface, csys) { super(id); this.id = id; this.shell = shell; this.surface = surface; this.sketchObjects = []; + this._csys = csys } normal() { - return this.surface.normalInMiddle(); + return this.csys.z; } depth() { - return this.surface.tangentPlaneInMiddle().w; + this.evalCSys(); + return this.w; } - calcBasis() { - return BasisForPlane(this.normal()); - }; - basis() { if (!this._basis) { - this._basis = this.calcBasis(); + this._basis = [this.csys.x, this.csys.y, this.csys.z]; } return this._basis; } get csys() { - if (!this._csys) { - let [x,y,z] = this.basis(); - this._csys = new CSys(this.normal().multiply(this.depth()), x, y, z); - } + this.evalCSys(); return this._csys; } + + get isPlaneBased() { + return this.surface.simpleSurface && this.surface.simpleSurface.isPlane; + } + + evalCSys() { + if (!this._csys) { + if (this.isPlaneBased) { + let [x, y, z] = this.surface.simpleSurface.basis(); + let origin = z.multiply(this.surface.simpleSurface.w); + this._csys = new CSys(origin, x, y, z); + } else { + let origin = this.surface.southWestPoint(); + let z = this.surface.normalUV(0, 0); + let derivatives = this.surface.impl.eval(0, 0, 1); + let x = new Vector().set3(derivatives[1][0])._normalize(); + let y = new Vector().set3(derivatives[0][1])._normalize(); + + if (this.surface.inverted) { + const t = x; + x = y; + y = t; + } + this._csys = new CSys(origin, x, y, z); + } + this.w = this.csys.w(); + } + } setSketch(sketch) { this.sketch = sketch; @@ -76,14 +99,22 @@ export class MFace extends MObject { get sketchToWorldTransformation() { if (!this._sketchToWorldTransformation) { - this._sketchToWorldTransformation = this.surface.tangentPlaneInMiddle().get3DTransformation(); + if (this.isPlaneBased) { + this._sketchToWorldTransformation = this.csys.outTransformation; + } else { + throw 'sketches are supported only for planes yet'; + } } return this._sketchToWorldTransformation; } get worldToSketchTransformation() { if (!this._worldToSketchTransformation) { - this._worldToSketchTransformation = this.sketchToWorldTransformation.invert(); + if (this.isPlaneBased) { + this._worldToSketchTransformation = this.csys.inTransformation; + } else { + throw 'sketches are supported only for planes yet'; + } } return this._worldToSketchTransformation; } diff --git a/web/app/cad/model/mopenFace.js b/web/app/cad/model/mopenFace.js index d61226da..07ed97d7 100644 --- a/web/app/cad/model/mopenFace.js +++ b/web/app/cad/model/mopenFace.js @@ -3,11 +3,11 @@ import {MFace} from './mface'; export class MOpenFaceShell extends MShell { - constructor(surfacePrototype) { + constructor(surfacePrototype, csys) { super(); this.surfacePrototype = surfacePrototype; this.faces.push(new MFace(this.id + '/SURFACE', this, - surfacePrototype.boundTo([], 100, 100))); + surfacePrototype.boundTo([], 100, 100), csys)); } get face() { diff --git a/web/app/cad/model/surfacePrototype.js b/web/app/cad/model/surfacePrototype.js index c6ec0d5d..74160d85 100644 --- a/web/app/cad/model/surfacePrototype.js +++ b/web/app/cad/model/surfacePrototype.js @@ -1,4 +1,6 @@ import {createBoundingSurfaceFrom2DPoints} from '../../brep/brep-builder'; +import NurbsSurface from '../../brep/geom/surfaces/nurbsSurface'; +import {BrepSurface} from '../../brep/geom/surfaces/brepSurface'; export class SurfacePrototype { @@ -18,4 +20,35 @@ export class PlaneSurfacePrototype extends SurfacePrototype { boundTo(points2dOnSurface, minWidth, minHeight, offset) { return createBoundingSurfaceFrom2DPoints(points2dOnSurface, this.plane, minWidth, minHeight, offset); } +} + +/* + * The only difference PlaneSurfacePrototype is show phony surface + * when no sketching from csys origin for estetic purposes. + * When sketch exists behaves like PlaneSurfacePrototype using csys transformation though + */ +export class CSysPlaneSurfacePrototype extends SurfacePrototype { + + constructor(csys) { + super(); + this.csys = csys; + this.plane = { + get3DTransformation: () => this.csys.outTransformation + } + } + + boundTo(points2dOnSurface, minWidth, minHeight, offset) { + + if (points2dOnSurface.length === 0) { + let dx = this.csys.x.multiply(minWidth); + let dy = this.csys.y.multiply(minHeight); + let origin = this.csys.origin; + return new BrepSurface(new NurbsSurface(verb.geom.NurbsSurface.byKnotsControlPointsWeights( 1, 1, [0,0,1,1], [0,0,1,1], + [ [ origin.plus(dy).data(), origin.plus(dx)._plus(dy).data()] , + [ origin.data(), origin.plus(dx ).data() ] ] ))); + + } + + return createBoundingSurfaceFrom2DPoints(points2dOnSurface, this.plane, minWidth, minHeight, offset); + } } \ No newline at end of file diff --git a/web/app/cad/part/menuConfig.js b/web/app/cad/part/menuConfig.js index 9cf10aa7..0f7e43a6 100644 --- a/web/app/cad/part/menuConfig.js +++ b/web/app/cad/part/menuConfig.js @@ -43,7 +43,7 @@ export default [ label: 'datum', cssIcons: ['magic'], info: 'operations on datum', - actions: ['DATUM_ROTATE', 'DATUM_MOVE'] + actions: ['DATUM_ROTATE', 'DATUM_MOVE', '-', 'PLANE_FROM_DATUM'] // actions: ['DATUM_MOVE', 'DATUM_ROTATE', 'DATUM_REBASE', '-', 'PLANE_FROM_DATUM', 'BOX', 'SPHERE', 'TORUS', // 'CONE', 'CYLINDER'] }, diff --git a/web/app/cad/part/partOperationsPlugin.js b/web/app/cad/part/partOperationsPlugin.js index d6ee32dc..42a2b26e 100644 --- a/web/app/cad/part/partOperationsPlugin.js +++ b/web/app/cad/part/partOperationsPlugin.js @@ -1,12 +1,13 @@ import boxOperation from '../craft/primitives/boxOperation'; import extrudeOperation from '../craft/cutExtrude/extrudeOperation'; import cutOperation from '../craft/cutExtrude/cutOperation'; -import planeOperation from '../craft/primitives/planeOperation'; +import planeOperation from '../craft/primitives/simplePlane/simplePlaneOperation'; import filletOperation from '../craft/fillet/filletOperation'; import revolveOperation from '../craft/revolve/revolveOperation'; import createDatumOperation from '../craft/datum/create/createDatumOperation'; import moveDatumOperation from '../craft/datum/move/moveDatumOperation'; import rotateDatumOperation from '../craft/datum/rotate/rotateDatumOperation'; +import datumOperation from '../craft/primitives/plane/planeOperation'; export function activate({services}) { services.operation.registerOperations([ @@ -18,6 +19,7 @@ export function activate({services}) { filletOperation, createDatumOperation, moveDatumOperation, - rotateDatumOperation + rotateDatumOperation, + datumOperation ]) } \ No newline at end of file diff --git a/web/app/cad/sketch/sketchModel.js b/web/app/cad/sketch/sketchModel.js index c30e8fd1..fd93ae42 100644 --- a/web/app/cad/sketch/sketchModel.js +++ b/web/app/cad/sketch/sketchModel.js @@ -6,6 +6,7 @@ import {LUT} from '../../math/bezier-cubic' import {distanceAB, isCCW, makeAngle0_360} from '../../math/math' import {normalizeCurveEnds} from '../../brep/geom/impl/nurbs-ext'; import Vector from '../../../../modules/math/vector'; +import {AXIS, ORIGIN} from '../../math/l3space'; const RESOLUTION = 20; @@ -31,8 +32,8 @@ class SketchPrimitive { return this.constructor.name !== 'Segment'; } - toNurbs(plane) { - let verbNurbs = this.toVerbNurbs(plane, to3DTrFunc(plane)); + toNurbs(csys) { + let verbNurbs = this.toVerbNurbs(csys.outTransformation.apply, csys); if (this.inverted) { verbNurbs = verbNurbs.reverse(); } @@ -43,7 +44,7 @@ class SketchPrimitive { return new BrepCurve(new NurbsCurve(verbNurbs)); } - toVerbNurbs(plane, _3dtr) { + toVerbNurbs(tr) { throw 'not implemented' } @@ -63,8 +64,8 @@ export class Segment extends SketchPrimitive { return [this.a, this.b]; } - toVerbNurbs(plane, _3dtr) { - return new verb.geom.Line(_3dtr(this.a).data(), _3dtr(this.b).data()); + toVerbNurbs(tr) { + return new verb.geom.Line(tr(this.a).data(), tr(this.b).data()); } } @@ -103,8 +104,11 @@ export class Arc extends SketchPrimitive { return points; } - toVerbNurbs(plane, _3dtr) { - const basis = plane.basis(); + toVerbNurbs(tr, csys) { + + const basisX = csys.x; + const basisY = csys.y; + const startAngle = makeAngle0_360(Math.atan2(this.a.y - this.c.y, this.a.x - this.c.x)); const endAngle = makeAngle0_360(Math.atan2(this.b.y - this.c.y, this.b.x - this.c.x)); @@ -113,16 +117,16 @@ export class Arc extends SketchPrimitive { angle = Math.PI * 2 + angle; } function pointAtAngle(angle) { - const dx = basis[0].multiply(Math.cos(angle)); - const dy = basis[1].multiply(Math.sin(angle)); + const dx = basisX.multiply(Math.cos(angle)); + const dy = basisY.multiply(Math.sin(angle)); return dx.plus(dy); } const xAxis = pointAtAngle(startAngle); const yAxis = pointAtAngle(startAngle + Math.PI * 0.5); - let arc = new verb.geom.Arc(_3dtr(this.c).data(), xAxis.data(), yAxis.data(), distanceAB(this.c, this.a), 0, Math.abs(angle)); + let arc = new verb.geom.Arc(tr(this.c).data(), xAxis.data(), yAxis.data(), distanceAB(this.c, this.a), 0, Math.abs(angle)); - return adjustEnds(arc, _3dtr(this.a), _3dtr(this.b)) + return adjustEnds(arc, tr(this.a), tr(this.b)) } } @@ -184,7 +188,7 @@ export class EllipticalArc extends SketchPrimitive { return points; } - toVerbNurbs(plane, _3dtr) { + toVerbNurbs(tr) { const xAxis = this.ep2.minus(this.ep1)._multiply(0.5); const yAxis = new Vector(xAxis.y, xAxis.x)._normalize()._multiply(this.r) ; const center = this.ep1.plus(xAxis); @@ -192,8 +196,8 @@ export class EllipticalArc extends SketchPrimitive { const startAngle = makeAngle0_360(Math.atan2(this.a.y - center.y, this.a.x - center.x)); const endAngle = makeAngle0_360(Math.atan2(this.b.y - center.y, this.b.x - center.x)); - let arc = new verb.geom.EllipseArc(_3dtr(center).data(), _3dtr(xAxis).data(), _3dtr(yAxis).data(), startAngle, endAngle); - return adjustEnds(arc, _3dtr(this.a), _3dtr(this.b)) + let arc = new verb.geom.EllipseArc(tr(center).data(), tr(xAxis).data(), tr(yAxis).data(), startAngle, endAngle); + return adjustEnds(arc, tr(this.a), tr(this.b)) } } @@ -223,9 +227,10 @@ export class Circle extends SketchPrimitive { } - toVerbNurbs(plane, _3dtr) { - const basis = plane.basis(); - return new verb.geom.Circle(_3dtr(this.c).data(), basis[0].data(), basis[1].data(), this.r); + toVerbNurbs(tr, csys) { + const basisX = csys.x; + const basisY = csys.y; + return new verb.geom.Circle(tr(this.c).data(), basisX.data(), basisY.data(), this.r); } } @@ -252,9 +257,9 @@ export class Contour { this.segments.push(obj); } - tessellateOnSurface(surface) { + tessellateOnSurface(csys) { const cc = new CompositeCurve(); - const tr = to3DTrFunc(surface); + const tr = csys.outTransformation; let prev = null; let firstPoint = null; @@ -273,7 +278,7 @@ export class Contour { tessellation[n - 1] = firstPoint; } - cc.add(segment.toNurbs(surface), prev, segment); + cc.add(segment.toNurbs(csys), prev, segment); prev = tessellation[n - 1]; //It might be an optimization for segments @@ -286,14 +291,11 @@ export class Contour { return cc; } - transferOnSurface(surface) { + transferInCoordinateSystem(csys) { const cc = []; - - let prev = null; - let firstPoint = null; for (let segIdx = 0; segIdx < this.segments.length; ++segIdx) { let segment = this.segments[segIdx]; - cc.push(segment.toNurbs(surface)); + cc.push(segment.toNurbs(csys)); } return cc; } @@ -320,13 +322,6 @@ export class Contour { } } -function to3DTrFunc(surface) { - const _3dTransformation = surface.get3DTransformation(); - return function (v) { - return _3dTransformation.apply(v); - } -} - class CompositeCurve { constructor() { diff --git a/web/app/math/csys.js b/web/app/math/csys.js index d3df8a95..25e288dd 100644 --- a/web/app/math/csys.js +++ b/web/app/math/csys.js @@ -17,21 +17,25 @@ export default class CSys { this.z = z; } - get inTransformation() { + w() { + return this.z.dot(this.origin); + } + + get outTransformation() { if (!this._inTr) { const basis = new Matrix3().setBasis([this.x, this.y, this.z]); const translate = new Matrix3(); - translate.tx = this.origin.x; - translate.ty = this.origin.y; - translate.tz = this.origin.z; - this._inTr = basis.combine(translate); + basis.tx = this.origin.x; + basis.ty = this.origin.y; + basis.tz = this.origin.z; + this._inTr = basis;//basis.combine(translate); } return this._inTr; } - get outTransformation() { + get inTransformation() { if (!this._outTr) { - this._outTr = this.inTransformation().invert(); + this._outTr = this.outTransformation.invert(); } return this._outTr; } diff --git a/web/app/math/l3space.js b/web/app/math/l3space.js index c716807e..50aa930e 100644 --- a/web/app/math/l3space.js +++ b/web/app/math/l3space.js @@ -19,9 +19,12 @@ export const STANDARD_BASES = freeze({ }); -/** @constructor */ -function Matrix3() { - this.reset(); +class Matrix3 { + constructor() { + this.reset(); + } + + apply = vector => this.__apply(vector, new Vector()); } Matrix3.prototype.reset = function() { @@ -181,10 +184,6 @@ Matrix3.prototype.combine = function(transform, out) { return m; }; -Matrix3.prototype.apply = function(vector) { - return this.__apply(vector, new Vector()) -}; - Matrix3.prototype._apply = function(vector) { return this.__apply(vector, vector); };