@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
137 lines (136 loc) • 5.01 kB
JavaScript
;
import { TypedSopNode } from "./_Base";
import {
BufferAttribute,
BufferGeometry,
Vector3,
Points,
LineSegments,
PointsMaterial,
LineBasicMaterial
} from "three";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { InputCloneMode } from "../../poly/InputCloneMode";
import { triangleBasicGraphFromGeometry } from "../../../core/geometry/modules/three/graph/triangleBasic/TriangleBasicGraphUtils";
const _v3 = new Vector3();
class ManifoldTestSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
this.replaceGeo = ParamConfig.BOOLEAN(false);
}
}
const ParamsConfig = new ManifoldTestSopParamsConfig();
export class ManifoldTestSopNode extends TypedSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
}
static type() {
return "manifoldTest";
}
initializeNode() {
this.io.inputs.setCount(1);
this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE);
}
cook(inputCoreGroups) {
const inputCoreGroup = inputCoreGroups[0];
const selectedObjects = inputCoreGroup.threejsObjectsWithGeo();
if (this.pv.replaceGeo == true) {
const newObjects = [];
for (const object of selectedObjects) {
const newMeshes = this._filterMesh(object);
if (newMeshes) {
newObjects.push(...newMeshes);
}
}
this.setObjects(newObjects);
} else {
for (const object of selectedObjects) {
this._filterMesh(object);
}
this.setCoreGroup(inputCoreGroup);
}
}
_filterMesh(object) {
const graph = triangleBasicGraphFromGeometry(object.geometry);
const edgeIds = [];
console.log({ edgeIds: edgeIds.length });
const unsharedEdgeIds = /* @__PURE__ */ new Set();
const overusedEdgeIds = /* @__PURE__ */ new Set();
graph.forNonManifoldEdge((edge, edgeId) => {
if (edge.triangleIds.length == 1) {
unsharedEdgeIds.add(edgeId);
} else if (edge.triangleIds.length > 2) {
overusedEdgeIds.add(edgeId);
} else {
}
});
if (unsharedEdgeIds.size > 0 || overusedEdgeIds.size > 0) {
const currentPositions = object.geometry.getAttribute("position").array;
const objects = [];
if (unsharedEdgeIds.size > 0) {
console.error(
`${this.path()}: unshared edges found: ${unsharedEdgeIds.size} (total edges count:${graph.edgesCount()})`
);
const points = createPointsFromEdges(graph, unsharedEdgeIds, currentPositions, 16711680);
const lineSegments = createLineSegmentsFromEdges(graph, unsharedEdgeIds, currentPositions, 255);
objects.push(points);
objects.push(lineSegments);
}
if (overusedEdgeIds.size > 0) {
console.error(
`${this.path()}: overused edges found: ${overusedEdgeIds.size} (total edges count:${graph.edgesCount()})`
);
const points = createPointsFromEdges(graph, overusedEdgeIds, currentPositions, 16729156);
const lineSegments = createLineSegmentsFromEdges(graph, overusedEdgeIds, currentPositions, 4474111);
objects.push(points);
objects.push(lineSegments);
}
return objects;
}
}
}
function createPointsFromEdges(graph, edgeIds, currentPositions, color) {
const geometry = new BufferGeometry();
const points = new Points(geometry, new PointsMaterial({ color, size: 0.25 }));
const positions = [];
const indices = [];
let newPointsCount = 0;
edgeIds.forEach((edgeId) => {
const edge = graph.edgeById(edgeId);
_v3.fromArray(currentPositions, edge.pointIdPair.id0 * 3);
_v3.toArray(positions, newPointsCount * 3);
indices.push(newPointsCount);
newPointsCount++;
_v3.fromArray(currentPositions, edge.pointIdPair.id1 * 3);
_v3.toArray(positions, newPointsCount * 3);
indices.push(newPointsCount);
newPointsCount++;
});
const positionAttribute = new BufferAttribute(new Float32Array(positions), 3);
geometry.setAttribute("position", positionAttribute);
geometry.setIndex(indices);
return points;
}
function createLineSegmentsFromEdges(graph, edgeIds, currentPositions, color) {
const geometry = new BufferGeometry();
const lineSegments = new LineSegments(geometry, new LineBasicMaterial({ color, linewidth: 2 }));
const positions = [];
const indices = [];
let newPointsCount = 0;
edgeIds.forEach((edgeId) => {
const edge = graph.edgeById(edgeId);
_v3.fromArray(currentPositions, edge.pointIdPair.id0 * 3);
_v3.toArray(positions, newPointsCount * 3);
indices.push(newPointsCount);
newPointsCount++;
_v3.fromArray(currentPositions, edge.pointIdPair.id1 * 3);
_v3.toArray(positions, newPointsCount * 3);
indices.push(newPointsCount);
newPointsCount++;
});
const positionAttribute = new BufferAttribute(new Float32Array(positions), 3);
geometry.setAttribute("position", positionAttribute);
geometry.setIndex(indices);
return lineSegments;
}