mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 16:33:15 +01:00
using unified face coordinate system for sketches and datums
This commit is contained in:
parent
49dffd435b
commit
e7cf64f54c
20 changed files with 231 additions and 97 deletions
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
const targetDir = invert ? csys.z : csys.z.negate();
|
||||
|
||||
let target;
|
||||
|
||||
let baseSurfaceNormal = baseSurface.normal;
|
||||
|
||||
const targetDir = baseSurfaceNormal.negate();
|
||||
|
||||
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});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
12
web/app/cad/craft/primitives/plane/PlaneWizard.jsx
Normal file
12
web/app/cad/craft/primitives/plane/PlaneWizard.jsx
Normal file
|
|
@ -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 <Group>
|
||||
<ReadOnlyValueField name='datum'/>
|
||||
</Group>;
|
||||
}
|
||||
6
web/app/cad/craft/primitives/plane/planeOpSchema.js
Normal file
6
web/app/cad/craft/primitives/plane/planeOpSchema.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
datum: {
|
||||
type: 'datum',
|
||||
defaultValue: {type: 'selection'}
|
||||
}
|
||||
}
|
||||
52
web/app/cad/craft/primitives/plane/planeOperation.js
Normal file
52
web/app/cad/craft/primitives/plane/planeOperation.js
Normal file
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -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';
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,41 +10,64 @@ 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;
|
||||
this.sketchObjects = [];
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
@ -19,3 +21,34 @@ export class PlaneSurfacePrototype extends SurfacePrototype {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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']
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
])
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,12 @@ export const STANDARD_BASES = freeze({
|
|||
});
|
||||
|
||||
|
||||
/** @constructor */
|
||||
function Matrix3() {
|
||||
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);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue