水库大坝三维模型的开发和使用3Dmax篇

成果图
在这里插入图片描述
开发过程

  • 工具插件three.js
  • 先加载模型
  • 做水体衔接
  • 水位测量标尺
  • 水位标记
  • 断面标记
  • 大坝监测点打点

上代码,技术交流+V: bloxed

<template><div class="box w100 h100"><el-row :gutter="20"  v-loading="loading"element-loading-background="rgba(122, 122, 122, 0.8)"element-loading-text="模型加载中..."><el-col :span="24" class="h100" ref="boxRef"><div id="container" ref="container"></div></el-col></el-row></div>
</template>
<script setup lang="ts">
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import {OrbitControls} from "three/addons/controls/OrbitControls";
import { Water } from 'three/examples/jsm/objects/Water.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import  TWEEN  from '@tweenjs/tween.js';
import {  CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
import { instrumentList,waterData,getTooltipData} from "../index.api"
const props = defineProps({damId:{type:Number,default:1},epcId:{type:String,default:""}
})
const boxRef = ref<any>(null);
const loading = ref(false);
let scene:any;
let textMesh:any;
let textMeshs:any =[];
let rectMeshs:any =[];
const camera = ref<any>(null);
let water:any;
const renderer = ref<any>(null);
const  container = ref<any>(null);
const  controls  = ref<any>(null);
const loaderT = new FontLoader();
import { useAppStore} from "@/store";
import { set } from '@vueuse/core';
const appStore = useAppStore();
//label ref
const dam_top_heightRef = ref<any>(null);
const tooltipData = ref<any>([])
//刻度尺
const acalesText = [{id:0,value:"校核洪水位:80.6m",x:-175,y:0,z:-130,color:0xFF0000},{id:0,value:"设计洪水位:80.6m",x:-175,y:-10,z:-130,color:0xFFFF00},{id:0,value:"正常水位:80.6m",x:-175,y:-20,z:-130,color:0x00FF00},{id:0,value:"当前水位:80.6m",x:-175,y:-49,z:-130,color:0xfffffff},{id:0,value:"死水位:80.6m",x:-175,y:-39,z:-130,color:0xfffffff},{id:1,value:"50",x:-224,y:-100,z:-130,color:0xfffffff},{id:2,value:"60",x:-224,y:-80,z:-130,color:0xfffffff},{id:3,value:"70",x:-224,y:-60,z:-130,color:0xfffffff},{id:4,value:"80",x:-224,y:-40,z:-130,color:0xfffffff},{id:5,value:"90",x:-224,y:-20,z:-130,color:0xfffffff},{id:6,value:"100m",x:-224,y:-0,z:-130,color:0xfffffff},
];
const  rectangles = [//坝顶高程
{id:0,width:48,height:16,x:-20,y:40,z:175,color:0x367DF9 },
//B09
{id:0,width:30,height:10,x:-30,y:0,z:80,color:0x367DF9 },
{id:0,width:30,height:10,x:-30,y:0,z:-30,color:0x367DF9 },
{id:0,width:30,height:10,x:-30,y:0,z:-100,color:0x367DF9 },//B10
{id:0,width:30,height:10,x:20,y:-20,z:80,color:0x367DF9 },
{id:0,width:30,height:10,x:20,y:-20,z:-30,color:0x367DF9 },
{id:0,width:30,height:10,x:20,y:-20,z:-100,color:0x367DF9 },//B11
{id:0,width:30,height:10,x:80,y:-30,z:80,color:0x367DF9 },
{id:0,width:30,height:10,x:80,y:-30,z:-30,color:0x367DF9 },
{id:0,width:30,height:10,x:80,y:-30,z:-100,color:0x367DF9 },
];
//label标签
const labels = [{id:"damTop",value:"坝顶高程:98.6m",x:-20,y:40,z:175,color:0xfffffff},{id:"B09",value:"B09:0mm",x:-30,y:0,z:80,color:0xfffffff},{id:"B05",value:"B05:0mm",x:-30,y:0,z:-30,color:0xfffffff},{id:"B01",value:"B01:0mm",x:-30,y:0,z:-100,color:0xfffffff},{id:"B10",value:"B10:0mm",x:20,y:-20,z:80,color:0xfffffff},{id:"B06",value:"B06:0mm",x:20,y:-20,z:-30,color:0xfffffff},{id:"B02",value:"B02:0mm",x:20,y:-20,z:-100,color:0xfffffff},{id:"B11",value:"B11:0mm",x:80,y:-30,z:80,color:0xfffffff},{id:"B07",value:"B7:0mm",x:80,y:-30,z:-30,color:0xfffffff},{id:"B03",value:"B3:0mm",x:80,y:-30,z:-100,color:0xfffffff},//断面{id:3,value:"断面:B0+027",x:-80,y:-30,z:-100,color:0xfffffff},{id:3,value:"断面:B0+050",x:-80,y:-30,z:-30,color:0xfffffff},{id:3,value:"断面:B0+073",x:-80,y:-30,z:80,color:0xfffffff},
]
//label标签线
const labelsLine = [{id:0,x:-10,y:35,z:175, x1:-10,y1:-50,z1:175,  color:0x00FFff},// B09{id:1,x:-30,y:0,z:80, x1:-30,y1:-50,z1:80,  color:0x00FFff},{id:2,x:-30,y:0,z:-30, x1:-30,y1:-50,z1:-30,  color:0x00FFff},{id:3,x:-22,y:0,z:-100, x1:-22,y1:-50,z1:-100,  color:0x00FFff},//B10{id:1,x:20,y:-20,z:80, x1:20,y1:-50,z1:80,  color:0x00FFff},{id:2,x:20,y:-20,z:-30, x1:20,y1:-50,z1:-30,  color:0x00FFff},{id:3,x:20,y:-20,z:-100, x1:20,y1:-50,z1:-100,  color:0x00FFff},//B11{id:4,x:80,y:-30,z:80, x1:80,y1:-80,z1:80,  color:0x00FFff},{id:5,x:80,y:-30,z:-30, x1:80,y1:-80,z1:-30,  color:0x00FFff},{id:6,x:80,y:-30,z:-100, x1:80,y1:-80,z1:-100,  color:0x00FFff},//断面{id:7,x:-100,y:-34,z:-100, x1:-22,y1:-34,z1:-100,  color:0x00FFff},{id:7,x:-100,y:-34,z:-30, x1:-32,y1:-34,z1:-30,  color:0x00FFff},{id:7,x:-100,y:-34,z:80, x1:-32,y1:-34,z1:80,  color:0x00FFff},]
const labelTwoLines =[
{ id:0,x:-153,y:-3,z:-130,x1:-200,y1:-5,z1:-130,x2:-215,y2:-9,z2:-130,color:0xFF0000
},
{ id:0,x:-153,y:-13,z:-130,x1:-200,y1:-14,z1:-130,x2:-215,y2:-11,z2:-130,color:0xFFFF00
},
]
onMounted(() => {})const initPage = async ()=>{loading.value = true;initScene();initCamera();initRenderer();initControl();initWater();await initModel();await initLine();await addText();await addLabelLine();await addLabelTwoLine();initRectangle();flyToCamera();initAnimate();initAddClick();}// Create the sceneconst initScene = ()=>{scene = new THREE.Scene();};
// Create the cameraconst initCamera= ()=>{camera.value = new THREE.PerspectiveCamera(45,1153 / 819, 0.1, 1000);camera.value.position.set(-163,143,-508);};// Create the rendererconst initRenderer =()=>{renderer.value = new THREE.WebGLRenderer({ antialias: true });renderer.value.setSize(container.value.clientWidth, container.value.clientHeight);renderer.value.setClearColor('#03243f', 0.1);renderer.value.domElement.style.position = "absolute";renderer.value.domElement.style.top = "-160px";renderer.value.domElement.style.left = "-60px";container.value.appendChild(renderer.value.domElement);};const initControl = ()=>{controls.value = new OrbitControls(camera.value, renderer.value.domElement);controls.value.enableDamping = true;// // 最大角度controls.value.maxPolarAngle = Math.PI / 2.2;};// 创建Raycaster实例const raycaster = new THREE.Raycaster();const mouse = new THREE.Vector2();const initAnimate = ()=> {water.material.uniforms["time"].value += 1.0 / 60.0;requestAnimationFrame(initAnimate);renderer.value.render(scene, camera.value);controls.value.update();textMeshs.forEach((mesh:any)=>{mesh.lookAt(camera.value.position)})rectMeshs.forEach((mesh:any)=>{mesh.lookAt(camera.value.position)})TWEEN.update();// console.log('Camera Position:', camera.value.position);};const initWater = ()=>{const waterGeometry = new THREE.BoxGeometry(200, 280,35);water = new Water(waterGeometry,{textureWidth: 512,textureHeight: 512,waterNormals: new THREE.TextureLoader().load('/3D/water.jpeg', function (texture:any) {texture.wrapS = texture.wrapT = THREE.RepeatWrapping;}),sunDirection: new THREE.Vector3(),sunColor: 0x007FFF,waterColor: 0x007FFF,distortionScale: 3.7,});water.rotation.x = - Math.PI / 2;water.position.x = -114;water.position.y = -81.5;water.position.z = 10;scene.add(water)};const initLine = ()=>{const axisMaterial = new THREE.LineBasicMaterial({ color: 0xffffff }); // Blue for Xconst yAxisMaterial = new THREE.LineBasicMaterial({ color: 0xff0000  }); // Red for Yconst zAxisMaterial = new THREE.LineBasicMaterial({ color: 0xffff }); // Green for Z// Create the geometry for the axesconst axisGeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-110, -140, -182.2),new THREE.Vector3(-11, -140, -182.2)]);const yAxisGeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-215, 0, -130),new THREE.Vector3(-215, -100, -130)]);const zAxisGeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(19, 0, -22.2),new THREE.Vector3(19, 0, 5)]);//begin 这里用作刻度线//水位使用const zAxisGeometry0 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-160, -60, -130),new THREE.Vector3(-214, -60, -130)]);const zAxisGeometry1 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-210, -100, -130),new THREE.Vector3(-215, -100, -130)]);const zAxisGeometry11 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-210, -90, -130),new THREE.Vector3(-215, -90, -130)]);const zAxisGeometry2 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-205, -80, -130),new THREE.Vector3(-215, -80, -130)]);const zAxisGeometry22 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-210, -70, -130),new THREE.Vector3(-215, -70, -130)]);const zAxisGeometry3 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-205, -50, -130),new THREE.Vector3(-215, -50, -130)]);const zAxisGeometry33 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-210, -40, -130),new THREE.Vector3(-215, -40, -130)]);const zAxisGeometry4 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-205, -30, -130),new THREE.Vector3(-215, -30, -130)]);const zAxisGeometry44 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-210, -20, -130),new THREE.Vector3(-215, -20, -130)]);const zAxisGeometry5 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-205, -10, -130),new THREE.Vector3(-215, -10, -130)]);const zAxisGeometry55 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-210, 0, -130),new THREE.Vector3(-215, 0, -130)]);//end // Create the line segments for the axesconst axis = new THREE.Line(axisGeometry, axisMaterial);const yAxis = new THREE.Line(yAxisGeometry, yAxisMaterial);const zAxis = new THREE.Line(zAxisGeometry, zAxisMaterial);//begin 这里用作刻度线const zAxis0 = new THREE.Line(zAxisGeometry0, axisMaterial);const zAxis1 = new THREE.Line(zAxisGeometry1, axisMaterial);const zAxis2 = new THREE.Line(zAxisGeometry2, axisMaterial);const zAxis3 = new THREE.Line(zAxisGeometry3, axisMaterial);const zAxis4 = new THREE.Line(zAxisGeometry4, axisMaterial);const zAxis11 = new THREE.Line(zAxisGeometry11, axisMaterial);const zAxis22 = new THREE.Line(zAxisGeometry22, axisMaterial);const zAxis33 = new THREE.Line(zAxisGeometry33, axisMaterial);const zAxis44 = new THREE.Line(zAxisGeometry44, axisMaterial);const zAxis5 = new THREE.Line(zAxisGeometry5, axisMaterial);const zAxis55 = new THREE.Line(zAxisGeometry55, axisMaterial);//end// scene.add(axis);scene.add(yAxis);// scene.add(zAxis);//begin 这里用作刻度线scene.add(zAxis0);scene.add(zAxis1);scene.add(zAxis2);scene.add(zAxis3);scene.add(zAxis4);scene.add(zAxis5);scene.add(zAxis11);scene.add(zAxis22);scene.add(zAxis33);scene.add(zAxis44);scene.add(zAxis55);//end}const addText =()=> {loaderT.load(// font资源URL'/3D/HONOR_Sans_CN_Regular.json',// onLoad回调function (font:any) {acalesText.forEach(item=>{const textGeometry = new TextGeometry(item.value, {font: font,size: 3.5, // 字体大小height: 10, // 挤出文本的厚度})textGeometry.center() // 居中文本const materials = new THREE.MeshBasicMaterial({color: item.color || 0xfffffff,transparent: true,opacity: 0.9,})textMesh = new THREE.Mesh(textGeometry, materials)textMesh.position.set(item.x,item.y, item.z)textMeshs.push(textMesh)scene.add(textMesh)})labels.forEach(item=>{const textGeometry = new TextGeometry(item.value, {font: font,size: 4, // 字体大小height: 10, // 挤出文本的厚度})textGeometry.center() // 居中文本const materials = new THREE.MeshBasicMaterial({color: item.color || 0xfffffff,transparent: true,opacity: 0.9,})textMesh = new THREE.Mesh(textGeometry, materials)textMesh.position.set(item.x,item.y, item.z)textMeshs.push(textMesh)scene.add(textMesh)})})
}
const addLabelLine = ()=>{labelsLine.forEach(item=>{const lineGeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(item.x,item.y, item.z),new THREE.Vector3(item.x1,item.y1, item.z1)]);const lineMaterial = new THREE.LineBasicMaterial({ color: item.color || 0xfffffff });const line = new THREE.Line(lineGeometry, lineMaterial);scene.add(line)})
}
//添加拐角线
const addLabelTwoLine = ()=>{labelTwoLines.forEach(item=>{const lineGeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(item.x,item.y, item.z),new THREE.Vector3(item.x1,item.y1, item.z1),new THREE.Vector3(item.x2,item.y2, item.z2)]);const lineMaterial = new THREE.LineBasicMaterial({ color: item.color || 0xfffffff });const line = new THREE.Line(lineGeometry, lineMaterial);scene.add(line)})
}const initModel = ()=>{// 加载.glb模型const loader = new GLTFLoader();const dracoLoader = new DRACOLoader();dracoLoader.setDecoderPath('/draco/'); // 指定Decoder的路径loader.setDRACOLoader(dracoLoader);loader.load('/3D/zhuba.glb', (gltf:any) => {//解决加载进来为黑色的情况const ambientLight = new THREE.AmbientLight(0xffffff, 1); // 白光,强度为1scene.add(ambientLight);const dirLight = new THREE.DirectionalLight('rgb(253,253,253)', 5);dirLight.position.set(10, 10, 5); // 根据需要自行调整位置scene.add(dirLight);gltf.scene.name = 'dam_model'scene.add(gltf.scene);setTimeout(()=>{loading.value = false;},1100)}, undefined, (error:any) => {console.error(error);});
}
const initRectangle =() =>{rectangles.forEach(item=>{const geometry = new THREE.PlaneGeometry( item.width, item.height );const material = new THREE.MeshBasicMaterial( {color: item.color, transparent: true, opacity: 1} );const plane = new THREE.Mesh( geometry, material );plane.position.set(item.x, item.y, item.z)rectMeshs.push(plane)scene.add( plane );})
} 
const flyToCamera = ()=>{}
const initAddClick = ()=>{//点击事件renderer.value.domElement.addEventListener('click', function (e:any) {//获取点击位置const mouse = new THREE.Vector2();mouse.x = (e.clientX / window.innerWidth) * 2 - 1;mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;//创建射线const raycaster = new THREE.Raycaster();// 更新Raycaster的射线方向raycaster.setFromCamera(mouse, camera.value);// 假设你想要获取与场景中所有对象的交点// 注意:intersectObjects会返回一个包含所有交点的数组const intersects = raycaster.intersectObjects(scene.children, true); // 第二个参数为true表示递归检查所有子对象if (intersects.length > 0) {// 获取最近的交点(通常是数组中的第一个元素)const intersect = intersects[0];// intersect.point就是你在3D空间中点击的位置console.log('Clicked point in 3D space:', intersect.point);// 如果你想要获取被点击对象的详细信息,可以使用intersect.objectconsole.log('Clicked object:', intersect.object);} else {console.log('No objects intersected by the ray.');}})
}
const  getwaterInfo = async()=>{const res = await waterData({epcId:appStore.epc.epcId})labels[0].value = "坝顶高程:" + res.damTop + 'm';acalesText[0].value = "校核洪水位:" + res.checkZ + 'm';acalesText[1].value = "设计洪水位:" + res.designZ + 'm';acalesText[2].value = "正常水位:" + res.normalZ + 'm';acalesText[3].value = "当前水位:" + (res.z ?? 0) + 'm';acalesText[4].value = "死水位:" + res.deadZ + 'm';
}
const getItemData = async()=>{const res = await getTooltipData({damId:props.damId,epcId:props.epcId})tooltipData.value = res;}
onMounted(async() => {await getwaterInfo();initPage();
})</script>
<style lang="scss" scoped>#container{width: 100%;height: calc(100vh - 100px);background-image: url("./bg.png");background-size: cover;}.box{overflow: hidden;height: calc(100vh - 100px);}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕设-基于springboot的校园招聘网站的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

