diff --git a/web/app/3d/craft/brep/cut-extrude.js b/web/app/3d/craft/brep/cut-extrude.js index 18fdaf3a..38bb69da 100644 --- a/web/app/3d/craft/brep/cut-extrude.js +++ b/web/app/3d/craft/brep/cut-extrude.js @@ -3,10 +3,12 @@ import * as math from '../../../math/math' import Vector from '../../../math/vector' import {Extruder} from '../../../brep/brep-builder' import {BREPValidator} from '../../../brep/brep-validator' +import * as approx from '../../../brep/approx' import {subtract, union} from '../../../brep/operations/boolean' import {Loop} from '../../../brep/topo/loop' import {Shell} from '../../../brep/topo/shell' import {ReadSketchFromFace} from './sketch-reader' +import {isCurveClass} from '../../cad-utils' import {BREPSceneSolid} from '../../scene/brep-scene-object' @@ -35,6 +37,7 @@ export function doOperation(app, params, cut) { newFace.id = undefined; } } + approx.update(result); const newSolid = new BREPSceneSolid(result); return { outdated: [solid], @@ -56,6 +59,7 @@ export class ParametricExtruder extends Extruder { constructor(params) { super(); this.params = params; + this.approxIndex = new Map(); } prepareLidCalculation(baseNormal, lidNormal) { @@ -84,4 +88,14 @@ export class ParametricExtruder extends Extruder { } return basePoints.map(p => p.plus(this.target)); } + + onWallCallback(wallFace, baseHalfEdge) { + const conn = baseHalfEdge.vertexA.point.sketchConnectionObject; + if (conn && isCurveClass(conn._class)) { + if (!conn.approxSurface) { + conn.approxSurface = new approx.ApproxSurface(); + } + conn.approxSurface.addFace(wallFace); + } + } } diff --git a/web/app/3d/scene/brep-scene-object.js b/web/app/3d/scene/brep-scene-object.js index 14a10003..251a237c 100644 --- a/web/app/3d/scene/brep-scene-object.js +++ b/web/app/3d/scene/brep-scene-object.js @@ -1,4 +1,5 @@ import Vector from '../../math/vector' +import {EDGE_AUX} from '../../brep/approx' import {Triangulate} from '../../3d/triangulation' import {SceneSolid, SceneFace} from './scene-object' @@ -40,7 +41,9 @@ export class BREPSceneSolid extends SceneSolid { for (let halfEdge of face.outerLoop.halfEdges) { if (!visited.has(halfEdge.edge)) { visited.add(halfEdge.edge); - this.addLineToScene(halfEdge.vertexA.point.three(), halfEdge.vertexB.point.three(), halfEdge.edge); + if (halfEdge.edge.data[EDGE_AUX] === undefined) { + this.addLineToScene(halfEdge.vertexA.point.three(), halfEdge.vertexB.point.three(), halfEdge.edge); + } } } } @@ -55,6 +58,7 @@ class BREPSceneFace extends SceneFace { super(solid, brepFace.id); brepFace.id = this.id; this.brepFace = brepFace; + brepFace.data['scene.face'] = this; } diff --git a/web/app/3d/selection.js b/web/app/3d/selection.js index fc655f67..09e3dede 100644 --- a/web/app/3d/selection.js +++ b/web/app/3d/selection.js @@ -1,4 +1,5 @@ import DPR from '../utils/dpr' +import * as approx from '../brep/approx' class AbstractSelectionManager { @@ -81,9 +82,10 @@ export class SelectionManager extends AbstractSelectionManager { select(sceneFace) { this.clear(); - if (!!sceneFace.curvedSurfaces) { - for (var i = 0; i < sceneFace.curvedSurfaces.length; i++) { - var face = sceneFace.curvedSurfaces[i]; + const group = this.findGroup(sceneFace); + if (group) { + for (var i = 0; i < group.length; i++) { + var face = group[i]; this.selection.push(face); setFacesColor(face.meshFaces, this.readOnlyColor); } @@ -98,6 +100,17 @@ export class SelectionManager extends AbstractSelectionManager { this.viewer.render(); } + findGroup(sceneFace) { + if (sceneFace.curvedSurfaces) { + return sceneFace.curvedSurfaces; + } + const approxFace = sceneFace.brepFace.data[approx.FACE_CHUNK]; + if (approxFace) { + return approxFace.faces.map(f => f.data['scene.face']); + } + return undefined; + } + deselectAll() { this.clear(); this.viewer.bus.notify('selection', null); diff --git a/web/app/brep/approx.js b/web/app/brep/approx.js index b73722cf..574c6532 100644 --- a/web/app/brep/approx.js +++ b/web/app/brep/approx.js @@ -1,8 +1,10 @@ -const FACE_CHUNK = 'approx.face.chunk'; -const EDGE_CHUNK = 'approx.edge.chunk'; -const EDGE_AUX = 'approx.edge.aux'; +import {DoubleKeyMap} from '../utils/utils' -class ApproxSurface { +export const FACE_CHUNK = 'approx.face.chunk'; +export const EDGE_CHUNK = 'approx.edge.chunk'; +export const EDGE_AUX = 'approx.edge.aux'; + +export class ApproxSurface { constructor() { this.faces = []; } @@ -11,9 +13,14 @@ class ApproxSurface { face.data[FACE_CHUNK] = this; this.faces.push(face); } + + clear() { + this.faces = []; + } + } -class ApproxCurve { +export class ApproxCurve { constructor(surface1, surface2) { this.surface1 = surface1; this.surface2 = surface2; @@ -37,8 +44,20 @@ class ApproxCurve { } } -function update(shell) { +export function update(shell) { const index = new DoubleKeyMap(); + for (let face of shell.faces) { + const approxSurface = face.data[FACE_CHUNK]; + if (approxSurface) { + approxSurface.clear(); + } + } + for (let face of shell.faces) { + const approxSurface = face.data[FACE_CHUNK]; + if (approxSurface) { + approxSurface.addFace(face); + } + } for (let e of shell.edges) { const face1 = e.halfEdge1.loop.face; const face2 = e.halfEdge2.loop.face; @@ -55,7 +74,7 @@ function update(shell) { } } -function getCurve(index, o1, o2) { +export function getCurve(index, o1, o2) { let curve = index.get(o1, o2); if (curve == null) { curve = new ApproxCurve(o1, o2); diff --git a/web/app/brep/brep-builder.js b/web/app/brep/brep-builder.js index a729e261..9f2f477c 100644 --- a/web/app/brep/brep-builder.js +++ b/web/app/brep/brep-builder.js @@ -38,7 +38,6 @@ export class Extruder { } extrude(basePoints, normal) { - basePoints = checkCCW(basePoints, normal); const baseLoop = createPlaneLoop(basePoints.map(p => new Vertex(p))); const baseFace = createPlaneFace(normal, baseLoop); const lidNormal = normal.multiply(-1); @@ -72,6 +71,7 @@ export class Extruder { const wallFace = createPlaneFace(wallNormal, wallLoop); wallFace.role = 'wall:' + i; + this.onWallCallback(wallFace, baseHalfEdge); shell.faces.push(wallFace); } @@ -90,6 +90,9 @@ export class Extruder { shell.faces.forEach(f => f.shell = shell); return shell; } + + onWallCallback(wallFace, baseHalfEdge) { + } } export class SimpleExtruder extends Extruder { diff --git a/web/app/brep/operations/boolean.js b/web/app/brep/operations/boolean.js index 3a52f88e..eae67a04 100644 --- a/web/app/brep/operations/boolean.js +++ b/web/app/brep/operations/boolean.js @@ -619,6 +619,7 @@ export function loopsToFaces(originFace, loops, out) { function createFaces(nestedLoop, surface) { const loop = nestedLoop.loop; const newFace = new Face(surface); + Object.assign(newFace.data, originFace.data); newFace.outerLoop = loop; loop.face = newFace; out.push(newFace); diff --git a/web/app/utils/utils.js b/web/app/utils/utils.js index 4c6c6fba..ff8e553f 100644 --- a/web/app/utils/utils.js +++ b/web/app/utils/utils.js @@ -78,11 +78,11 @@ export class DoubleKeyMap { if (subMap == null) { subMap = this.map.get(b); if (subMap != null) { - return subMap.get(a);; + return subMap.get(a); } return null; } - subMap.get(b); + return subMap.get(b); } set(a, b, value) {