-1

im pretty new to coding and as a nice project to get better wanted to make a gpx to stl converter. After doing some research i came to a conclusion that it must be possible. I use reactJS for this project.

My findings on how I should do it :

  1. Create upload btn for gpx file
  2. Get all coordinates out of the gpx file and save them
  3. Put these coordinates in a 3D model like threejs. (still not sure about the importance of this step and how to do it well)
  4. Convert the threejs render into an stl
  5. create a btn to download the file.

**My problems at the moment : **

  • After uploading my gpx, there is a render from three.js but doesnt show as a route(current threejs render) It looks like a few lines, coming out of the same starting point.
  • When trying to download the file, i get a file which is a few bytes and cant be opened (not in my computer or a online stl file opener.

This is my current code :

import React, { useState } from 'react';
function FileUploader({ onFileUpload }) {
 const [selectedFile, setSelectedFile] = useState(null);
 const handleFileChange = async (e) => {
 const file = e.target.files[0];
 
 // Lees de inhoud van het GPX-bestand
 const fileContent = await readFileContent(file);
 setSelectedFile(file);
 onFileUpload({ file, fileContent });
 };
 const readFileContent = (file) => {
 return new Promise((resolve, reject) => {
 const reader = new FileReader();
 reader.onload = (e) => {
 resolve(e.target.result);
 };
 reader.onerror = (e) => {
 reject(new Error('Error reading file.'));
 };
 reader.readAsText(file);
 });
 };
 return (
 <div className="file-uploader">
 <label>
 Selecteer een GPX-bestand:
 <input type="file" accept=".gpx" onChange={handleFileChange} />
 </label>
 </div>
 );
}
export default FileUploader;
**// Converter.js
**
import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { STLExporter } from 'three/addons/exporters/STLExporter.js';
function Converter({ gpxFile }) {
 const threeContainerRef = useRef(null);
 const sceneRef = useRef(null);
 const cameraRef = useRef(null);
 const rendererRef = useRef(null);
 const downloadSTL = () => {
 const STLExporterInstance = new STLExporter();
 const stlData = STLExporterInstance.parse(sceneRef.current);
 const blob = new Blob([stlData], { type: 'application/octet-stream' });
 const url = URL.createObjectURL(blob);
 
 const downloadLink = document.createElement('a');
 downloadLink.href = url;
 downloadLink.download = 'geconverteerd_model.stl';
 downloadLink.click();
 // Optioneel: Opruimen van de URL en het element
 URL.revokeObjectURL(url);
 //renderer.domElement.remove();
 };
 useEffect(() => {
 const convertGPXtoSTL = (gpxData) => {
 const validateGPX = (gpxData) => {
 try {
 const parser = new DOMParser();
 const xmlDoc = parser.parseFromString(gpxData, 'text/xml');
 const trkpts = xmlDoc.querySelectorAll('trkpt');
 if (!trkpts.length) {
 throw new Error('Geen trackpunten gevonden in het GPX-bestand.');
 }
 return trkpts;
 } catch (error) {
 throw new Error(`Ongeldige GPX-gegevens: ${error.message}`);
 }
 };
 const optimizeGPXData = (trkpts) => {
 const points = [];
 trkpts.forEach((trkpt) => {
 const lat = parseFloat(trkpt.getAttribute('lat'));
 const lon = parseFloat(trkpt.getAttribute('lon'));
 const eleNode = trkpt.querySelector('ele');
 if (eleNode) {
 const ele = parseFloat(eleNode.textContent);
 points.push({ lat, lon, ele });
 }
 });
 return points;
 };
 const trkpts = validateGPX(gpxData);
 const points = optimizeGPXData(trkpts);
 console.log('Geoptimaliseerde GPX-punten:', points);
 return points;
 };
 const create3DScene = (points) => {
 const scene = new THREE.Scene();
 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
 const renderer = new THREE.WebGLRenderer();
 
 renderer.setSize(window.innerWidth, window.innerHeight);
 threeContainerRef.current.appendChild(renderer.domElement);
 
 const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
 
 // Maak een geometrie voor de lijnen
 const geometry = new THREE.BufferGeometry().setFromPoints(
 points.map((point) => new THREE.Vector3(point.lon, point.ele, point.lat))
 );
 
 // Maak een lijn met de geometrie en het materiaal
 const line = new THREE.Line(geometry, material);
 scene.add(line);
 
 camera.position.set(points[0].lon, points[0].ele, points[0].lat);
 camera.lookAt(new THREE.Vector3(points[points.length - 1].lon, points[points.length - 1].ele, points[points.length - 1].lat));
 
 // Voeg een grid toe voor visuele referentie
 const gridHelper = new THREE.GridHelper(10, 10);
 scene.add(gridHelper);
 
 return { scene, camera, renderer };
 };
 
 
 const points = convertGPXtoSTL(gpxFile.fileContent);
 const { scene, camera, renderer } = create3DScene(points);
 sceneRef.current = scene;
 cameraRef.current = camera;
 rendererRef.current = renderer;
 // Animeren van de scene
 const animate = () => {
 requestAnimationFrame(animate);
 // Voeg hier eventuele animaties of updates toe
 renderer.render(scene, camera);
 };
 animate();
 // Voeg cleanup-functie toe
 return () => {
 renderer.domElement.remove();
 };
 }, [gpxFile.fileContent]);
 return (
 <div className="converter">
 <h2>GPX-bestand geüpload:</h2>
 <p>Bestandsnaam: {gpxFile.file.name}</p>
 <p>Bestandsinhoud: {gpxFile.fileContent}</p>
 <h2>3D-weergave van GPX-data:</h2>
 <div ref={threeContainerRef}></div>
<button onClick={downloadSTL}>Download STL</button> 
</div>
 );
}
export default Converter;
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
 <React.StrictMode>
 <App />
 </React.StrictMode>
);
LoS
2,0162 gold badges11 silver badges37 bronze badges
asked Jan 18, 2024 at 13:27
1
  • When you pick tags, please read their descriptions. Don't spam the tag stl for C++. Commented Jan 18, 2024 at 15:33

1 Answer 1

0

The issue seems to be related to the way you are creating the geometry for the route in Three.js and exporting it to STL

  1. In the create3DScene(), update the creation of the geometry to use THREE.BufferGeoymetr for better performance. Also, ensure that you are adding the geometry to the scene.

2)In the downloadSTL(), ensure that the scene has a valid geometry before exporting to STL. Also, consider using STLExporter from three/examples/jsm/exporters/STLExporter.js

answered Jan 18, 2024 at 13:42
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.