重生之我在异世界学编程之C语言:深入动态内存管理收尾 + 柔性数组篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文常见的动态内存管理错误&#xf…

无人直播源码

DY无人直播系统架构设计介绍 在DY等短视频平台的直播中&#xff0c;无人直播系统能够提供自动化、智能化的互动体验&#xff0c;既减轻了主播的工作量&#xff0c;又提升了观众的参与感。以下是一个典型的无人直播系统架构设计&#xff0c;包含全局配置、点对点互动、产品话术、…

被裁20240927 --- 嵌入式硬件开发 前篇

前篇主要介绍一些相关的概念&#xff0c;用于常识扫盲&#xff0c;后篇开始上干货&#xff01; 他捧着一只碗吃过百家的饭 1. 处理器芯片1.1 处理器芯片制造商一、 英特尔&#xff08;Intel&#xff09;二、 三星&#xff08;SAMSUNG&#xff09;三、 高通&#xff08;Qualcomm…

【Linux】进程间通信 -> 匿名管道命名管道

进程间通信的目的 数据传输&#xff1a;一个进程许需要将它的数据发送给另外一个进程。资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它们发生了某种事件&#xff08;如进程终止时要通知父进程…

Pytorch注意力机制应用到具体网络方法(闭眼都会版)

文章目录 以YoloV4-tiny为例要加入的注意力机制代码模型中插入注意力机制 以YoloV4-tiny为例 解释一下各个部分&#xff1a; 最左边这部分为主干提取网络&#xff0c;功能为特征提取中间这边部分为FPN&#xff0c;功能是加强特征提取最后一部分为yolo head&#xff0c;功能为获…

