UNPKG

holes-in

Version:

Generates a 3D mesh from a 2D outer path and 2D inner paths

217 lines (175 loc) 7.79 kB
"use strict"; const holesIn = require("../../lib/index"); const pathHelper = require("../../lib/path-helper") const BABYLON = require("babylonjs"); const debugger3d = { cssclass: "canvas3d", options: {inMesh:true, outMesh:true, frontMesh:true, backMesh:true, horizontalMesh:true, wireframe:false, backFaceCulling:false,normals:false,swapToBabylon:true, displayNormals:false, lengthU: 100, lengthV: 100, enableTexture: "./assets/logo-rasterized.jpg" }, engine: null, scene: null, vertexData: null, camera: null, holes: null, outerShape: null, doNotBuild: null, meshDirty: false, updateMesh(){ const outerShape = debugger3d.outerShape; const holes = debugger3d.holes; if(!debugger3d.meshDirty){return;} if(!holes || !outerShape || !outerShape.path){return;} const cpyOptions = JSON.parse(JSON.stringify(debugger3d.options)); const cpyOut= JSON.parse(JSON.stringify(outerShape)); const cpyHoles= JSON.parse(JSON.stringify(holes)); if(debugger3d.options.doNotBuild) { const val = debugger3d.toClipperString(document.getElementById("doNotBuild").value); debugger3d.pathToEdge(JSON.parse(val)); cpyOptions.doNotBuild = JSON.parse(JSON.stringify(debugger3d.doNotBuild)); pathHelper.scaleUpPath(cpyOptions.doNotBuild); } cpyOptions.mergeVerticalGeometries = false; const geom= holesIn.getGeometry(cpyOut,cpyHoles,cpyOptions); let geomMerged= holesIn.mergeMeshes([geom.frontMesh, geom.backMesh, geom.inMesh, geom.outMesh,geom.horizontalMesh]); let nullMesh= false; if(!geomMerged){ geomMerged={}; geomMerged.points=[]; geomMerged.faces=[]; geomMerged.normals=[]; geomMerged.uvs=[]; nullMesh=true; } debugger3d.meshDirty=false; const vertexData = debugger3d.vertexData; vertexData.positions = geomMerged.points; vertexData.indices = geomMerged.faces; vertexData.normals = geomMerged.normals; vertexData.uvs = geomMerged.uvs; vertexData.applyToMesh(debugger3d.mesh, 1); if(nullMesh){return;} const material = debugger3d.mesh.material; material.wireframe=debugger3d.options.wireframe; material.backFaceCulling=debugger3d.options.backFaceCulling; if(debugger3d.options.enableTexture) { material.ambientTexture = new BABYLON.Texture(debugger3d.options.enableTexture, debugger3d.scene); } else { material.ambientTexture = null; } debugger3d.scene.meshes.filter( mesh => mesh.name === "lines" ).forEach( mesh => mesh.dispose()); if(debugger3d.options.displayNormals){ debugger3d.displayNormals(geomMerged); } debugger3d.updateCamera(); }, updateCamera(){ //updates the camera postion debugger3d.mesh.refreshBoundingInfo(); const boundingSphere = debugger3d.mesh.getBoundingInfo().boundingSphere; const center = boundingSphere.maximum.add(boundingSphere.minimum).scale(0.5); debugger3d.camera.target = center; }, displayNormals(geom){ for(let i=0;i<geom.points.length;i+=3){ const origin = new BABYLON.Vector3(geom.points[i],geom.points[i+1],geom.points[i+2]); const norm = new BABYLON.Vector3(geom.normals[i],geom.normals[i+1],geom.normals[i+2]).scale(5); const dst= origin.add(norm); const lineMesh =new BABYLON.Mesh.CreateLines("lines"+i, [origin ,dst],debugger3d.scene); } }, createScene(engine,canvas) { const camera = new BABYLON.ArcRotateCamera("camera1",0, 0, 200,new BABYLON.Vector3(0,0,0), debugger3d.scene); camera.radius = 200; camera.setTarget(new BABYLON.Vector3(0,0,0)); camera.attachControl(canvas, false); debugger3d.camera= camera; const light1 = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(1,1,1), debugger3d.scene); const light2 = new BABYLON.HemisphericLight('light2', new BABYLON.Vector3(-1,-1,0), debugger3d.scene); light1.diffuse = new BABYLON.Color3(1, 1, 1); light1.specular = new BABYLON.Color3(1, 1, 1); light2.diffuse = new BABYLON.Color3(1, 1, 1); light2.specular = new BABYLON.Color3(1, 1, 1); debugger3d.scene.clearColor = new BABYLON.Color3(0.3,0.3,0.3); debugger3d.scene.onPointerDown = function (evt, pickResult) { // if the click hits the ground object, we change the impact position const textureCoordinates = pickResult.getTextureCoordinates(); // console.log("tex ", textureCoordinates, " point ", pickResult.pickedPoint); }; }, createMesh(){ const mesh= new BABYLON.Mesh("Mesh", debugger3d.scene); mesh.position = BABYLON.Vector3.Zero(); debugger3d.vertexData = new BABYLON.VertexData(); const material = new BABYLON.StandardMaterial("mat1",debugger3d.scene); material.wireframe= debugger3d.options.wireframe; material.backFaceCulling = debugger3d.options.backFaceCulling; material.ambientColor= new BABYLON.Color3(1,1,1); material.diffuseColor= new BABYLON.Color3(1,1,1); mesh.material= material; debugger3d.mesh = mesh; }, init() { debugger3d.initBabylon(); debugger3d.initEvents(); }, initBabylon(){ document.querySelectorAll('input').forEach(el => el.checked =debugger3d.options[el.getAttribute("data-target")]); const canvas3d= document.getElementById("babylon"); canvas3d.classList.add("canvas3d"); setTimeout(() => { canvas3d.height = canvas3d.offsetHeight; canvas3d.width = canvas3d.offsetWidth; }, 200); debugger3d.engine = new BABYLON.Engine(canvas3d, true); debugger3d.scene = new BABYLON.Scene(debugger3d.engine); debugger3d.createScene(debugger3d.engine,canvas3d); debugger3d.createMesh(); debugger3d.engine.runRenderLoop(function() { debugger3d.scene.render(); debugger3d.updateMesh(); }); }, initEvents(){ ["option", "option3d"].forEach(elementId => { [...document.getElementById(elementId).getElementsByTagName('input')].forEach(el => { el.addEventListener("change", e => { const value = (e.target.checked); debugger3d.options[el.getAttribute("data-target")] = value; debugger3d.meshDirty = true; }); el.checked = debugger3d.options[el.getAttribute("data-target")]; }); }); document.addEventListener('resize', function(){ debugger3d.engine.resize(); }); document.getElementById("babylon").addEventListener('resize', function(){ debugger3d.engine.resize(); }); }, pathToEdge (paths) { if (!paths || !paths.length ) return; if(!paths[0].length) paths = [paths]; const doNotBuild = paths; const edges = []; for (let i = 0; i < doNotBuild.length; i++) { const path = doNotBuild[i]; for (let j = 0; j < path.length; j++) { const ptA = path[j]; const ptB = path[(j + 1) % path.length]; edges.push([{X:ptA.X,Y:ptA.Y},{X:ptB.X,Y:ptB.Y}]); } } debugger3d.doNotBuild = edges; }, rebuild(outerShape, holes){ debugger3d.outerShape = JSON.parse(JSON.stringify(outerShape)); debugger3d.holes = JSON.parse(JSON.stringify(holes)); debugger3d.meshDirty = true; }, toClipperString(string) { return string.replace(/x/g,"X").replace(/y/g, "Y"); } }; module.exports = debugger3d;