From 8d5561f2b78a2fe70aacd421a7401698871c5d57 Mon Sep 17 00:00:00 2001 From: "Val Erastov (xibyte)" Date: Tue, 15 Dec 2020 02:03:09 -0800 Subject: [PATCH] defeature by vertex utility --- modules/brep/operations/boolean.js | 2 +- .../brep/operations/directMod/defeaturing.ts | 34 +++++++++++++++++++ modules/engine/api.ts | 34 +++++++++++++++++++ .../engine/impl/wasm/GenericWASMEngine_V1.ts | 4 +++ modules/engine/impl/wasm/externals.d.ts | 1 + modules/geom/impl/plane.ts | 8 +++++ ...tureWizard.tsx => DefeatureFaceWizard.tsx} | 2 +- web/app/cad/model/mshell.ts | 8 ++--- web/app/cad/sandbox.ts | 29 ++++++++++++---- 9 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 modules/brep/operations/directMod/defeaturing.ts rename web/app/cad/craft/defeature/{DefeatureWizard.tsx => DefeatureFaceWizard.tsx} (96%) diff --git a/modules/brep/operations/boolean.js b/modules/brep/operations/boolean.js index 7b051357..4af2b63c 100644 --- a/modules/brep/operations/boolean.js +++ b/modules/brep/operations/boolean.js @@ -1138,7 +1138,7 @@ class VertexFactory { } } -class EdgeGraph { +export class EdgeGraph { constructor() { this.vertexToEdge = new Map(); this.graphEdges = []; diff --git a/modules/brep/operations/directMod/defeaturing.ts b/modules/brep/operations/directMod/defeaturing.ts new file mode 100644 index 00000000..a38b749d --- /dev/null +++ b/modules/brep/operations/directMod/defeaturing.ts @@ -0,0 +1,34 @@ +import {Shell} from "brep/topo/shell"; +import {Vertex} from "brep/topo/vertex"; +import {EdgeGraph} from "brep/operations/boolean"; +import {HalfEdge} from "brep/topo/edge"; +import {Plane} from "geom/impl/plane"; +import {DEFLECTION} from "../../../../web/app/cad/craft/e0/common"; +import {EngineAPI_V1, GenericResponse} from "engine/api"; + +export function defeatureByVertex(shell: Shell, vertex: Vertex, engine: EngineAPI_V1): GenericResponse { + + const graph = new EdgeGraph(); + for (let e of shell.edges) { + graph.add(e.halfEdge1); + graph.add(e.halfEdge2); + } + + const edges: HalfEdge[] = graph.vertexToEdge.get(vertex); + const [p1, p2, p3] = edges.map(e => e.vertexB.point); + let plane = Plane.by3Points(p1, p2, p3); + + if (plane.normal.multiply(plane.w).minus(vertex.point).dot(plane.normal) > 1) { + plane = plane.invert(); + } + + return engine.splitByPlane({ + deflection: DEFLECTION, + shape: shell.data.externals.ptr, + plane: { + point: plane.normal.multiply(plane.w).data(), + dir: plane.normal.data(), + } + }) + +} \ No newline at end of file diff --git a/modules/engine/api.ts b/modules/engine/api.ts index 5127f158..7fc45b64 100644 --- a/modules/engine/api.ts +++ b/modules/engine/api.ts @@ -177,6 +177,40 @@ export interface EngineAPI_V1 { deflection: number; + }): GenericResponse; + + /** + * Split a shape by plane + */ + splitByPlane(params: { + + /** + * Base shape containing face to split + */ + shape: Handle; + + /** + * Splitting plane + */ + plane: { + + /** + * Plane's point + */ + point: Vec3; + + /** + * Plane's normal + */ + dir: Vec3; + }; + + /** + * Tessellation detail parameter + */ + deflection: number; + + }): GenericResponse; /** diff --git a/modules/engine/impl/wasm/GenericWASMEngine_V1.ts b/modules/engine/impl/wasm/GenericWASMEngine_V1.ts index 9752c1cb..311a5df3 100644 --- a/modules/engine/impl/wasm/GenericWASMEngine_V1.ts +++ b/modules/engine/impl/wasm/GenericWASMEngine_V1.ts @@ -53,6 +53,10 @@ export class GenericWASMEngine_V1 implements EngineAPI_V1 { return callEngine(params, Module._SPI_splitFace); } + splitByPlane(params) { + return callEngine(params, Module._SPI_splitByPlane); + } + defeatureFaces(params) { return callEngine(params, Module._SPI_defeatureFaces); } diff --git a/modules/engine/impl/wasm/externals.d.ts b/modules/engine/impl/wasm/externals.d.ts index 87a34bc3..0df932bb 100644 --- a/modules/engine/impl/wasm/externals.d.ts +++ b/modules/engine/impl/wasm/externals.d.ts @@ -10,6 +10,7 @@ declare var Module: { _SPI_stepImport: Function; _SPI_revolve: Function; _SPI_splitFace: Function; + _SPI_splitByPlane: Function; _SPI_defeatureFaces: Function; _SPI_loftPreview: Function; _SPI_loft: Function; diff --git a/modules/geom/impl/plane.ts b/modules/geom/impl/plane.ts index 7a8f4295..fc6c41fb 100644 --- a/modules/geom/impl/plane.ts +++ b/modules/geom/impl/plane.ts @@ -18,6 +18,14 @@ export class Plane { static XZ = new Plane(AXIS.Y, 0); static YZ = new Plane(AXIS.X, 0); + static by3Points(a: Vector, b: Vector, c: Vector): Plane { + const ab = b.minus(a); + const ac = c.minus(a); + const n = ab.cross(ac)._normalize(); + const w = a.dot(n); + return new Plane(n, w); + } + constructor(normal: Vector, w: number) { this.normal = normal; this.w = w; diff --git a/web/app/cad/craft/defeature/DefeatureWizard.tsx b/web/app/cad/craft/defeature/DefeatureFaceWizard.tsx similarity index 96% rename from web/app/cad/craft/defeature/DefeatureWizard.tsx rename to web/app/cad/craft/defeature/DefeatureFaceWizard.tsx index 5e19876c..af29ecc2 100644 --- a/web/app/cad/craft/defeature/DefeatureWizard.tsx +++ b/web/app/cad/craft/defeature/DefeatureFaceWizard.tsx @@ -7,7 +7,7 @@ import {DEFLECTION} from "../e0/common"; import {MFace} from "../../model/mface"; -export function DefeatureWizard() { +export function DefeatureFaceWizard() { const ctx = useContext(AppContext); diff --git a/web/app/cad/model/mshell.ts b/web/app/cad/model/mshell.ts index 63318aaa..5ec6949d 100644 --- a/web/app/cad/model/mshell.ts +++ b/web/app/cad/model/mshell.ts @@ -1,5 +1,5 @@ import {MObject, MObjectIdGenerator} from './mobject'; -import {MBrepFace} from './mface'; +import {MBrepFace, MFace} from './mface'; import {MEdge} from './medge'; import {MVertex} from './mvertex'; import CSys from 'math/csys'; @@ -15,9 +15,9 @@ export class MShell extends MObject { csys: CSys; shell; - faces = []; - edges = []; - vertices = []; + faces: MFace[] = []; + edges: MEdge[] = []; + vertices: MVertex[] = []; location$: StateStream = state(new Matrix3x4()); diff --git a/web/app/cad/sandbox.ts b/web/app/cad/sandbox.ts index efaaf219..5200e76a 100644 --- a/web/app/cad/sandbox.ts +++ b/web/app/cad/sandbox.ts @@ -8,17 +8,15 @@ import {createOctreeFromSurface, traverseOctree} from "voxels/octree"; import {Matrix3x4} from 'math/matrix'; import {AXIS, ORIGIN} from "math/vector"; import {BrepInputData, CubeExample} from "engine/data/brepInputData"; -import {Vec3} from "math/vec"; import {ApplicationContext} from "context"; import {readShellEntityFromJson} from "./scene/wrappers/entityIO"; -import {DEG_RAD} from "math/commons"; import {DEFLECTION, E0_TOLERANCE} from "./craft/e0/common"; import {readBrep, writeBrep} from "brep/io/brepIO"; import {PRIMITIVE_TYPES} from "engine/data/primitiveData"; import {pullFace} from "brep/operations/directMod/pullFace"; -import {Shell} from "brep/topo/shell"; -import { testVertexMoving } from 'brep/operations/directMod/vertexMoving'; -import {DefeatureWizard} from "./craft/defeature/DefeatureWizard"; +import {DefeatureFaceWizard} from "./craft/defeature/DefeatureFaceWizard"; +import {defeatureByVertex} from "brep/operations/directMod/defeaturing"; +import {testVertexMoving} from "brep/operations/directMod/vertexMoving"; export function runSandbox(ctx: ApplicationContext) { @@ -212,10 +210,26 @@ export function runSandbox(ctx: ApplicationContext) { - ctx.domService.contributeComponent(DefeatureWizard); + ctx.domService.contributeComponent(DefeatureFaceWizard); } + function testRemoveVertex() { + + const boxData = ctx.craftEngine.modellingEngine.loadModel(writeBrep(exposure.brep.primitives.box(500, 500, 500))); + const box = readShellEntityFromJson(boxData); + services.exposure.addOnScene(box); + box.vertices.forEach(v => v.ext.view.rootGroup.sphere.onMouseClick = () => { + ctx.craftService.models$.update((models) => { + const [cube] = models; + const result = defeatureByVertex(cube.brepShell, v.brepVertex, ctx.craftEngine.modellingEngine); + const mShell = readShellEntityFromJson(result); + return [mShell]; + }); + }); + } + + function test5() { const degree = 3 @@ -568,7 +582,8 @@ export function runSandbox(ctx: ApplicationContext) { // testVertexMoving(ctx); // test4(); // testSplitFace(); - testRemoveFaces(); + // testRemoveFaces(); + testRemoveVertex(); } });