修改el-select下拉框高度;更新:支持动态修改

文章目录 效果动态修改&#xff1a;效果代码固定高度版本动态修改高度版本&#xff08;2024-12-25 更新&#xff1a; 支持动态修改下拉框高度&#xff09; 效果 动态修改&#xff1a;效果 代码 固定高度版本 注意点&#xff1a; popper-class 尽量独一无二&#xff0c;防止影…

如何完全剔除对Eureka的依赖,报错Cannot execute request on any known server

【现象】 程序运行报错如下&#xff1a; com.netflix.discovery.shared.transport.TransportException报错Cannot execute request on any known server 【解决方案】 &#xff08;1&#xff09;在Maven工程中的pom去掉Eureka相关的引用&#xff08;注释以下部分&#xff0…

vscode写python,遇到问题:ModuleNotFoundError: No module named ‘pillow‘(已解决 避坑)

1 问题&#xff1a; ModuleNotFoundError: No module named pillow 2 原因&#xff1a; 原因1&#xff1a;安装Pillow的pip命令所处的python版本与vscode调用的python解释器版本不同。 如&#xff1a; 原因2&#xff1a;虽然用的是pillow&#xff0c;但是写代码的时候只能用…

Ashy的考研游记

文章目录 摘要12.1112.2012.21 DAY1&#xff08;政治/英语&#xff09;政治英语 12.22 DAY2&#xff08;数学/专业课&#xff09;数学专业课 结束估分 摘要 在24年的12月里&#xff0c;Ashy完成了他的考研冲刺&#xff0c;顺利的结束了他本年度的考研之旅。 在十二月里&#…

