mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-08 09:24:18 +01:00
selection for BREP faces
This commit is contained in:
parent
4dde1c4274
commit
e003b7e8dd
5 changed files with 126 additions and 63 deletions
|
|
@ -7,7 +7,7 @@ export const EditFace = {
|
|||
info: 'open sketcher for a face/plane',
|
||||
listens: ['selection'],
|
||||
update: ActionHelpers.checkForSelectedFaces(1),
|
||||
invoke: (app) => app.sketchSelectedFace()
|
||||
invoke: (app) => app.editFace()
|
||||
};
|
||||
|
||||
export const Save = {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ function App() {
|
|||
}
|
||||
|
||||
App.prototype.BREPTest = function() {
|
||||
setTimeout(() => this.BREPTestImpl1());
|
||||
setTimeout(() => this.BREPTestImpl());
|
||||
};
|
||||
|
||||
App.prototype.BREPTestImpl1 = function() {
|
||||
|
|
@ -104,7 +104,8 @@ App.prototype.BREPTestImpl = function() {
|
|||
this.viewer.workGroup.add(sceneSolid.cadGroup);
|
||||
};
|
||||
const box1 = BREPPrimitives.box(500, 500, 500);
|
||||
const box2 = BREPPrimitives.box(250, 250, 500, new Matrix3().translate(25, 25, 250));
|
||||
const box2 = BREPPrimitives.box(250, 250, 750, new Matrix3().translate(25, 25, 0));
|
||||
const box3 = BREPPrimitives.box(150, 600, 350, new Matrix3().translate(25, 25, -250));
|
||||
|
||||
BREPValidator.validateToConsole(box1);
|
||||
|
||||
|
|
@ -113,8 +114,10 @@ App.prototype.BREPTestImpl = function() {
|
|||
|
||||
//addToScene(box1);
|
||||
//addToScene(box2);
|
||||
//addToScene(box3);
|
||||
|
||||
const result = BREPBool.subtract(box1, box2);
|
||||
let result = BREPBool.subtract(box1, box2);
|
||||
result = BREPBool.subtract(result, box3);
|
||||
addToScene(result);
|
||||
|
||||
this.viewer.render()
|
||||
|
|
@ -212,7 +215,7 @@ App.prototype.projectStorageKey = function(polyFaceId) {
|
|||
};
|
||||
|
||||
|
||||
App.prototype.sketchSelectedFace = function() {
|
||||
App.prototype.editFace = function() {
|
||||
if (this.viewer.selectionMgr.selection.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ class AbstractSelectionManager {
|
|||
return this.selection.indexOf(face) != -1;
|
||||
}
|
||||
|
||||
pick(sketchFace) {
|
||||
if (!this.contains(sketchFace)) {
|
||||
this.select(sketchFace);
|
||||
pick(object) {
|
||||
if (!this.contains(object)) {
|
||||
this.select(object);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -77,43 +77,8 @@ export class SelectionManager extends AbstractSelectionManager {
|
|||
this.defaultColor = defaultColor;
|
||||
this.readOnlyColor = readOnlyColor;
|
||||
this.planeSelection = [];
|
||||
|
||||
this.basisGroup = new THREE.Object3D();
|
||||
var length = 200;
|
||||
var arrowLength = length * 0.2;
|
||||
var arrowHead = arrowLength * 0.4;
|
||||
|
||||
function createArrow(axis, color) {
|
||||
var arrow = new THREE.ArrowHelper(axis, new THREE.Vector3(0, 0, 0), length, color, arrowLength, arrowHead);
|
||||
arrow.updateMatrix();
|
||||
arrow.matrixAutoUpdate = false;
|
||||
arrow.line.renderOrder = 1e11;
|
||||
arrow.cone.renderOrder = 1e11;
|
||||
arrow.line.material.linewidth = 1/DPR;
|
||||
arrow.line.material.depthWrite = false;
|
||||
arrow.line.material.depthTest = false;
|
||||
arrow.cone.material.depthWrite = false;
|
||||
arrow.cone.material.depthTest = false;
|
||||
return arrow;
|
||||
}
|
||||
|
||||
var xAxis = createArrow(new THREE.Vector3(1, 0, 0), 0xFF0000);
|
||||
var yAxis = createArrow(new THREE.Vector3(0, 1, 0), 0x00FF00);
|
||||
this.basisGroup.add(xAxis);
|
||||
this.basisGroup.add(yAxis);
|
||||
}
|
||||
|
||||
updateBasis(basis, depth) {
|
||||
this.basisGroup.matrix.identity();
|
||||
var mx = new THREE.Matrix4();
|
||||
mx.makeBasis(basis[0].three(), basis[1].three(), basis[2].three());
|
||||
var depthOff = new THREE.Vector3(0, 0, depth);
|
||||
depthOff.applyMatrix4(mx);
|
||||
mx.setPosition(depthOff);
|
||||
this.basisGroup.applyMatrix(mx);
|
||||
}
|
||||
|
||||
|
||||
select(sketchFace) {
|
||||
this.clear();
|
||||
if (sketchFace.curvedSurfaces !== null) {
|
||||
|
|
@ -124,8 +89,8 @@ export class SelectionManager extends AbstractSelectionManager {
|
|||
}
|
||||
} else {
|
||||
this.selection.push(sketchFace);
|
||||
this.updateBasis(sketchFace.basis(), sketchFace.depth());
|
||||
sketchFace.solid.cadGroup.add(this.basisGroup);
|
||||
this.viewer.updateBasis(sketchFace.basis(), sketchFace.depth());
|
||||
this.viewer.showBasis();
|
||||
setFacesColor(sketchFace.faces, this.selectionColor);
|
||||
}
|
||||
sketchFace.solid.mesh.geometry.colorsNeedUpdate = true;
|
||||
|
|
@ -144,11 +109,47 @@ export class SelectionManager extends AbstractSelectionManager {
|
|||
setFacesColor(selectee.faces, this.defaultColor);
|
||||
selectee.solid.mesh.geometry.colorsNeedUpdate = true;
|
||||
}
|
||||
if (this.basisGroup.parent !== null ) this.basisGroup.parent.remove( this.basisGroup );
|
||||
this.viewer.hideBasis();
|
||||
this.selection.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
export class BREPFaceSelectionManager extends AbstractSelectionManager {
|
||||
|
||||
constructor(viewer, selectionColor, readOnlyColor, defaultColor) {
|
||||
super(viewer);
|
||||
this.selectionColor = selectionColor;
|
||||
this.defaultColor = defaultColor;
|
||||
this.readOnlyColor = readOnlyColor;
|
||||
}
|
||||
|
||||
select(face) {
|
||||
this.clear();
|
||||
this.selection.push(face);
|
||||
setFacesColor(face.meshFaces, this.selectionColor);
|
||||
|
||||
face.solid.mesh.geometry.colorsNeedUpdate = true;
|
||||
this.viewer.bus.notify('selection', face);
|
||||
this.viewer.render();
|
||||
}
|
||||
|
||||
deselectAll() {
|
||||
this.clear();
|
||||
this.viewer.bus.notify('selection', null);
|
||||
this.viewer.render();
|
||||
}
|
||||
|
||||
clear() {
|
||||
for (let selectee of this.selection) {
|
||||
setFacesColor(selectee.meshFaces, this.defaultColor);
|
||||
selectee.solid.mesh.geometry.colorsNeedUpdate = true;
|
||||
}
|
||||
this.viewer.hideBasis();
|
||||
this.selection.length = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function setFacesColor(faces, color) {
|
||||
for (let face of faces) {
|
||||
if (color == null) {
|
||||
|
|
@ -158,4 +159,3 @@ function setFacesColor(faces, color) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import * as cad_utils from './cad-utils'
|
|||
import {Matrix3, AXIS, ORIGIN} from '../math/l3space'
|
||||
import DPR from '../utils/dpr'
|
||||
import * as mask from '../utils/mask';
|
||||
import {SelectionManager, SketchSelectionManager} from './selection'
|
||||
import {SelectionManager, BREPFaceSelectionManager, SketchSelectionManager} from './selection'
|
||||
|
||||
function Viewer(bus, container) {
|
||||
this.bus = bus;
|
||||
|
|
@ -92,7 +92,9 @@ function Viewer(bus, container) {
|
|||
|
||||
this.workGroup = new THREE.Object3D();
|
||||
this.scene.add(this.workGroup);
|
||||
this.createBasisGroup();
|
||||
this.selectionMgr = new SelectionManager( this, 0xFAFAD2, 0xFF0000, null);
|
||||
this.brepSelectionMgr = new BREPFaceSelectionManager( this, 0xFAFAD2, 0xFF0000, null);
|
||||
this.sketchSelectionMgr = new SketchSelectionManager( this, new THREE.LineBasicMaterial({color: 0xFF0000, linewidth: 6/DPR}));
|
||||
var viewer = this;
|
||||
|
||||
|
|
@ -159,6 +161,53 @@ function Viewer(bus, container) {
|
|||
this.animate();
|
||||
}
|
||||
|
||||
Viewer.prototype.createBasisGroup = function() {
|
||||
this.basisGroup = new THREE.Object3D();
|
||||
var length = 200;
|
||||
var arrowLength = length * 0.2;
|
||||
var arrowHead = arrowLength * 0.4;
|
||||
|
||||
function createArrow(axis, color) {
|
||||
var arrow = new THREE.ArrowHelper(axis, new THREE.Vector3(0, 0, 0), length, color, arrowLength, arrowHead);
|
||||
arrow.updateMatrix();
|
||||
arrow.matrixAutoUpdate = false;
|
||||
arrow.line.renderOrder = 1e11;
|
||||
arrow.cone.renderOrder = 1e11;
|
||||
arrow.line.material.linewidth = 1/DPR;
|
||||
arrow.line.material.depthWrite = false;
|
||||
arrow.line.material.depthTest = false;
|
||||
arrow.cone.material.depthWrite = false;
|
||||
arrow.cone.material.depthTest = false;
|
||||
return arrow;
|
||||
}
|
||||
|
||||
var xAxis = createArrow(new THREE.Vector3(1, 0, 0), 0xFF0000);
|
||||
var yAxis = createArrow(new THREE.Vector3(0, 1, 0), 0x00FF00);
|
||||
this.basisGroup.add(xAxis);
|
||||
this.basisGroup.add(yAxis);
|
||||
};
|
||||
|
||||
Viewer.prototype.updateBasis = function(basis, depth){
|
||||
this.basisGroup.matrix.identity();
|
||||
var mx = new THREE.Matrix4();
|
||||
mx.makeBasis(basis[0].three(), basis[1].three(), basis[2].three());
|
||||
var depthOff = new THREE.Vector3(0, 0, depth);
|
||||
depthOff.applyMatrix4(mx);
|
||||
mx.setPosition(depthOff);
|
||||
this.basisGroup.applyMatrix(mx);
|
||||
};
|
||||
|
||||
Viewer.prototype.showBasis = function(){
|
||||
this.workGroup.add(this.basisGroup);
|
||||
};
|
||||
|
||||
Viewer.prototype.hideBasis = function(){
|
||||
if (this.basisGroup.parent !== null ) {
|
||||
this.basisGroup.parent.remove( this.basisGroup );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Viewer.prototype.lookAt = function(obj) {
|
||||
var box = new THREE.Box3();
|
||||
box.setFromObject(obj);
|
||||
|
|
@ -189,7 +238,9 @@ export const PICK_KIND = {
|
|||
FACE: mask.type(1),
|
||||
SKETCH: mask.type(2),
|
||||
EDGE: mask.type(3),
|
||||
VERTEX: mask.type(4)
|
||||
VERTEX: mask.type(4),
|
||||
TOPO_FACE: mask.type(5),
|
||||
TOPO_EDGE: mask.type(6)
|
||||
};
|
||||
|
||||
Viewer.prototype.raycastObjects = function(event, kind, visitor) {
|
||||
|
|
@ -206,12 +257,20 @@ Viewer.prototype.raycastObjects = function(event, kind, visitor) {
|
|||
if (!visitor(pickResult.object, PICK_KIND.SKETCH)) {
|
||||
break;
|
||||
}
|
||||
} else if (mask.is(kind, PICK_KIND.TOPO_FACE) && !!pickResult.face && pickResult.face.__TCAD_TOPO) {
|
||||
if (!visitor(pickResult.face.__TCAD_TOPO, PICK_KIND.TOPO_FACE)) {
|
||||
break;
|
||||
}
|
||||
} else if (mask.is(kind, PICK_KIND.TOPO_EDGE) && pickResult.object instanceof THREE.Line && pickResult.object.__TCAD_TOPO) {
|
||||
if (!visitor(pickResult.object.__TCAD_TOPO, PICK_KIND.TOPO_EDGE)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Viewer.prototype.handlePick = function(event) {
|
||||
this.raycastObjects(event, PICK_KIND.FACE | PICK_KIND.SKETCH, (object, kind) => {
|
||||
this.raycastObjects(event, PICK_KIND.FACE | PICK_KIND.SKETCH | PICK_KIND.TOPO_FACE | PICK_KIND.TOPO_EDGE, (object, kind) => {
|
||||
if (kind == PICK_KIND.FACE) {
|
||||
if (this.selectionMgr.pick(object)) {
|
||||
return false;
|
||||
|
|
@ -220,6 +279,10 @@ Viewer.prototype.handlePick = function(event) {
|
|||
if (this.sketchSelectionMgr.pick(object)) {
|
||||
return false;
|
||||
}
|
||||
} else if (kind == PICK_KIND.TOPO_FACE) {
|
||||
this.brepSelectionMgr.select(object);
|
||||
} else if (kind == PICK_KIND.TOPO_EDGE) {
|
||||
//this.brepSelectionMgr.selectEdge(object);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export class SceneSolid {
|
|||
this.mesh = new THREE.Mesh(geometry, createSolidMaterial());
|
||||
this.cadGroup.add(this.mesh);
|
||||
|
||||
this.polyFaces = [];
|
||||
this.sceneFaces = [];
|
||||
this.createFaces();
|
||||
this.createEdges();
|
||||
this.createVertices();
|
||||
|
|
@ -27,8 +27,8 @@ export class SceneSolid {
|
|||
let gIdx = 0;
|
||||
const geom = this.mesh.geometry;
|
||||
for (let brepFace of this.shell.faces) {
|
||||
const polyFace = new SceneFace(brepFace);
|
||||
this.polyFaces.push(polyFace);
|
||||
const sceneFace = new SceneFace(brepFace, this);
|
||||
this.sceneFaces.push(sceneFace);
|
||||
const polygons = triangulate(brepFace);
|
||||
for (let p = 0; p < polygons.length; ++p) {
|
||||
const poly = polygons[p];
|
||||
|
|
@ -45,20 +45,16 @@ export class SceneSolid {
|
|||
const b = i - 1 + off;
|
||||
const c = i + off;
|
||||
const face = new THREE.Face3(a, b, c);
|
||||
polyFace.faces.push(face);
|
||||
face.__TCAD_polyFace = polyFace;
|
||||
sceneFace.meshFaces.push(face);
|
||||
face.__TCAD_TOPO = sceneFace;
|
||||
face.normal = normal;
|
||||
face.materialIndex = gIdx ++;
|
||||
geom.faces.push(face);
|
||||
if (brepFace.debugName == 'base') {
|
||||
face.color.set(new THREE.Color().setHex( 0x000077 ));
|
||||
}
|
||||
if (brepFace.debugName == 'wall_3') {
|
||||
face.color.set(new THREE.Color().setHex( 0x007700 ));
|
||||
}
|
||||
|
||||
}
|
||||
//view.setFaceColor(polyFace, utils.isSmoothPiece(group.shared) ? 0xFF0000 : null);
|
||||
//view.setFaceColor(sceneFace, utils.isSmoothPiece(group.shared) ? 0xFF0000 : null);
|
||||
off = geom.vertices.length;
|
||||
}
|
||||
}
|
||||
|
|
@ -71,7 +67,7 @@ export class SceneSolid {
|
|||
for (let halfEdge of face.outerLoop.halfEdges) {
|
||||
if (!visited.has(halfEdge.edge)) {
|
||||
visited.add(halfEdge.edge);
|
||||
this.addLineToScene(halfEdge.vertexA.point, halfEdge.vertexB.point, halfEdge.edge);
|
||||
this.addLineToScene(halfEdge.vertexA.point.three(), halfEdge.vertexB.point.three(), halfEdge.edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,9 +92,10 @@ const WIREFRAME_MATERIAL = new THREE.LineBasicMaterial({color: 0xff0000, linewid
|
|||
|
||||
|
||||
class SceneFace {
|
||||
constructor(brepFace) {
|
||||
constructor(brepFace, solid) {
|
||||
this.solid = solid;
|
||||
this.brepFace = brepFace;
|
||||
this.faces = [];
|
||||
this.meshFaces = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue