Public
Edited
Jan 15, 2024
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
turf = require("@turf/turf@5")
Insert cell
Insert cell
Insert cell
async function create3dFromSvgV8(svg, type, scaleBy, color=false) {
// Get Shapes and Points
const loader = new THREE.SVGLoader(); // Load the svg using three to use it's tooling
let paths = loader.parse(svg.outerHTML).paths; // Parse the SVG file and retrieve all the paths
let style = paths[0].userData.style; // Store the style of the first path in a variable
const shapes = []
let points = [];
// THREE.JS FN Retrieves the shapes for each path, converts it to a threejs 'shape' and add the the 'shapes' array
paths.forEach((path, i) => {
paths[i].toShapes(true, false).forEach((shape, i) => {
shapes.push(shape);
});
for (let j = 0, jl = path.subPaths.length; j < jl; j++) {
points.push(path.subPaths[j].getPoints());
}
});

// Create Group
const group = new THREE.Group();
const depth = 40
// Points: Paint Stroke
if( ['lines'].includes(type) ){
points.forEach((pointsArr, i) => {
const geometry = THREE.SVGLoader.pointsToStroke( pointsArr, style )
material.color = new THREE.Color().setStyle( color||'pink' )
const mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
});
}
// Prepare Extrude Settings
const material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide });
material.color = new THREE.Color().setStyle( color||'blue' )
let extrudeSettings = { depth: depth, bevelEnabled: false }
// Shapes: Extrtrude Geometry
if( ['geoms'].includes(type) ){
shapes.forEach(shape => {
const geometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings);
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
});
}
// Points: Extrude Stroke
if (["extrude"].includes(type)) {
let x = 20; // depth
let y = 2; // Topwidth
let z = 2; // bottomWidth
let startPos = depth+x/2+1;
const shapeBufferGeometry = [];
points.forEach((twoVectorArray, i) => {
let threeVectorArray = [];
twoVectorArray.forEach((v, i) => { threeVectorArray.push(new THREE.Vector3(v.x, v.y, startPos)); });
const extrusionPath = new THREE.CurvePath();
for (let i = 0; i < threeVectorArray.length - 1; i++) {
extrusionPath.add( new THREE.LineCurve3( threeVectorArray[i], threeVectorArray[i + 1] ) );
}
const squareShape = new THREE.Shape()
.moveTo(x, 0)
.lineTo(x, y)
.lineTo(y, z)
.lineTo(z, 0);
var geometry = new THREE.ExtrudeBufferGeometry(squareShape, {
extrudePath: extrusionPath,
curveSegments: 1,
steps: 200,
bevelEnabled: false,
});
material.color = new THREE.Color().setHex(Math.random() * 0xffffff);
shapeBufferGeometry.push(geometry);
});

const iconGeometry = THREE.BufferGeometryUtils.mergeBufferGeometries( shapeBufferGeometry, true);
const mesh = new THREE.Mesh(iconGeometry, material);
group.add(mesh);
}

position(group)
return group;
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
meshHullRes = {
let meshA = hull3D.children[0]
let meshB = hull3DSmall.children[0]
let meshC = geomBounds3D.children[0]
meshB.scale.set(.95, .95, .95);

let bb1 = getBoundingBoxCenter(meshA)
let bb2 = getBoundingBoxCenter(meshB)
let bb3 = getBoundingBoxCenter(meshC)
let translation = new THREE.Vector3().subVectors(bb1, bb2);
meshB.position.x += translation.x;
meshB.position.y += translation.y;
meshB.position.z = -1 // bb1.z;

translation = new THREE.Vector3().subVectors(bb1, bb3);
meshC.position.x += translation.x;
meshC.position.y += translation.y;
meshC.position.z = 0// bb1.z;
meshA.updateMatrix();
meshB.updateMatrix();
meshC.updateMatrix();

// Create a CSG object from each mesh
let bspA = CSG.fromMesh( meshA );
let bspB = CSG.fromMesh( meshB );
let bspC = CSG.fromMesh( meshC );

// Perform the CSG subtraction
let bspResult = bspA.subtract(bspB);
bspResult = bspResult.subtract(bspC);
var mesh = CSG.toMesh( bspResult, meshA.matrix, meshA.material );
mesh.geometry.computeVertexNormals();

const material = new THREE.MeshNormalMaterial();
new THREE.MeshBasicMaterial( { side: THREE.DoubleSide } );
material.color = new THREE.Color().setStyle( 'orange' )
var bufferGeometry = new THREE.BufferGeometry().fromGeometry( mesh.geometry );
mesh = new THREE.Mesh( bufferGeometry, material )
// Doesn't show in STL
position(mesh)
return mesh
}
Insert cell
Insert cell
Insert cell
{
// Equirectangular Background
const renderer = new THREE.WebGLRenderer({ antialias: true });
const controls = new THREE.OrbitControls(camera, renderer.domElement);
invalidation.then(() => (controls.dispose(), renderer.dispose()));
renderer.setSize(900, 600);
renderer.setPixelRatio(devicePixelRatio);
controls.addEventListener("change", () => renderer.render(scene, camera));
renderer.render(scene, camera);
return renderer.domElement;
}
Insert cell
STLExporter = import("https://cdn.skypack.dev/three@0.136.0/examples/jsm/exporters/STLExporter.js")
Insert cell
{
let exporter = new STLExporter.STLExporter();
let exportScene = (meshThis, name) => {
// console.log('exportScene', meshThis)
let buffer = exporter.parse( meshThis )
let filename = name+'.stl'
let blobby = new Blob( [ buffer ], { type: "text/stl" } )
return DOM.download(blobby, filename, "Download "+name)
}
// ${exportScene(geomBounds3D, 'geomBoundsLines')}
return html`
${exportScene(meshRes, 'meshRes')}
${ exportScene(hull3D, 'hull3D')}
${exportScene(geomBounds3D, 'geomBounds3D')}
${exportScene(meshHullRes, 'meshHullRes')}
`}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more