@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
181 lines (180 loc) • 5.99 kB
JavaScript
"use strict";
import { TetSopNode } from "./_BaseTet";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { SopType } from "../../poly/registers/nodes/types/Sop";
import { stringToIndices } from "../../../core/String";
import { isBooleanTrue } from "../../../core/Type";
import { Vector3 } from "three";
import { tetCenter } from "../../../core/geometry/modules/tet/utils/tetCenter";
import { isPositionInsideMesh } from "../../../core/geometry/modules/tet/utils/tetInsideMesh";
import { ThreeMeshBVHHelper } from "../../../core/geometry/bvh/ThreeMeshBVHHelper";
import { findNonDelaunayTetsFromMultiplePointsCheck } from "../../../core/geometry/modules/tet/utils/findNonDelaunayTets";
import { tetRemoveUnusedPoints } from "../../../core/geometry/modules/tet/utils/tetRemoveUnusedPoints";
import { tetQuality } from "../../../core/geometry/modules/tet/utils/tetQuality";
import { arrayPushItems } from "../../../core/ArrayUtils";
const _tetCenter = new Vector3();
const _indices = [];
class TetDeleteSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
this.byQuality = ParamConfig.BOOLEAN(0);
this.minQuality = ParamConfig.FLOAT(0.5, {
range: [0, 1],
rangeLocked: [true, true],
visibleIf: { byQuality: 1 }
});
this.byIds = ParamConfig.BOOLEAN(0, {
separatorBefore: true
});
this.ids = ParamConfig.STRING("0", {
visibleIf: { byIds: 1 }
});
this.byIndex = ParamConfig.BOOLEAN(0, {
separatorBefore: true
});
this.index = ParamConfig.INTEGER(-1, {
range: [0, 100],
rangeLocked: [true, false],
visibleIf: { byIndex: 1 }
});
this.byIndexRange = ParamConfig.BOOLEAN(0, {
separatorBefore: true
});
this.indexRangeStart = ParamConfig.INTEGER(0, {
range: [0, 2e3],
rangeLocked: [true, false],
visibleIf: { byIndexRange: 1 }
});
this.indexRangeEnd = ParamConfig.INTEGER(2e3, {
range: [0, 2e3],
rangeLocked: [true, false],
visibleIf: { byIndexRange: 1 }
});
this.byDelaunay = ParamConfig.BOOLEAN(0, {
separatorBefore: true
});
this.byBoundingObject = ParamConfig.BOOLEAN(0, {
separatorBefore: true
});
this.invert = ParamConfig.BOOLEAN(0, {
separatorBefore: true
});
}
}
const ParamsConfig = new TetDeleteSopParamsConfig();
export class TetDeleteSopNode extends TetSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
}
static type() {
return SopType.TET_DELETE;
}
initializeNode() {
this.io.inputs.setCount(1, 2);
}
async cook(inputCoreGroups) {
const tetObjects = inputCoreGroups[0].tetObjects();
if (tetObjects) {
for (const tetObject of tetObjects) {
this._deleteTets(tetObject, inputCoreGroups);
}
this.setObjects(tetObjects);
} else {
this.setObjects([]);
}
}
_deleteTets(tetObject, inputCoreGroups) {
var _a;
const selectedIds = [];
if (isBooleanTrue(this.pv.byQuality)) {
this._findTetsByQuality(tetObject, selectedIds);
}
if (isBooleanTrue(this.pv.byIds)) {
this._findTetsById(selectedIds);
}
if (isBooleanTrue(this.pv.byIndex)) {
this._findTetsByIndex(tetObject, selectedIds);
}
if (isBooleanTrue(this.pv.byIndexRange)) {
this._findTetsByIndexRange(tetObject, selectedIds);
}
if (isBooleanTrue(this.pv.byDelaunay)) {
this._findTetsByDelaunay(tetObject, selectedIds);
}
if (isBooleanTrue(this.pv.byBoundingObject)) {
const boundingObject = (_a = inputCoreGroups[1]) == null ? void 0 : _a.threejsObjectsWithGeo()[0];
if (boundingObject) {
this._findTetsByBoundingObject(tetObject, boundingObject, selectedIds);
}
}
if (isBooleanTrue(this.pv.invert)) {
const nonSelectedIds = [];
const selectedIdsSet = new Set(selectedIds);
tetObject.geometry.tetrahedrons.forEach((_, tetId) => {
if (!selectedIdsSet.has(tetId)) {
nonSelectedIds.push(tetId);
}
});
tetObject.geometry.removeTets(nonSelectedIds);
} else {
tetObject.geometry.removeTets(selectedIds);
}
tetRemoveUnusedPoints(tetObject.geometry);
}
_findTetsByQuality(tetObject, selectedIds) {
tetObject.geometry.tetrahedrons.forEach((_, tetId) => {
if (tetQuality(tetObject.geometry, tetId) < this.pv.minQuality) {
selectedIds.push(tetId);
}
});
}
_findTetsById(selectedIds) {
stringToIndices(this.pv.ids, _indices);
arrayPushItems(_indices, selectedIds);
}
_findTetsByIndex(tetObject, selectedIds) {
const index = this.pv.index;
if (index == -1) {
const lastId = tetObject.geometry.lastAddedTetId();
if (lastId != null) {
selectedIds.push(lastId);
}
} else {
let i = 0;
tetObject.geometry.tetrahedrons.forEach((_, tetId) => {
if (i == index) {
selectedIds.push(tetId);
}
i++;
});
}
}
_findTetsByIndexRange(tetObject, selectedIds) {
const min = this.pv.indexRangeStart;
const max = this.pv.indexRangeEnd;
let i = 0;
tetObject.geometry.tetrahedrons.forEach((_, tetId) => {
if (i >= min && i <= max) {
selectedIds.push(tetId);
}
i++;
});
}
_findTetsByDelaunay(tetObject, selectedIds) {
const invalidTets = [];
findNonDelaunayTetsFromMultiplePointsCheck(tetObject.geometry, invalidTets);
selectedIds.push(...invalidTets);
}
_findTetsByBoundingObject(tetObject, boundingObject, selectedIds) {
ThreeMeshBVHHelper.assignDefaultBVHIfNone(boundingObject);
const tetGeometry = tetObject.geometry;
tetGeometry.tetrahedrons.forEach((_, tetId) => {
tetCenter(tetGeometry, tetId, _tetCenter);
const isInside = isPositionInsideMesh(_tetCenter, boundingObject, 1e-3);
if (isInside) {
selectedIds.push(tetId);
}
});
}
}