import THREE from 'three.js'; import Shape from 'Doodle3D/clipper-js'; export default function intersectionsToShapes(layerIntersectionIndexes, layerIntersectionPoints, lines, settings) { console.log("generating slices"); const layers = []; for (let layer = 1; layer < layerIntersectionIndexes.length; layer ++) { const intersectionIndexes = layerIntersectionIndexes[layer]; const intersectionPoints = layerIntersectionPoints[layer]; if (intersectionIndexes.length === 0) continue; const closedShapes = []; const openShapes = []; for (let i = 0; i < intersectionIndexes.length; i ++) { let index = intersectionIndexes[i]; if (intersectionPoints[index] === undefined) continue; const shape = []; const firstPoints = [index]; let isFirstPoint = true; let closed = false; while (index !== -1) { const intersection = intersectionPoints[index]; // uppercase X and Y because clipper vector shape.push(intersection); delete intersectionPoints[index]; const connects = lines[index].connects; const faceNormals = lines[index].normals; for (let i = 0; i < connects.length; i ++) { index = connects[i]; if (firstPoints.indexOf(index) !== -1 && shape.length > 2) { closed = true; index = -1; break; } // Check if index has an intersection or is already used if (intersectionPoints[index] !== undefined) { const faceNormal = faceNormals[Math.floor(i / 2)]; const a = new THREE.Vector2(intersection.x, intersection.y); const b = new THREE.Vector2(intersectionPoints[index].x, intersectionPoints[index].y); // can't calculate normal between points if distance is smaller as 0.0001 if ((faceNormal.x === 0 && faceNormal.y === 0) || a.distanceTo(b) < 0.0001) { if (isFirstPoint) { firstPoints.push(index); } delete intersectionPoints[index]; connects.push(...lines[index].connects); faceNormals.push(...lines[index].normals); index = -1; } else { // make sure the path goes the right direction // THREE.Vector2.normal is not yet implimented // const normal = a.sub(b).normal().normalize(); const normal = a.sub(b); normal.set(-normal.y, normal.x).normalize(); if (normal.dot(faceNormal) > 0) { break; } else { index = -1; } } } else { index = -1; } } isFirstPoint = false; } if (!closed) { index = firstPoints[0]; while (index !== -1) { if (firstPoints.indexOf(index) === -1) { const intersection = intersectionPoints[index]; shape.unshift(intersection); delete intersectionPoints[index]; } const connects = lines[index].connects; for (let i = 0; i < connects.length; i ++) { index = connects[i]; if (intersectionPoints[index] !== undefined) { break; } else { index = -1; } } } } if (closed) { closedShapes.push(shape); } else { openShapes.push(shape); } } layers.push({ closedShapes, openShapes }); } return layers; }