AIGC实践|AI/AR助力文旅沉浸式互动体验探索

前言&#xff1a; 本篇文章的创作灵感来源于近期热门话题——让文物“动起来”&#xff0c;各大博物馆成为新进潮流打卡地。结合之前创作的AI文旅宣传片良好的流量和反馈&#xff0c;外加最近比较感兴趣的AR互动探索&#xff0c;想尝试看看自己能不能把这些零碎的内容整合起来…

Kubernetes(k8s)离线部署DolphinScheduler3.2.2

1.环境准备 1.1 集群规划 本次安装环境为&#xff1a;3台k8s现有的postgreSql数据库zookeeper服务 1.2 下载及介绍 DolphinScheduler-3.2.2官网&#xff1a;https://dolphinscheduler.apache.org/zh-cn/docs/3.2.2 官网安装文档&#xff1a;https://dolphinscheduler.apach…

C++的侵入式链表

非侵入式链表 非侵入式链表是一种链表数据结构&#xff0c;其中每个元素&#xff08;节点&#xff09;并不需要自己包含指向前后节点的指针。链表的结构和节点的存储是分开的&#xff0c;链表容器会单独管理这些指针。 常见的非侵入式链表节点可以由以下所示&#xff0c;即&a…

在vscode的ESP-IDF中使用自定义组件

