UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

109 lines (92 loc) 3.45 kB
/** * Creates polygons between 2 lines * * */ import {BufferGeometry} from 'three'; import {Mesh} from 'three'; import {LineSegments} from 'three'; import {BaseSopNodeType, TypedSopNode} from './_Base'; import {CoreGeometryUtilCurve} from '../../../core/geometry/util/Curve'; import {CoreGeometryOperationSkin} from '../../../core/geometry/operation/Skin'; import {CoreGroup} from '../../../core/geometry/Group'; import {NodeParamsConfig} from '../utils/params/ParamsConfig'; import {arrayCompact, arraySortBy} from '../../../core/ArrayUtils'; import {SopType} from '../../poly/registers/nodes/types/Sop'; class SkinSopParamsConfig extends NodeParamsConfig {} const ParamsConfig = new SkinSopParamsConfig(); export class SkinSopNode extends TypedSopNode<SkinSopParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return SopType.SKIN; } override initializeNode() { this.io.inputs.setCount(1, 2); } override cook(inputCoreGroups: CoreGroup[]) { const inputs = this.io.inputs.inputs() const compactInputs:BaseSopNodeType[]=[] arrayCompact(inputs,compactInputs) const inputsCount = compactInputs.length; switch (inputsCount) { case 1: return this.process_one_input(inputCoreGroups); case 2: return this.process_two_inputs(inputCoreGroups); default: return this.states.error.set('inputs count not valid'); } } process_one_input(input_contents: CoreGroup[]) { const core_group0 = input_contents[0]; const line_segments0 = this._getLineSegments(core_group0); const geometries: BufferGeometry[] = []; if (line_segments0) { const first_line_segment = line_segments0[0] as Mesh; if (first_line_segment) { const src_geometries = CoreGeometryUtilCurve.line_segment_to_geometries(first_line_segment); if (src_geometries) { src_geometries.forEach((src_geometry, i) => { if (i > 0) { const prev_src_geometry = src_geometries[i - 1]; const geometry = this._skin(prev_src_geometry, src_geometry); geometries.push(geometry); } }); } } } this.setGeometries(geometries); } process_two_inputs(input_contents: CoreGroup[]) { const core_group0 = input_contents[0]; const core_group1 = input_contents[1]; const line_segments0 = this._getLineSegments(core_group0); const line_segments1 = this._getLineSegments(core_group1); const line_segments = arraySortBy([line_segments0, line_segments1], (array) => -array.length); const smallest_array = line_segments[0]; const largest_array = line_segments[1]; const geometries: BufferGeometry[] = []; smallest_array.forEach((line_segment, i) => { const other_line_segment = largest_array[i]; if (line_segment != null && other_line_segment != null) { const geo = (line_segment as Mesh).geometry as BufferGeometry; const other_geo = (other_line_segment as Mesh).geometry as BufferGeometry; const geometry = this._skin(geo, other_geo); geometries.push(geometry); } }); this.setGeometries(geometries); } _getLineSegments(core_group: CoreGroup) { return core_group.threejsObjects().filter((child) => (child as LineSegments).isLineSegments); } _skin(geometry1: BufferGeometry, geometry0: BufferGeometry) { // TODO: maybe instead of doing this, const geometry = new BufferGeometry(); const operation = new CoreGeometryOperationSkin(geometry, geometry1, geometry0); operation.process(); return geometry; } }