mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-30 12:24:27 +01:00
approx for surfaces to accommodate non-plane surfaces to accommodate current boolean algorithm
This commit is contained in:
parent
b480b7550a
commit
51e427de7a
7 changed files with 68 additions and 14 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue