当前位置: 首页 > news >正文

利用three.js在Vue项目中展示重构的stl模型文件

一、目的

   为了在前端页面展示3d打印机打印过程

二、前期准备

完整模型的stl文件和模型切割成的n个stl文件

models文件夹下的文件就是切割后的stl文件

三、代码

<template>
    <div ref="threeContainer" class="three-container"></div>
  </template>
  
  <script>
  import * as THREE from "three";
  import { STLLoader } from "three/examples/jsm/loaders/STLLoader.js";
  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
  
  export default {
    name: "CastleDemo",
    mounted() {
      this.initThree();
    },
    methods: {
      initThree() {
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0xeeeeee);
  
        const camera = new THREE.PerspectiveCamera(
          75,
          window.innerWidth / window.innerHeight,
          0.1,
          1000
        );
        camera.position.set(0, 20, 50); // 调整相机位置,使其离模型更远
        camera.lookAt(scene.position);
  
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        this.$refs.threeContainer.appendChild(renderer.domElement);
  
        const ambientLight = new THREE.AmbientLight(0x404040, 1);
        const pointLight = new THREE.PointLight(0xffffff, 1, 1000);
        pointLight.position.set(0, 50, 50);
        scene.add(ambientLight, pointLight);
  
        const loader = new STLLoader();
        const models = this.generateModels(); // 生成47个模型的配置
  
        // 状态变量:控制是否开始旋转
        let allModelsLoaded = false;
  
        // 逐层加载模型
        let currentModelIndex = 0;
        const loadNextModel = () => {
          if (currentModelIndex < models.length) {
            const model = models[currentModelIndex];
            loader.load(model.url, (geometry) => {
              geometry.center();
              const material = new THREE.MeshStandardMaterial({
                color: model.color,
                transparent: true, // 启用透明度
                opacity: 0.8, // 设置透明度值
              });
              const mesh = new THREE.Mesh(geometry, material);
              mesh.position.set(...model.position);
              mesh.scale.set(model.scale, model.scale, model.scale);
              scene.add(mesh);
  
              // 动态更新进度
              currentModelIndex++;
              loadNextModel();
            });
          } else {
            // 所有模型加载完成
            allModelsLoaded = true;
          }
        };
  
        loadNextModel(); // 开始加载第一个模型
  
        // 添加轨道控制器
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true; // 启用阻尼效果
        controls.dampingFactor = 0.25; // 阻尼系数
        controls.enableZoom = true; // 允许缩放
        controls.enablePan = true; // 允许平移
  
        // 添加旋转逻辑
        let rotationSpeed = 0.01; // 旋转速度
        function animate() {
          requestAnimationFrame(animate);
  
          // 只有在所有模型加载完成后才开始旋转
          if (allModelsLoaded) {
            scene.traverse((object) => {
              if (object.isMesh) {
                object.rotation.y += rotationSpeed; // 绕Y轴旋转
                object.rotation.x += rotationSpeed * 0.5; // 绕X轴旋转
              }
            });
          }
  
          controls.update(); // 更新轨道控制器
          renderer.render(scene, camera);
        }
        animate();
      },
  
      // 生成47个模型的配置
      generateModels() {
        const models = [];
        const basePosition = [0, -36.5, 0]; // 基础位置,从底部开始
        const spacing = 0.5; // 模型之间的间距
  
        for (let i = 0; i < 72; i++) { 
          const position = [
            basePosition[0], // X轴位置
            basePosition[1] + i * spacing, // Y轴方向排列,从低到高
            basePosition[2],
          ];
          const color = this.getColorByIndex(i); // 根据索引计算颜色
          models.push({
            url: `/3Dmodels/castledemo/models/part_${String(i).padStart(6, "0")}.stl`, // 文件名格式为 part_000000.stl 到 part_000046.stl
            position,
            scale: 0.3,
            color,
          });
        }
        return models;
      },
  
      // 根据索引计算颜色
      getColorByIndex(index) {
        const startColor = 0xffff00; // 起始颜色为黄色
        const endColor = 0x00ffff; // 结束颜色为青色
        const colorRange = endColor - startColor;
        const ratio = index / (47 - 1); // 计算颜色比例
        const color = startColor + Math.floor(colorRange * ratio);
        return color;
      },
    },
  };
  </script>
  
  <style scoped>
  .three-container {
    
    background-color: #ffffff;
  }
  </style>

四、最终效果

五、问题

模型重构出来会存在走位的情况,可能需要根据每个模型文件的实际大小进行调整。

相关文章:

  • Grafana接入Zabbix数据源
  • java23种设计模式-状态模式
  • 超越期望:提供超越标准的客户服务
  • Flume
  • 【Kubernetes】 Scheduler 的逻辑:从 Predicates/Priorities 到 Filter/Score
  • 微深节能 高炉废渣车天车精确定位系统 格雷母线
  • 使用CSS3DRenderer/CSS2DRenderer给模型上面添加html标签的一个demo
  • 3.1部署filebeat:5044
  • 2025年光电科学与智能传感国际学术会议(ICOIS 2025)
  • 可视化的决策过程:决策树 Decision Tree
  • 良田S500L高拍仪对接
  • STM32之时钟树
  • DeepSeek开源周Day5: 3FS存储系统与AI数据处理新标杆
  • 51单片机编程学习笔记——Delay效果的实现
  • 顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-大模型电话机器人
  • 2004-2024年可调谐激光雷达研究领域国内外发展研究2025.2.28
  • 防流、节抖、重绘、回流原理,以及实现方法和区别
  • 【搜广推算法的力量:如何用数据驱动用户体验与商业价值?】
  • 21-发糖果
  • 内容中台实战指南:效能提升与体系构建
  • 做网站便宜/收录情况
  • 电商网站开发背景/下载安装百度一下
  • 做爰视频在线观看免费网站/网络营销的应用研究论文
  • wordpress扁平化登录页源码/女装标题优化关键词
  • 专门做ppt会员网站/百度推广是什么工作
  • 乐清市网站建设/上海搜索引擎优化公司排名