mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 16:33:15 +01:00
221 lines
6.5 KiB
JavaScript
221 lines
6.5 KiB
JavaScript
import {checkForSelectedFaces} from './actions/action-helpers'
|
|
import {triangulateToThree} from './scene/brep-scene-object'
|
|
import {createSolidMaterial} from './scene/scene-object'
|
|
import DPR from '../utils/dpr'
|
|
|
|
export const DEBUG = true;
|
|
|
|
export function AddDebugSupport(app) {
|
|
if (!DEBUG) return;
|
|
app.actionManager.registerActions(DebugActions);
|
|
app.ui.registerMenuActions(DebugMenuConfig);
|
|
app.controlBar.add('menu.debug', true);
|
|
addGlobalDebugActions(app);
|
|
}
|
|
|
|
function addGlobalDebugActions(app) {
|
|
const debugGroup = new THREE.Object3D();
|
|
const debugVolumeGroup = new THREE.Object3D();
|
|
app.viewer.workGroup.add(debugGroup);
|
|
app.viewer.workGroup.add(debugVolumeGroup);
|
|
window.__DEBUG__ = {
|
|
AddLine: (a, b) => {
|
|
debugGroup.add(createLine(a, b));
|
|
app.viewer.render();
|
|
},
|
|
AddSegment: (a, b, color) => {
|
|
__DEBUG__.AddPolyLine([a, b], color);
|
|
},
|
|
AddPolyLine: (points, color) => {
|
|
for (let i = 1; i < points.length; ++i) {
|
|
debugGroup.add(createLine(points[i - 1], points[i], color));
|
|
}
|
|
debugGroup.add(createPoint(points[0], 0x000088));
|
|
debugGroup.add(createPoint(points[points.length - 1], 0x880000));
|
|
app.viewer.render();
|
|
},
|
|
AddPoint: (coordinates, or, vector, andColorAtTheEnd) => {
|
|
debugGroup.add(createPoint(coordinates, or, vector, andColorAtTheEnd));
|
|
app.viewer.render();
|
|
},
|
|
AddVertex: (v) => {
|
|
window.__DEBUG__.AddPoint(v.point);
|
|
},
|
|
AddPolygon: (vertices, color) => {
|
|
for (let i = 0; i < vertices.length; i ++) {
|
|
__DEBUG__.AddSegment(vertices[i].point, vertices[(i + 1) % vertices.length].point, color);
|
|
}
|
|
},
|
|
AddPlane: (plane) => {
|
|
const geo = new THREE.PlaneBufferGeometry(2000, 2000, 8, 8);
|
|
const coplanarPoint = plane.normal.multiply(plane.w);
|
|
const focalPoint = coplanarPoint.plus(plane.normal);
|
|
geo.lookAt(focalPoint.three());
|
|
geo.translate(coplanarPoint.x, coplanarPoint.y, coplanarPoint.z);
|
|
const mat = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide,
|
|
transparent: true,
|
|
opacity: 0.3, });
|
|
const planeObj = new THREE.Mesh(geo, mat);
|
|
debugGroup.add(planeObj);
|
|
app.viewer.render();
|
|
},
|
|
AddHalfEdge: (he, color) => {
|
|
const points = [he.vertexA.point];
|
|
if (he.edge && he.edge.curve) {
|
|
he.edge.curve.approximate(10, he.vertexA.point, he.vertexB.point, points);
|
|
}
|
|
points.push(he.vertexB.point);
|
|
window.__DEBUG__.AddPolyLine(points, color);
|
|
},
|
|
AddFace: (face, color) => {
|
|
for (let e of face.edges) __DEBUG__.AddHalfEdge(e, color);
|
|
},
|
|
AddVolume: (shell, color) => {
|
|
color = color || 0xffffff;
|
|
const geometry = new THREE.Geometry();
|
|
triangulateToThree(shell, geometry);
|
|
const mesh = new THREE.Mesh(geometry, createSolidMaterial({
|
|
color,
|
|
transparent: true,
|
|
opacity: 0.5,
|
|
}));
|
|
debugVolumeGroup.add(mesh);
|
|
window.__DEBUG__.AddWireframe(shell, color);
|
|
app.viewer.render();
|
|
},
|
|
AddWireframe: (shell, color) => {
|
|
color = color || 0xffffff;
|
|
const visited = new Set();
|
|
for (let e of shell.edges) {
|
|
var lg = new THREE.Geometry();
|
|
lg.vertices.push(e.halfEdge1.vertexA.point.three());
|
|
lg.vertices.push(e.halfEdge2.vertexA.point.three());
|
|
const line = new THREE.Line(lg, new THREE.LineBasicMaterial({color, linewidth: 3/DPR}));
|
|
debugVolumeGroup.add(line);
|
|
}
|
|
app.viewer.render();
|
|
},
|
|
HideSolids: () => {
|
|
app.findAllSolidsOnScene().forEach(s => s.cadGroup.traverse(o => o.visible = false));
|
|
app.viewer.render();
|
|
},
|
|
Clear: () => {
|
|
clearGroup(debugGroup);
|
|
app.viewer.render();
|
|
},
|
|
ClearVolumes: () => {
|
|
clearGroup(debugVolumeGroup);
|
|
app.viewer.render();
|
|
}
|
|
}
|
|
}
|
|
|
|
function clearGroup(g) {
|
|
while (g.children.length) {
|
|
const o = g.children[0];
|
|
o.material.dispose();
|
|
o.geometry.dispose();
|
|
g.remove(o);
|
|
}
|
|
}
|
|
|
|
function createLine(a, b, color) {
|
|
color = color || 0xFA8072;
|
|
const debugLineMaterial = new THREE.LineBasicMaterial({color, linewidth: 10});
|
|
const lg = new THREE.Geometry();
|
|
lg.vertices.push(a.three());
|
|
lg.vertices.push(b.three());
|
|
return new THREE.Line(lg, debugLineMaterial);
|
|
}
|
|
|
|
function createPoint(x, y, z, color) {
|
|
if (!z) {
|
|
color = y;
|
|
y = x.y;
|
|
z = x.z;
|
|
x = x.x;
|
|
}
|
|
color = color || 0x00ff00;
|
|
var geometry = new THREE.SphereGeometry( 5, 16, 16 );
|
|
var material = new THREE.MeshBasicMaterial( {color} );
|
|
var sphere = new THREE.Mesh(geometry, material);
|
|
sphere.position.x = x;
|
|
sphere.position.y = y;
|
|
sphere.position.z = z;
|
|
return sphere;
|
|
}
|
|
|
|
const DebugMenuConfig = {
|
|
debug: {
|
|
label: 'debug',
|
|
cssIcons: ['bug'],
|
|
info: 'set of debug actions',
|
|
actions: [ 'DebugPrintAllSolids', 'DebugPrintFace', 'DebugFaceId', 'DebugFaceSketch']
|
|
}
|
|
};
|
|
|
|
const DebugActions = {
|
|
'DebugPrintAllSolids': {
|
|
cssIcons: ['cutlery'],
|
|
label: 'print all solids',
|
|
info: 'print all solids from the proejct as JSON',
|
|
invoke: (app) => {
|
|
app.findAllSolids().map(function (o) {
|
|
console.log("Solid ID: " + o.tCadId);
|
|
console.log(JSON.stringify(o.csg));
|
|
});
|
|
}
|
|
},
|
|
|
|
'DebugPrintFace': {
|
|
cssIcons: ['cutlery'],
|
|
label: 'print face',
|
|
info: 'print a face out as JSON',
|
|
listens: ['selection'],
|
|
update: checkForSelectedFaces(1),
|
|
invoke: (app) => {
|
|
var s = app.viewer.selectionMgr.selection[0];
|
|
console.log(JSON.stringify({
|
|
polygons: s.csgGroup.polygons,
|
|
basis: s._basis
|
|
}));
|
|
}
|
|
},
|
|
|
|
'DebugFaceId': {
|
|
cssIcons: ['cutlery'],
|
|
label: 'print face id',
|
|
info: 'print a face id',
|
|
listens: ['selection'],
|
|
update: checkForSelectedFaces(1),
|
|
invoke: (app) => {
|
|
console.log(app.viewer.selectionMgr.selection[0].id);
|
|
}
|
|
},
|
|
|
|
'DebugFaceSketch': {
|
|
cssIcons: ['cutlery'],
|
|
label: 'print face sketch',
|
|
info: 'print face sketch stripping constraints and boundary',
|
|
listens: ['selection'],
|
|
update: checkForSelectedFaces(1),
|
|
invoke: (app) => {
|
|
const faceId = app.viewer.selectionMgr.selection[0].id;
|
|
const sketch = JSON.parse(localStorage.getItem(app.faceStorageKey(faceId)));
|
|
const layers = sketch.layers.filter(l => l.name != '__bounds__');
|
|
const data = [];
|
|
for (let l of layers) {
|
|
for (let d of l.data) {
|
|
data.push(d);
|
|
}
|
|
}
|
|
const squashed = {
|
|
layers: [{
|
|
name: 'sketch',
|
|
data
|
|
}]
|
|
};
|
|
console.log(JSON.stringify(squashed));
|
|
}
|
|
}
|
|
};
|