将 gpx 文件转换为 stl 文件:reactJS

问题描述 投票:0回答:1

我对编码还很陌生,作为一个很好的项目,我想制作一个 gpx 到 stl 转换器。经过一些研究后,我得出的结论是,这一定是可能的。我在这个项目中使用reactJS。

我对应该如何做的发现:

  1. 为 gpx 文件创建上传 btn
  2. 从 gpx 文件中获取所有坐标并保存它们
  3. 将这些坐标放入 3D 模型(如 Threejs)中。 (还是不确定这一步的重要性以及如何做好)
  4. 将 Threejs 渲染转换为 stl
  5. 创建一个 btn 来下载文件。

**我目前的问题:**

  • 上传我的 gpx 后,有来自 Three.js 的渲染,但没有显示为路线(current threejs render)它看起来像几行,来自同一个起点。
  • 尝试下载文件时,我得到一个只有几个字节的文件,无法打开(不在我的电脑或在线 stl 文件打开器中。

这是我当前的代码:

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>
);
reactjs three.js converters gpx stl-format
1个回答
0
投票

这个问题似乎与您在 Three.js 中为路线创建几何图形并将其导出到 STL 的方式有关

  1. 在 create3DScene() 中,更新几何体的创建以使用 THREE.BufferGeoymetr 以获得更好的性能。另外,请确保将几何体添加到场景中。

2)在downloadSTL()中,在导出到STL之前确保场景具有有效的几何体。另外,考虑使用三个/examples/jsm/exporters/STLExporter.js中的STLExporter

© www.soinside.com 2019 - 2024. All rights reserved.