以hello-world为例&#xff0c;演示步骤和注意事项 1、新建ESP-IDF项目 选择模板 从hello-world模板创建 2、打开项目 3、编译结果没错 正在执行任务: /home/azhu/.espressif/python_env/idf5.1_py3.10_env/bin/python /home/azhu/esp/v5.1/esp-idf/tools/idf_size.py /home…

2025差旅平台怎么选?一体化、全流程降本案例解析

差旅支出在企业中一直是一项重要但容易被忽视的成本开支&#xff0c;尤其是在项目驱动型企业中&#xff0c;因频繁的差旅需求&#xff0c;支出规模往往持续增长。以差旅平台分贝通签约伙伴——某智能制造业的业务模式为例&#xff0c;该模式要求员工定期前往不同的工厂、供应商…

【linux】NFS实验

NFS NFS服务 nfs,最早是Sun这家公司所发展出来的,它最大的功能就是可以透过网络,让不同的机器,不同的操作系统,进行实现文档的共享。所以你可以简单的将他看做是文件服务器。 实验准备 ①先准备一个服务器端的操作系统和客户端的操作系统(Red Hat)。 ②选择NAT模式,…

智源研究院与安谋科技达成战略合作,共建开源AI“芯”生态

12月25日&#xff0c;智源研究院与安谋科技&#xff08;中国&#xff09;有限公司&#xff08;以下简称“安谋科技”&#xff09;与正式签署战略合作协议&#xff0c;双方将面向多元AI芯片领域开展算子库优化与适配、编译器与工具链支持、生态系统建设与推广等一系列深入合作&a…

ROG NUC:强大内核激发创意,AI赋能学子科技探索

有这么一款能够激发无限创意、助力科技探索的迷你主机&#xff0c;它以其卓越的性能和迷你的身材成为了成为了ProArt百校行活动中的明星产品&#xff0c;助力广大学子勇敢探索未知&#xff0c;追逐属于自己的科技梦想。它就是ROG NUC 2024&#xff01; 强大性能&#xff0c;创意…

从零玩转CanMV-K230(8)-多线程例程

文章目录 前言一、_thread模块API二、使用示例创建并启动线程停止线程_thread.exit() 总结 前言 K230上不支持threading&#xff0c;只能支持_thread&#xff0c;该模块实现了相应 CPython 模块的子集&#xff0c;CPython 是 Python 编程的参考实现 语言&#xff0c;也是最著名…

yii2 手动添加 phpoffice\phpexcel

1.下载地址&#xff1a;https://github.com/PHPOffice/PHPExcel 2.解压并修改文件名为phpexcel 在yii项目的vendor目录下创建一个文件夹命名为phpoffice 把phpexcel目录放到phpoffic文件夹下 查看vendor\phpoffice\phpexcel目录下会看到这些文件 3.到vendor\composer目录下…