H5网页三维CAD中创建一个装配体

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
注册配置 MSE Nacos/ZooKeeper,182元/月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
简介: 本文介绍了如何使用mxcad3d创建小车装配体模型。通过官方教程搭建项目环境,使用API创建车轮、车轴、车身等部件,并通过实例引用与组合实现装配体的构建。最终通过按钮触发绘制小车模型,展示其三维效果。

前言

在网页CAD中有些相同的零件可以只建一个模型实例,其余用到的地方均为实例的引用,然后将引用组合起来形成装配体。mxcad3d提供了丰富的三维建模功能和便捷的API,接下来聊一下如何利用mxcad3d来创建小车装配体模型。
图片1.png

快速入门

首先我们需要学习mxcad的基本使用方法,可以通过官方的入门教程来搭建一个最基本的项目模板。
开发环境准备(对前端开发不熟悉的一定要看)安装Node.js和VS Code,然后创建最基本的mxcad开发项目API文档使用说明

本次教程最后完成的完整测试项目压缩包(https://gitee.com/mxcadx/mxcad_docs/tree/master/examples3D/Test3dAssemblyCar.7z) ,压缩包下载解压后需要在项目目录下打开cmd命令行,然后在命令行中执行npm install来安装依赖,然后再按照本教程中的方式来运行项目查看效果。

编写创建装配体小车的代码

1.按照上面前言中第2条中的方式,根据官方快速入门教程来创建一个名为Test3dAssemblyCar的项目,如下图:
图片2.png

2.编写绘制装配体小车的代码
在index.html中插入一个按钮"绘制装配体小车", index.html的完整代码如下:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <title>vite use mxcad</title>  
</head>  
<body>  
    <div style="height: 800px; overflow: hidden;"> <canvas id="myCanvas"></canvas></div>  
    <button>绘制装配体小车</button>  
    <script type="module" src="./src/index.ts"></script>  
</body>  
</html>

在src/index.ts中编写绘制装配体小车的函数,src/index.ts的完整代码如下:

import {
    MdGe, Mx3dGeAxis, Mx3dGeColor, Mx3dGeCSYSR, Mx3dGeDir, Mx3dGeLocation, Mx3dGePoint, Mx3dGeTrsf, Mx3dGeVec, Mx3dMkCylinder, Mx3dMkFace, Mx3dMkPolygon, Mx3dMkPrism, MxCAD3DObject } from "mxcad"\
// 创建mxcad3d对象\
const mxcad3d = new MxCAD3DObject()\
// 初始化mxcad3d对象\
mxcad3d.create({
   \
    // canvas元素的css选择器字符串(示例中是id选择器),或canvas元素对象\
    canvas: "#myCanvas",\
    // 获取加载wasm相关文件(wasm/js/worker.js)路径位置\
    locateFile: (fileName)=> new URL(`/node_modules/mxcad/dist/wasm/3d/${
     fileName}`, import.meta.url).href,\
})\
// 初始化完成\
mxcad3d.on("init", ()=>{
   \
    console.log("初始化完成");\
});\
function drawAssemblyCar() {
   \
  // 轮子形状\
  const pt = new Mx3dGePoint(0, 0, 0);  // 中心点\
  const dir = new Mx3dGeDir(0, 0, 1); // 方向\
  const csysr = new Mx3dGeCSYSR(pt, dir); // 根据点和方向创建一个右手坐标系\
  const wheel = new Mx3dMkCylinder(csysr, 20, 10);  // 轮子(宽扁的圆柱体)\
  let wheelShape = wheel.Shape(); // 获取轮子拓扑形状\
  // 轴形状\
  const axle = new Mx3dMkCylinder(csysr, 5, 100); // 轴(细长的圆柱体)\
  const axleShape = axle.Shape(); // 获取轴拓扑形状\
  wheelShape = wheelShape.cut(axleShape); // 切割掉轮子的轴孔\
  // 车体形状\
  const bodyPts:Mx3dGePoint\[] = \[]\
  bodyPts.push(new Mx3dGePoint(0, 0, 0));\
  bodyPts.push(new Mx3dGePoint(0, 50, 0));\
  bodyPts.push(new Mx3dGePoint(160, 50, 0));\
  bodyPts.push(new Mx3dGePoint(160, 0, 0));\
  const bodyPoly = new Mx3dMkPolygon(); // 创建多段线(车体的截面轮廓)\
  bodyPts.forEach((pt) => {
   \
    bodyPoly.Add(pt);\
  });\
  bodyPoly.Close(); // 闭合多段线\
  const bodyWire = bodyPoly.Wire(); // 获取多段线(车体的截面轮廓)的拓扑Wire\
  const bodyMkFace = new Mx3dMkFace(bodyWire); // 用Wire生成面\
  const bodyFace = bodyMkFace.Face(); // 获取面\
  const bodyPrism = new Mx3dMkPrism(bodyFace, new Mx3dGeVec(0, 0, 100)); // 用面生成车体实体\
  let bodyShape = bodyPrism.Shape(); // 获取车体实体形状\
  bodyShape.TranslateBy2Points(new Mx3dGePoint(30, 0, 0), new Mx3dGePoint(0, 0, 0)); // 移动到合适位置,方便装配\
  const wheelForCut = new Mx3dMkCylinder(csysr, 25, 15); // 车体嵌入车轮的地方,用车体切掉,用于放入轮子\
  // 以下是切出四个放轮子的空间\
  const wheelForCutShape = wheelForCut.Shape();\
  bodyShape = bodyShape.cut(wheelForCutShape);\
  bodyShape = bodyShape.cut(wheelForCutShape.TranslatedByVec(new Mx3dGeVec(0, 0, 85)));\
  bodyShape = bodyShape.cut(wheelForCutShape.TranslatedByVec(new Mx3dGeVec(100, 0, 0)));\
  bodyShape = bodyShape.cut(wheelForCutShape.TranslatedByVec(new Mx3dGeVec(100, 0, 85)));\
  const axleForCut = new Mx3dMkCylinder(csysr, 6, 100); // 车体嵌入轴的地方,用车体切掉,用于放入轴\
  // 以下是切出两个放轴的空间\
  const axleForCutShape = axleForCut.Shape();\
  bodyShape = bodyShape.cut(axleForCutShape);\
  bodyShape = bodyShape.cut(axleForCutShape.TranslatedByVec(new Mx3dGeVec(100, 0, 0)));\
  // 获取文档\
  const doc = mxcad3d.getDocument();\
  // 车子装配体标签\
  const carLabel = doc.addShapeLabel();\
  // 轮子实例标签\
  const wheelLabel = doc.addShapeLabel();\
  // 车轴实例标签\
  const axleLabel = doc.addShapeLabel();\
  // 轮轴装配体实例标签\
  const wheelAxleLabel = doc.addShapeLabel();\
  // 车壳实例标签\
  const bodyLabel = doc.addShapeLabel();\
  // 轮子、轴、车体形状都添加到模型文档的标签中(同时为不同的形状设置不同的颜色)\
  wheelLabel.setShape(wheelShape);\
  wheelLabel.setColor(new Mx3dGeColor(MdGe.MxNameOfColor.Color\_NOC\_BLACK));\
  axleLabel.setShape(axleShape);\
  axleLabel.setColor(new Mx3dGeColor(MdGe.MxNameOfColor.Color\_NOC\_RED));\
  bodyLabel.setShape(bodyShape);\
  bodyLabel.setColor(new Mx3dGeColor(MdGe.MxNameOfColor.Color\_NOC\_BLUE2));\
  // 轮轴装配体(轮轴装配体需要两个轮子、一个轴)\
  wheelAxleLabel.addComponent(wheelLabel, new Mx3dGeLocation()); // 添加第一个轮子,没有位置(原位置,轮子模型创建的位置)\
  const wheel\_2\_trsf = new Mx3dGeTrsf();\
  wheel\_2\_trsf.SetTranslationPart(new Mx3dGeVec(0, 0, 90));\
  wheelAxleLabel.addComponent(wheelLabel, new Mx3dGeLocation(wheel\_2\_trsf)); // 添加第二个轮子,有位置(向Z轴正方向移动90之后的位置)\
  wheelAxleLabel.addComponent(axleLabel, new Mx3dGeLocation()); // 添加轴,没有位置(原位置,轴模型创建的位置)\
  // 车子装配体(车子装配体需要两个轮轴装配体、一个车体)\
  const wheelAxle\_1\_trsf = new Mx3dGeTrsf();\
  wheelAxle\_1\_trsf.SetRotation(new Mx3dGeAxis(new Mx3dGePoint(0, 0, 0), new Mx3dGeDir(1, 0, 0)), Math.PI / 2);\
  carLabel.addComponent(wheelAxleLabel, new Mx3dGeLocation(wheelAxle\_1\_trsf)); // 添加第一个轮轴装配体,有位置(绕X轴旋转90度之后的位置)\
  let wheelAxle\_2\_trsf = new Mx3dGeTrsf();\
  wheelAxle\_2\_trsf.SetTranslationPart(new Mx3dGeVec(100, 0, 0));\
  wheelAxle\_2\_trsf = wheelAxle\_2\_trsf.Multiplied(wheelAxle\_1\_trsf); // 矩阵相乘,得到第二个轮轴装配体的位置,相乘后的矩阵代表先绕X轴旋转90度,然后再向X轴正方形平移100\
  carLabel.addComponent(wheelAxleLabel, new Mx3dGeLocation(wheelAxle\_2\_trsf)); // 添加第二个轮轴装配体,有位置(绕X轴旋转90度,然后再向X轴正方形平移100之后的位置)\
  carLabel.addComponent(bodyLabel, new Mx3dGeLocation(wheelAxle\_1\_trsf)); // 添加车体,有位置(绕X轴旋转90度之后的位置)\
  // 更新新图显示模型,会将文档中的模型显示到当前视图中\
  mxcad3d.update();\
}\
// 给button添加点击事件,点击后调用drawAssemblyCar函数\
// 立即执行函数\
(function addEventToButton(){
   \
  const btn = document.querySelector("button");\
  if (btn) {
   \
    btn.addEventListener("click", () => {
   \
      drawAssemblyCar();\
    });\
  }\
})()

按照官方快速入门教程,新建终端,运行npx vite命令来运行项目,观察效果如下图:
图片3.png

相关文章
|
10月前
|
前端开发 JavaScript API
(前端3D模型开发)网页三维CAD中加载和保存STEP模型
本文介绍了如何使用`mxcad3d`库在网页上实现STEP格式三维模型的导入与导出。首先,通过官方教程搭建基本项目环境,了解核心对象如MxCAD3DObject、Mx3dDbDocument等的使用方法。接着,编写了加载和保存STEP模型的具体代码,包括HTML界面设计和TypeScript逻辑实现。最后,通过运行项目验证功能,展示了从模型加载到保存的全过程。此外,`mxcad3d`还支持多种其他格式的三维模型文件操作。
774 128
|
机器学习/深度学习 算法 搜索推荐
精确率(Precision)和召回率(Recall)
精确率(Precision)和召回率(Recall)是用于评估分类模型性能的指标。它们通常用于二分类问题,例如判断一个样本是正例(Positive)还是负例(Negative)。
7328 0
|
微服务 数据库 持续交付
带你读《微服务架构设计模式》之一:逃离单体地狱
本书中,微服务架构的先驱、Java 开发者社区的意见领袖 Chris Richardson 收集、分类并解释了 44 个架构设计模式,这些模式用来解决诸如服务拆分、事务管理、查询和跨服务通信等难题。本书不仅仅是一个模式目录,还提供了经验驱动的建议,以帮助你设计、实现、测试和部署基于微服务的应用程序。
10849 1
|
存储 缓存 监控
一文读懂分布式架构知识体系(内含超全核心知识大图)
7月9日 19:00-21:30 阿里云开发者社区首场“Offer 5000”直播开启!15位团队技术大牛在线招人,更有《阿里云技术面试红宝书》助你拿下Offer!马上投递简历:https://developer.aliyun.com/special/offerday01
19460 0
|
12月前
|
负载均衡 安全 网络协议
DDOS攻击与防护
DDoS攻击通过大量合法请求占用目标服务器资源,导致正常用户无法访问。常见类型包括洪水攻击(如SYN Flood和UDP Flood)和放大攻击。其危害包括服务中断、经济损失及数据泄露。防护措施涵盖网络层面(流量清洗、带宽扩容、负载均衡)、系统层面(优化配置、安装防护软件、更新补丁)和应用层面(验证码、限速策略、动态IP封禁)。
1916 1
|
存储 缓存 数据挖掘
阿里云服务器通用算力型u1与经济型e实例对比与常见问题参考
阿里云的通用算力型u1与经济型e实例均以实惠的价格提供云服务,但各有侧重。经济型e实例采用共享模式,适用于个人开发者、学生及小微企业,适合搭建网站、开发测试等轻量级应用;通用算力型u1实例则提供独享资源,更适合对稳定性和性能有一定要求的企业级应用,如中大型网站、数据分析等场景。e实例基于Intel® Xeon® Platinum处理器,提供ESSD Entry云盘,价格亲民;u1实例同样支持ESSD系列云盘,具备更高性价比和稳定算力保障。选择时,个人用户可优先考虑经济型e实例,追求性价比;企业用户则推荐使用通用算力型u1实例,以获得更佳的性能和服务质量保证。
369 4
阿里云服务器通用算力型u1与经济型e实例对比与常见问题参考
Cannot access ‘androidx.lifecycle.HasDefaultViewModelProviderFactory‘ which is a supertype of ‘com.e
今天创建了个项目,突然出现了这样的问题,怎么处理都没用,网上找了一堆没发现答案,故此记录。
447 0
Cannot access ‘androidx.lifecycle.HasDefaultViewModelProviderFactory‘ which is a supertype of ‘com.e
|
7月前
|
数据采集 传感器 算法
从数据中挖掘洞见:初探数据挖掘的艺术与科学
从数据中挖掘洞见:初探数据挖掘的艺术与科学
156 11
|
自然语言处理 IDE 开发工具
通义灵码编程智能体上线,支持Qwen3模型
通义灵码最全使用指南,一键收藏。
128893 31
通义灵码编程智能体上线,支持Qwen3模型
|
9月前
|
存储 Java 数据库连接
时序数据库TDengine 3.3.5.0 发布:高并发支持与增量备份功能引领新升级
TDengine 3.3.5.0 版本正式发布,带来多项更新与优化。新特性包括提升 MQTT 稳定性和高并发性能、新增 taosX 增量备份与恢复、支持 JDBC 和 Rust 连接器 STMT2 接口、灵活配置 Grafana Dashboard 等。性能优化涵盖查询内存管控、多级存储迁移、强密码策略等,全面提升时序数据管理的效率和可靠性。欢迎下载体验并提出宝贵意见。
236 5