mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 18:02:50 +01:00
wizard for cut operation
This commit is contained in:
parent
0225493404
commit
8f3c07f952
13 changed files with 137 additions and 98 deletions
|
|
@ -2,15 +2,40 @@ import {Matrix3, ORIGIN} from '../../../math/l3space'
|
|||
import * as math from '../../../math/math'
|
||||
import Vector from '../../../math/vector'
|
||||
import {Extruder} from '../../../brep/brep-builder'
|
||||
import {BREPValidator} from '../../../brep/brep-validator'
|
||||
import {subtract} from '../../../brep/operations/boolean'
|
||||
import {Loop} from '../../../brep/topo/loop'
|
||||
import {ReadSketchFromFace} from './sketch-reader'
|
||||
|
||||
import {BREPSceneSolid} from '../../scene/brep-scene-object'
|
||||
|
||||
export function Extrude(app, params) {
|
||||
|
||||
}
|
||||
|
||||
export function Cut(app, params) {
|
||||
const face = app.findFace(params.face);
|
||||
const solid = face.solid;
|
||||
|
||||
const sketch = ReadSketchFromFace(app, face);
|
||||
for (let polygon of sketch) {
|
||||
if (!Loop.isPolygonCCWOnSurface(polygon, face.brepFace.surface)) {
|
||||
polygon.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function Cut(face, params) {
|
||||
const extruder = new ParametricExtruder(face, params);
|
||||
const cutter = extruder.extrude(sketch[0]);
|
||||
BREPValidator.validateToConsole(cutter);
|
||||
const newSolid = new BREPSceneSolid(subtract(solid.shell, cutter));
|
||||
//const newSolid = new BREPSceneSolid(cutter);
|
||||
solid.vanish();
|
||||
|
||||
app.viewer.workGroup.add(newSolid.cadGroup);
|
||||
app.bus.notify('solid-list', {
|
||||
solids: [],
|
||||
needRefresh: [newSolid]
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +57,7 @@ export class ParametricExtruder extends Extruder {
|
|||
}
|
||||
target._multiply(Math.abs(this.params.value));
|
||||
} else {
|
||||
target = normal.multiply(Math.abs(this.params.value));
|
||||
target = lidNormal.multiply(Math.abs(this.params.value));
|
||||
}
|
||||
this.target = target;
|
||||
}
|
||||
|
|
@ -40,10 +65,10 @@ export class ParametricExtruder extends Extruder {
|
|||
calculateLid(basePoints) {
|
||||
if (this.params.prism != 1) {
|
||||
const scale = this.params.prism < 0.001 ? 0.0001 : this.params.prism;
|
||||
const _3Dtr = this.face.surface.get3DTransformation();
|
||||
const _3Dtr = this.face.brepFace.surface.get3DTransformation();
|
||||
const _2Dtr = _3Dtr.invert();
|
||||
const poly2d = basePoints.map(p => _2Dtr.apply(p));
|
||||
basePoints = math.polygonOffset(poly2d, scale).map(p => _2Dtr.apply(p));
|
||||
basePoints = math.polygonOffset(poly2d, scale).map(p => _3Dtr.apply(p));
|
||||
}
|
||||
return basePoints.map(p => p.plus(this.target));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ import {sortPolygons, getSketchedPolygons3D} from '../mesh/workbench'
|
|||
|
||||
// here will be function of conversion sketch objects to brep DS
|
||||
|
||||
export function ReadSketchFromFace(app, faceId) {
|
||||
return getSketchedPolygons3D(app, faceId);
|
||||
export function ReadSketchFromFace(app, face) {
|
||||
return getSketchedPolygons3D(app, face);
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import {CURRENT_SELECTION as S} from './wizard'
|
||||
import {PreviewWizard, SketchBasedPreviewMaker} from './preview-wizard'
|
||||
import {PreviewWizard, SketchBasedPreviewer} from './preview-wizard'
|
||||
import {ParametricExtruder} from '../cut-extrude'
|
||||
|
||||
const METADATA = [
|
||||
|
|
@ -10,9 +10,9 @@ const METADATA = [
|
|||
['face' , 'face' , S ]
|
||||
];
|
||||
|
||||
class Cut extends PreviewWizard {
|
||||
export class CutWizard extends PreviewWizard {
|
||||
constructor(app, initialState) {
|
||||
super(app, 'CUT', METADATA, null, initialState)
|
||||
super(app, 'CUT', METADATA, new ExtrudePreviewer(true), initialState)
|
||||
}
|
||||
|
||||
uiLabel(name) {
|
||||
|
|
@ -21,9 +21,9 @@ class Cut extends PreviewWizard {
|
|||
}
|
||||
}
|
||||
|
||||
class Extrude extends PreviewWizard {
|
||||
export class ExtrudeWizard extends PreviewWizard {
|
||||
constructor(app, initialState) {
|
||||
super(app, 'EXTRUDE', METADATA, new ExtrudePreviewMaker(), initialState)
|
||||
super(app, 'EXTRUDE', METADATA, new ExtrudePreviewer(false), initialState)
|
||||
}
|
||||
|
||||
uiLabel(name) {
|
||||
|
|
@ -32,18 +32,19 @@ class Extrude extends PreviewWizard {
|
|||
}
|
||||
}
|
||||
|
||||
export class ExtrudePreviewMaker extends SketchBasedPreviewMaker{
|
||||
export class ExtrudePreviewer extends SketchBasedPreviewer {
|
||||
|
||||
constructor(cut) {
|
||||
constructor(inversed) {
|
||||
super();
|
||||
this.cut = cut;
|
||||
this.inversed = inversed;
|
||||
}
|
||||
|
||||
createImpl(app, params, sketch, face) {
|
||||
const parametricExtruder = new ParametricExtruder(face, params);
|
||||
|
||||
const baseNormal = this.cut ? face.surface.normal : face.surface.normal.negate();
|
||||
const lidNormal = this.cut ? baseNormal.negate() : face.surface.normal;
|
||||
const surface = face.brepFace.surface;
|
||||
const baseNormal = this.inversed ? surface.normal : surface.normal.negate();
|
||||
const lidNormal = this.inversed ? baseNormal.negate() : surface.normal;
|
||||
|
||||
parametricExtruder.prepareLidCalculation(baseNormal, lidNormal);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,20 +4,26 @@ import {Loop} from '../../../../brep/topo/loop'
|
|||
|
||||
export class PreviewWizard extends Wizard {
|
||||
|
||||
constructor(app, opearation, metadata, previewMaker, initialState) {
|
||||
constructor(app, opearation, metadata, previewer, initialState) {
|
||||
super(app, opearation, metadata, initialState);
|
||||
this.operation = opearation;
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.previewMaker = previewMaker;
|
||||
this.previewer = previewer;
|
||||
this.previewObject = null;
|
||||
this.app.viewer.workGroup.add(this.previewGroup);
|
||||
this.updatePreview();
|
||||
}
|
||||
|
||||
createRequest() {
|
||||
return {
|
||||
type: this.operation,
|
||||
params: this.readFormFields()
|
||||
};
|
||||
}
|
||||
|
||||
updatePreview() {
|
||||
if (this.previewObject != null) {
|
||||
this.destroyPreviewObject();
|
||||
}
|
||||
this.previewObject = this.previewMaker.create(this.app, this.readFormFields());
|
||||
this.destroyPreviewObject();
|
||||
this.previewObject = this.previewer.create(this.app, this.readFormFields());
|
||||
if (this.previewObject != null) {
|
||||
this.previewGroup.add( this.previewObject );
|
||||
}
|
||||
|
|
@ -25,14 +31,22 @@ export class PreviewWizard extends Wizard {
|
|||
}
|
||||
|
||||
destroyPreviewObject() {
|
||||
this.previewGroup.parent.remove( this.previewObject );
|
||||
this.previewObject.geometry.dispose();
|
||||
this.previewGroup = null;
|
||||
if (this.previewObject != null) {
|
||||
this.previewGroup.remove( this.previewObject );
|
||||
this.previewObject.geometry.dispose();
|
||||
this.previewObject = null;
|
||||
}
|
||||
}
|
||||
|
||||
onUIChange() {
|
||||
super.onUIChange();
|
||||
this.updatePreview();
|
||||
}
|
||||
|
||||
|
||||
dispose() {
|
||||
this.destroyPreviewObject();
|
||||
this.app.viewer.workGroup.remove(this.previewGroup);
|
||||
this.app.viewer.render();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -54,7 +68,7 @@ PreviewWizard.createMesh = function(triangles) {
|
|||
return new THREE.Mesh(geometry, IMAGINARY_SURFACE_MATERIAL);
|
||||
};
|
||||
|
||||
export class SketchBasedPreviewMaker {
|
||||
export class SketchBasedPreviewer {
|
||||
|
||||
constructor() {
|
||||
this.fixToCCW = true;
|
||||
|
|
@ -69,15 +83,16 @@ export class SketchBasedPreviewMaker {
|
|||
if (!face) return null;
|
||||
const needSketchRead = !this.sketch || params.face != this.face;
|
||||
if (needSketchRead) {
|
||||
this.sketch = ReadSketchFromFace(app, params.face);
|
||||
this.sketch = ReadSketchFromFace(app, face);
|
||||
for (let polygon of this.sketch) {
|
||||
if (!Loop.isPolygonCCWOnSurface(polygon, face.surface) && this.fixToCCW) {
|
||||
if (!Loop.isPolygonCCWOnSurface(polygon, face.brepFace.surface) && this.fixToCCW) {
|
||||
polygon.reverse();
|
||||
}
|
||||
}
|
||||
this.face = params.face;
|
||||
}
|
||||
return this.createImpl(app, params, this.sketch, face);
|
||||
const triangles = this.createImpl(app, params, this.sketch, face);
|
||||
return PreviewWizard.createMesh(triangles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +102,8 @@ export const IMAGINARY_SURFACE_MATERIAL = new THREE.MeshPhongMaterial({
|
|||
transparent: true,
|
||||
opacity: 0.5,
|
||||
shininess: 0,
|
||||
depthWrite: false,
|
||||
depthTest: false,
|
||||
side : THREE.DoubleSide
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ export class Wizard {
|
|||
|
||||
constructor(app, opearation, metadata, initialState) {
|
||||
this.app = app;
|
||||
this.metadata = params;
|
||||
this.metadata = metadata;
|
||||
this.formFields = {};
|
||||
this.box = this.createUI(opearation, metadata);
|
||||
if (initialState != undefined) {
|
||||
|
|
@ -16,6 +16,10 @@ export class Wizard {
|
|||
return name;
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.box.root.find('input, select').first().focus()
|
||||
}
|
||||
|
||||
createUI(operation, metadata) {
|
||||
const box = new tk.Box($('#view-3d'));
|
||||
const folder = new tk.Folder(operation);
|
||||
|
|
@ -23,10 +27,10 @@ export class Wizard {
|
|||
for (let def of metadata) {
|
||||
const name = def[0];
|
||||
const type = def[1];
|
||||
const defaultValue = def[1];
|
||||
const defaultValue = def[2];
|
||||
const params = def[3];
|
||||
const label = this.uiLabel(name);
|
||||
const formItem = createFormField(name, label, type, defaultValue, params);
|
||||
const formItem = this.createFormField(name, label, type, params);
|
||||
formItem.setter(defaultValue);
|
||||
tk.add(folder, formItem.ui);
|
||||
this.formFields[name] = formItem;
|
||||
|
|
@ -48,17 +52,21 @@ export class Wizard {
|
|||
}
|
||||
|
||||
okClick() {
|
||||
this.apply();
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
onUIChange() {
|
||||
|
||||
apply() {
|
||||
this.app.craft.modify(this.createRequest(), false);
|
||||
}
|
||||
|
||||
onUIChange() {}
|
||||
|
||||
readFormFields() {
|
||||
const params = {};
|
||||
for (let field of this.formFields) {
|
||||
params[field.name] = field.getter();
|
||||
const keys = Object.keys(this.formFields);
|
||||
for (let key of keys) {
|
||||
params[key] = this.formFields[key].getter();
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
|
@ -80,13 +88,13 @@ export class Wizard {
|
|||
|
||||
createFormField(name, label, type, params) {
|
||||
if (type == 'number') {
|
||||
const number = tk.config(tk.Number(label, 0, params.step, params.round), params);
|
||||
const number = tk.config(new tk.Number(label, 0, params.step, params.round), params);
|
||||
number.input.on('t-change', () => this.onUIChange(name));
|
||||
return Field.fromInput(number.input);
|
||||
return Field.fromInput(number, Field.TEXT_TO_NUMBER_COERCION);
|
||||
} else if (type == 'face') {
|
||||
const face = new tk.Text(label, '');
|
||||
face.input.on('change', () => this.onUIChange(name));
|
||||
return Field.fromInput(face.input, undefined, (faceId) => {
|
||||
return Field.fromInput(face, undefined, (faceId) => {
|
||||
if (faceId === CURRENT_SELECTION) {
|
||||
let selection = this.app.viewer.selectionMgr.selection[0];
|
||||
return selection ? selection.id : '';
|
||||
|
|
@ -100,17 +108,20 @@ function FaceSelectionListener() {
|
|||
this.callbacks = [];
|
||||
}
|
||||
|
||||
function Field(getter, setter) {
|
||||
function Field(ui, getter, setter) {
|
||||
this.ui = ui;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
Field.NO_COERCION = (v) => v;
|
||||
Field.NO_COERCION = (v) => v;
|
||||
Field.NUMBER_TO_TEXT_COERCION = (v) => v + "";
|
||||
Field.TEXT_TO_NUMBER_COERCION = (v) => parseFloat(v);
|
||||
|
||||
Field.fromInput = function (input, getterCoercer, setterCoercer) {
|
||||
Field.fromInput = function (inputEl, getterCoercer, setterCoercer) {
|
||||
getterCoercer = getterCoercer || Field.NO_COERCION;
|
||||
setterCoercer = setterCoercer || Field.NO_COERCION;
|
||||
return new Field(() => getterCoercer(input.val()), (value) => input.val(setterCoercer(value)));
|
||||
return new Field(inputEl, () => getterCoercer(inputEl.input.val()), (value) => inputEl.input.val(setterCoercer(value)));
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import Counters from '../counters'
|
|||
|
||||
export function Craft(app) {
|
||||
this.app = app;
|
||||
this.operations = {};
|
||||
this.history = [];
|
||||
this.solids = [];
|
||||
this._historyPointer = 0;
|
||||
|
|
@ -18,6 +19,10 @@ export function Craft(app) {
|
|||
});
|
||||
}
|
||||
|
||||
Craft.prototype.registerOperation = function(name, action) {
|
||||
this.operations[name] = action;
|
||||
};
|
||||
|
||||
Craft.prototype.remove = function(modificationIndex) {
|
||||
const history = this.history;
|
||||
history.splice(modificationIndex, history.length - modificationIndex);
|
||||
|
|
@ -62,35 +67,7 @@ Craft.prototype.modifyInternal = function(request) {
|
|||
var op = this.operations[request.type];
|
||||
if (!op) return;
|
||||
|
||||
var newSolids = op(this.app, request.params);
|
||||
if (newSolids == null) return;
|
||||
const toUpdate = [];
|
||||
for (let i = 0; i < request.solids.length; i++) {
|
||||
let solid = request.solids[i];
|
||||
var indexToRemove = this.solids.indexOf(solid);
|
||||
if (indexToRemove != -1) {
|
||||
let updatedIdx = newSolids.findIndex((s) => s.id == solid.id);
|
||||
if (updatedIdx != -1) {
|
||||
toUpdate[updatedIdx] = indexToRemove;
|
||||
} else {
|
||||
this.solids.splice(indexToRemove, 1);
|
||||
}
|
||||
}
|
||||
solid.vanish();
|
||||
}
|
||||
for (let i = 0; i < newSolids.length; i++) {
|
||||
let solid = newSolids[i];
|
||||
if (toUpdate[i] !== undefined) {
|
||||
this.solids[toUpdate[i]] = solid;
|
||||
} else {
|
||||
this.solids.push(solid);
|
||||
}
|
||||
this.app.viewer.workGroup.add(solid.cadGroup);
|
||||
}
|
||||
this.app.bus.notify('solid-list', {
|
||||
solids: this.solids,
|
||||
needRefresh: newSolids
|
||||
});
|
||||
op(this.app, request.params);
|
||||
};
|
||||
|
||||
Craft.prototype.modify = function(request, overriding) {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ export function getSketchedPolygons3D(app, face) {
|
|||
var geom = readSketchGeom(JSON.parse(savedFace), face.id, false);
|
||||
var polygons2D = cad_utils.sketchToPolygons(geom);
|
||||
|
||||
var normal = face.csgGroup.normal;
|
||||
var normal = face.normal();
|
||||
var depth = null;
|
||||
var sketchedPolygons = [];
|
||||
for (var i = 0; i < polygons2D.length; i++) {
|
||||
|
|
@ -180,7 +180,7 @@ export function getSketchedPolygons3D(app, face) {
|
|||
if (depth == null) {
|
||||
var _3dTransformation = new Matrix3().setBasis(face.basis());
|
||||
//we lost depth or z off in 2d sketch, calculate it again
|
||||
depth = face.csgGroup.plane.w;
|
||||
depth = face.depth();
|
||||
}
|
||||
|
||||
var polygon = [];
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
import {MESH_OPERATIONS} from './mesh/workbench'
|
||||
import {Extrude} from './brep/cut-extrude'
|
||||
import {Extrude, Cut} from './brep/cut-extrude'
|
||||
|
||||
export const CUT = {
|
||||
icon: 'img/3d/cut',
|
||||
label: 'Cut',
|
||||
info: (p) => '(' + r(p.depth) + ')',
|
||||
action: (app, request) => {
|
||||
}
|
||||
info: (p) => '(' + r(p.value) + ')',
|
||||
action: (app, params) => Cut(app, params)
|
||||
};
|
||||
|
||||
export const PAD = {
|
||||
icon: 'img/3d/extrude',
|
||||
label: 'Extrude',
|
||||
info: (p) => '(' + r(p.height) + ')',
|
||||
info: (p) => '(' + r(p.value) + ')',
|
||||
action: (app, request) => {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ function App() {
|
|||
this.tabSwitcher = new TabSwitcher($('#tab-switcher'), $('#view-3d'));
|
||||
this.controlBar = new ControlBar(this, $('#control-bar'));
|
||||
|
||||
this.ui = new UI(this);
|
||||
this.craft = new Craft(this);
|
||||
this.ui = new UI(this);
|
||||
|
||||
AddDebugSupport(this);
|
||||
|
||||
|
|
@ -44,6 +44,8 @@ function App() {
|
|||
this.load();
|
||||
}
|
||||
|
||||
this.BREPTest();
|
||||
|
||||
this._refreshSketches();
|
||||
this.viewer.render();
|
||||
|
||||
|
|
@ -69,11 +71,11 @@ function App() {
|
|||
}
|
||||
app._refreshSketches();
|
||||
});
|
||||
this.BREPTest();
|
||||
}
|
||||
|
||||
App.prototype.BREPTest = function() {
|
||||
setTimeout(() => this.BREPTestImpl());
|
||||
this.BREPTestImpl();
|
||||
//setTimeout(() => this.BREPTestImpl());
|
||||
};
|
||||
|
||||
App.prototype.BREPTestImpl1 = function() {
|
||||
|
|
|
|||
|
|
@ -78,13 +78,7 @@ export class MeshSceneSolid extends SceneSolid {
|
|||
|
||||
this.processWires();
|
||||
};
|
||||
|
||||
vanish () {
|
||||
this.cadGroup.parent.remove( this.cadGroup );
|
||||
this.material.dispose();
|
||||
this.mesh.geometry.dispose();
|
||||
}
|
||||
|
||||
|
||||
collectCurvedSurface(face) {
|
||||
var derivedFrom = getDerivedFrom(face.csgGroup.shared);
|
||||
if (derivedFrom === null || !isCurveClass(derivedFrom._class)) return;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ export class SceneSolid {
|
|||
}
|
||||
|
||||
vanish() {
|
||||
throw 'not implemented';
|
||||
this.cadGroup.parent.remove( this.cadGroup );
|
||||
this.material.dispose();
|
||||
this.mesh.geometry.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import ToolBar from './toolbar'
|
|||
import * as MenuConfig from '../menu/menu-config'
|
||||
import * as Operations from '../craft/operations'
|
||||
import Menu from '../menu/menu'
|
||||
import {ExtrudeWizard} from '../craft/mesh/wizards/extrude'
|
||||
import {CutWizard} from '../craft/brep/wizards/cut-extrude'
|
||||
|
||||
import {ExtrudeWizard as MeshExtrudeWizard} from '../craft/mesh/wizards/extrude'
|
||||
import {RevolveWizard} from '../craft/mesh/wizards/revolve'
|
||||
import {PlaneWizard} from '../craft/mesh/wizards/plane'
|
||||
import {BoxWizard} from '../craft/mesh/wizards/box'
|
||||
|
|
@ -56,6 +58,15 @@ function UI(app) {
|
|||
app.bus.subscribe("solid-pick", function(solid) {
|
||||
ui.registerWizard(new TransformWizard(app.viewer, solid));
|
||||
});
|
||||
registerOperations(app);
|
||||
}
|
||||
|
||||
function registerOperations(app) {
|
||||
const opNames = Object.keys(Operations);
|
||||
for (let opName of opNames) {
|
||||
console.log('Registering Operation ' + opName);
|
||||
app.craft.registerOperation(opName, Operations[opName].action);
|
||||
}
|
||||
}
|
||||
|
||||
UI.prototype.createCraftToolBar = function (vertPos) {
|
||||
|
|
@ -121,7 +132,7 @@ UI.prototype.fillControlBar = function() {
|
|||
};
|
||||
|
||||
UI.prototype.registerWizard = function(wizard, overridingHistory) {
|
||||
wizard.ui.box.root.css({left : (this.mainBox.root.width() + this.craftToolBar.node.width() + 30) + 'px', top : 0});
|
||||
wizard.box.root.css({left : (this.mainBox.root.width() + this.craftToolBar.node.width() + 30) + 'px', top : 0});
|
||||
var craft = this.app.craft;
|
||||
wizard.onRequestReady = function(request) {
|
||||
if (request.invalidAndShouldBeDropped == true) {
|
||||
|
|
@ -167,9 +178,9 @@ UI.prototype.createWizardForOperation = function(op) {
|
|||
UI.prototype.createWizard = function(type, overridingHistory, initParams, face) {
|
||||
let wizard = null;
|
||||
if ('CUT' === type) {
|
||||
wizard = new ExtrudeWizard(this.app, face, true, initParams);
|
||||
wizard = new CutWizard(this.app, initParams);
|
||||
} else if ('PAD' === type) {
|
||||
wizard = new ExtrudeWizard(this.app, face, false, initParams);
|
||||
wizard = new MeshExtrudeWizard(this.app, face, false, initParams);
|
||||
} else if ('REVOLVE' === type) {
|
||||
wizard = new RevolveWizard(this.app, face, initParams);
|
||||
} else if ('PLANE' === type) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ export function BooleanAlgorithm( shell1, shell2, type ) {
|
|||
}
|
||||
const loop = new Loop();
|
||||
while (edge) {
|
||||
//__DEBUG__.AddHalfEdge(edge);
|
||||
__DEBUG__.AddHalfEdge(edge);
|
||||
const isNew = faceData.newEdges.indexOf(edge) != -1;
|
||||
if (isNew) newLoops.add(loop);
|
||||
|
||||
|
|
@ -435,7 +435,7 @@ function intersectFaceWithEdge(face, edge, result, vertecies) {
|
|||
//TODO: should check if point on a vertex then exclude two edges of the vertex from further intersection test cuz it would produce three identical Nodes
|
||||
if (pointBelongsToFace(pointOfIntersection, face)) {
|
||||
let vertexOfIntersection;
|
||||
if (math.areVectorsEqual(edge.vertexA.point, pointOfIntersection, TOLERANCE)) {
|
||||
if (math.areVectorsEqual(edge.vertexA.point, pointOfIntersection, TOLERANCE)) { //TODO: TOLERANCE^2 ???
|
||||
vertecies.add(edge.vertexA);
|
||||
vertexOfIntersection = edge.vertexA;
|
||||
//console.log("point A on surface");
|
||||
|
|
|
|||
Loading…
Reference in a new issue