mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-14 20:33:30 +01:00
improve sketch loop selection/highlights
This commit is contained in:
parent
9af681b21f
commit
5eb5812075
6 changed files with 105 additions and 21 deletions
|
|
@ -174,6 +174,9 @@ export function activate(context) {
|
|||
for (let i = 0; i < pickResults.length; i++) {
|
||||
const pickResult = pickResults[i];
|
||||
for (let picker of pickers) {
|
||||
if (pickResult.object && pickResult.object.passRayCast && pickResult.object.passRayCast(pickResults)) {
|
||||
// continue;
|
||||
}
|
||||
if (picker(pickResult)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import {state} from 'lstream';
|
|||
|
||||
import {addToListInMap} from 'gems/iterables';
|
||||
import {EMPTY_ARRAY} from '../../../../modules/gems/iterables';
|
||||
import {DATUM, FACE, SHELL, SKETCH_OBJECT, EDGE} from './entites';
|
||||
import {DATUM, FACE, SHELL, SKETCH_OBJECT, EDGE, LOOP} from './entites';
|
||||
|
||||
export const SELECTABLE_ENTITIES = [FACE, EDGE, SKETCH_OBJECT, DATUM, SHELL];
|
||||
|
||||
|
|
@ -34,7 +34,13 @@ export function activate(ctx) {
|
|||
ctx.services.marker.$markedEntities.attach(marked => {
|
||||
let byType = new Map();
|
||||
marked.forEach((obj) => {
|
||||
addToListInMap(byType, obj.TYPE, obj);
|
||||
if (obj.TYPE === LOOP) {
|
||||
if (byType[FACE] && !byType[FACE].includes(obj.face)) {
|
||||
addToListInMap(byType, FACE, obj.face);
|
||||
}
|
||||
} else {
|
||||
addToListInMap(byType, obj.TYPE, obj);
|
||||
}
|
||||
});
|
||||
SELECTABLE_ENTITIES.forEach(entityType => {
|
||||
let entities = byType.get(entityType);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {setAttribute} from '../../../../../modules/scene/objectData';
|
|||
import {FACE, SHELL} from '../entites';
|
||||
import {NULL_COLOR, SELECTION_COLOR, setFacesColor, SketchingView} from './faceView';
|
||||
import {View} from './view';
|
||||
import {SketchMesh} from './shellView';
|
||||
|
||||
export class OpenFaceShellView extends View {
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ export class OpenFaceView extends SketchingView {
|
|||
geometry.faces.push(new THREE.Face3(0, 2, 3));
|
||||
geometry.faces.forEach(f => setAttribute(f, FACE, this));
|
||||
geometry.computeFaceNormals();
|
||||
this.mesh = new THREE.Mesh(geometry, this.material);
|
||||
this.mesh = new SketchMesh(geometry, this.material);
|
||||
this.rootGroup.add(this.mesh);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import {View} from './view';
|
||||
import * as SceneGraph from '../../../../../modules/scene/sceneGraph';
|
||||
import {setAttribute} from '../../../../../modules/scene/objectData';
|
||||
import {getAttribute, setAttribute} from '../../../../../modules/scene/objectData';
|
||||
import {createSolidMaterial} from '../wrappers/sceneObject';
|
||||
import {FaceView, SELECTION_COLOR} from './faceView';
|
||||
import {EdgeView} from './edgeView';
|
||||
import {SHELL} from '../entites';
|
||||
import {FACE, SHELL} from '../entites';
|
||||
import {Mesh} from 'three';
|
||||
|
||||
export class ShellView extends View {
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ export class ShellView extends View {
|
|||
|
||||
const geometry = new THREE.Geometry();
|
||||
geometry.dynamic = true;
|
||||
this.mesh = new THREE.Mesh(geometry, this.material);
|
||||
this.mesh = new SketchMesh(geometry, this.material);
|
||||
this.rootGroup.add(this.mesh);
|
||||
|
||||
|
||||
|
|
@ -68,4 +69,30 @@ export class ShellView extends View {
|
|||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class SketchMesh extends Mesh {
|
||||
|
||||
constructor(geometry, material) {
|
||||
super(geometry, material);
|
||||
}
|
||||
|
||||
passRayCast(hits) {
|
||||
for (let hit of hits) {
|
||||
if (hit.object === this && hit.face) {
|
||||
let faceView = getAttribute(hit.face, FACE);
|
||||
if (faceView) {
|
||||
if (faceView.sketchLoopViews.find(v => hits.find(h => v.mesh.geometry.faces.indexOf(h.face) !== -1))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
passMouseEvent(e) {
|
||||
return this.passRayCast(e.hits);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import {View} from './view';
|
||||
import {MarkTracker, View} from './view';
|
||||
import * as SceneGraph from 'scene/sceneGraph';
|
||||
import {tessellateLoopsOnSurface} from '../../tess/brep-tess';
|
||||
import {createSolidMaterial} from '../wrappers/sceneObject';
|
||||
|
|
@ -9,7 +9,7 @@ import Vector from '../../../../../modules/math/vector';
|
|||
import {LOOP} from '../entites';
|
||||
import {setAttribute} from '../../../../../modules/scene/objectData';
|
||||
|
||||
export class SketchLoopView extends View {
|
||||
export class SketchLoopView extends MarkTracker(View) {
|
||||
constructor(mLoop) {
|
||||
super(mLoop);
|
||||
this.rootGroup = SceneGraph.createGroup();
|
||||
|
|
@ -17,11 +17,13 @@ export class SketchLoopView extends View {
|
|||
const geometry = new Geometry();
|
||||
geometry.dynamic = true;
|
||||
this.mesh = new Mesh(geometry, createSolidMaterial({
|
||||
color: 0xDBFFD9,
|
||||
color: SKETCH_LOOP_DEFAULT_HIGHLIGHT_COLOR,
|
||||
side: DoubleSide,
|
||||
// transparent: true,
|
||||
depthTest: true,
|
||||
depthWrite: false,
|
||||
polygonOffset: true,
|
||||
polygonOffsetFactor: 1,
|
||||
polygonOffsetUnits: 0.1,
|
||||
polygonOffsetFactor: -4,
|
||||
visible: false
|
||||
}));
|
||||
let surface = mLoop.face.surface;
|
||||
|
|
@ -44,21 +46,26 @@ export class SketchLoopView extends View {
|
|||
|
||||
this.rootGroup.add(this.mesh);
|
||||
this.mesh.onMouseEnter = (e) => {
|
||||
this.mesh.material.visible = true;
|
||||
this.mark(SKETCH_LOOP_DEFAULT_HIGHLIGHT_COLOR, 5);
|
||||
e.viewer.requestRender();
|
||||
};
|
||||
this.mesh.onMouseLeave = (e) => {
|
||||
this.mesh.material.visible = false;
|
||||
this.withdraw(5);
|
||||
e.viewer.requestRender();
|
||||
};
|
||||
}
|
||||
|
||||
mark(color) {
|
||||
|
||||
mark(color = SKETCH_LOOP_DEFAULT_SELECT_COLOR, priority = 10) {
|
||||
super.mark(color, priority);
|
||||
}
|
||||
|
||||
markImpl(color) {
|
||||
this.mesh.material.visible = true;
|
||||
this.mesh.material.color.setHex(color)
|
||||
}
|
||||
|
||||
withdraw(color) {
|
||||
|
||||
withdrawImpl() {
|
||||
this.mesh.material.visible = false;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
|
@ -66,4 +73,7 @@ export class SketchLoopView extends View {
|
|||
this.mesh.geometry.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SKETCH_LOOP_DEFAULT_HIGHLIGHT_COLOR = 0xDBFFD9;
|
||||
const SKETCH_LOOP_DEFAULT_SELECT_COLOR = 0xCCEFCA;
|
||||
|
|
@ -10,11 +10,10 @@ export class View {
|
|||
setVisible(value) {
|
||||
}
|
||||
|
||||
mark(color) {
|
||||
|
||||
mark(color, priority) {
|
||||
}
|
||||
|
||||
withdraw() {
|
||||
withdraw(priority) {
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
|
@ -23,3 +22,41 @@ export class View {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
export const MarkTracker = ViewClass => class extends ViewClass {
|
||||
|
||||
constructor(model) {
|
||||
super(model);
|
||||
this.marks = new Map();
|
||||
}
|
||||
|
||||
mark(color, priority) {
|
||||
this.marks.set(priority, color);
|
||||
this.doMark();
|
||||
}
|
||||
|
||||
withdraw(priority) {
|
||||
this.marks.delete(priority);
|
||||
this.doMark();
|
||||
}
|
||||
|
||||
doMark() {
|
||||
let keys = this.marks.keys();
|
||||
let maxPriority = - Number.MAX_VALUE;
|
||||
for (let key of keys) {
|
||||
if (key > maxPriority) {
|
||||
maxPriority = key;
|
||||
}
|
||||
}
|
||||
let color = this.marks.get(maxPriority);
|
||||
if (color !== undefined) {
|
||||
this.markImpl(color)
|
||||
} else {
|
||||
this.withdrawImpl(color)
|
||||
}
|
||||
}
|
||||
|
||||
markImpl(color) {}
|
||||
|
||||
withdrawImpl(color) {}
|
||||
};
|
||||
Loading…
Reference in a new issue