UNPKG

voxel-triangulation

Version:

a library for subdividing voxels into triangles

93 lines (72 loc) 2.78 kB
import { BufferGeometry, BufferAttribute, MeshStandardMaterial, EdgesGeometry, LineBasicMaterial, WireframeGeometry, LineSegments, Mesh, MeshPhongMaterial } from 'three' import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'; import ndarray from 'ndarray' import { product, flatten } from 'ramda' const { random } = Math import triangulateVoxels from '../voxel-triangulation' /* const values = [ 0, 1, 0, 0, 1, 2, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0 ];*/ const componentizedColores = [ [255, 0, 0], [0, 255, 0], [0, 0, 255] ] const loadVoxels = () => { const AMOUNT_OF_VOXEL_VALUES = 3 const SHAPE = [10, 10, 10] const values = new Array(product(SHAPE)).fill(0).map((_, index) => parseInt(random() * (AMOUNT_OF_VOXEL_VALUES + 1))) const voxels = ndarray(values, SHAPE); const config = { exclude: [0] }; let { vertices, normals, indices, voxelValues } = triangulateVoxels(voxels, config); document.querySelector("#statistics").innerHTML = ` ${voxels.shape[0]}&times;${voxels.shape[1]}&times;${voxels.shape[2]} voxels <br> ${vertices.length} vertices <br> ${indices.length / 3} triangles ` let normalizedColors = componentizedColores.map((color) => color.map((c) => c / 255.0)); let alignedColors = [ [0, 0, 0], ...normalizedColors ]; let flattenedColors = flatten(voxelValues.map((v) => alignedColors[v])); let geometry = new BufferGeometry(); geometry.setAttribute('position', new BufferAttribute(new Float32Array(vertices), 3)); geometry.setAttribute('normal', new BufferAttribute(new Float32Array(normals), 3)); geometry.setAttribute('color', new BufferAttribute(new Float32Array(flattenedColors), 3) ); geometry.setIndex(new BufferAttribute(new Uint32Array(indices), 1)); // mesh const material = new MeshPhongMaterial( { color: 0xffffff, polygonOffset: true, polygonOffsetFactor: 1, // positive value pushes polygon further away polygonOffsetUnits: 1 } ); const mesh = new Mesh( geometry, material ); // wireframe const geo = new WireframeGeometry( mesh.geometry ); // or WireframeGeometry const mat = new LineBasicMaterial( { color: 0x000000 } ); const wireframe = new LineSegments( geo, mat ); mesh.add( wireframe ); let exporter = new GLTFExporter(); exporter.parse(mesh, (json) => { let string = JSON.stringify(json); let blob = new Blob([string], { type:'text/plain' }); let url = URL.createObjectURL(blob); let modelViewer = document.querySelector('#model-viewer') modelViewer.src = url; }); } loadVoxels()