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

chili3d 笔记15 生成投影工程图

这东西哪怕加载一下启动都会慢半分钟不止 

注册3件套

 接下来想办法获得所选物体的所有edge起点终点信息


您询问的是如何获得所选物体的所有edge(边)的起点终点信息。根据代码库分析,这涉及到Chili3d的形状系统和网格数据处理。

获取Edge起点终点信息的方法

在Chili3d中,有几种方式可以获取edge的起点终点信息:

1. 通过IEdge接口获取几何信息

每个edge都实现了IEdge接口,可以通过curve方法获取几何信息: shape.ts:50-57

具体实现中,OccEdge类提供了curve方法来获取边的几何曲线: shape.ts:275-280

2. 通过网格数据获取顶点位置

对于可视化目的,edge的起点终点信息存储在网格数据中。EdgeMeshData结构包含了位置信息: meshData.ts:105-119

3. 从形状中查找所有edges

要获取所选物体的所有edges,可以使用findSubShapes方法: shape.ts:40

4. 网格生成过程中的edge处理

在C++层面,EdgeMesher类负责生成edge的网格数据,包含起点终点信息: mesher.cpp:107-145

网格数据结构定义了edge的位置和分组信息: mesher.cpp:82-88

实际使用示例

在测试代码中可以看到edge网格数据的结构,包含起点终点的坐标: testEdge.ts:92-109

Notes

要获取所选物体的所有edge起点终点信息,您需要:

  1. 使用findSubShapes(ShapeType.Edge)获取所有edges
  2. 对每个edge调用mesh.edges.positions获取顶点坐标数据
  3. 或者使用curve()方法获取几何曲线,然后计算起点终点

网格数据中的positions是Float32Array格式,按照[x1,y1,z1,x2,y2,z2,...]的顺序存储顶点坐标。

private draw_drawing(app: IApplication) {  const document = app.activeView?.document;  if (!document) {  Logger.info("document is null");  return;  }  const geometries = document.selection.getSelectedNodes();  const entities = geometries.filter((x) => x instanceof GeometryNode);  for (const entity of entities) {  const mesh = entity.mesh;  // 获取实体的所有边顶点位置  if (mesh.edges?.positions) {  const positions = mesh.edges.positions;  Logger.info(`实体 ${entity.name} 的边数量: ${positions.length / 6}`);  // 遍历所有边的起点终点  for (let i = 0; i < positions.length; i += 6) {  const start = {   x: positions[i],   y: positions[i+1],   z: positions[i+2]   };  const end = {   x: positions[i+3],   y: positions[i+4],   z: positions[i+5]   };  Logger.info(`边 ${i/6 + 1}: 起点(${start.x}, ${start.y}, ${start.z}) -> 终点(${end.x}, ${end.y}, ${end.z})`);  }  }  }  
}

 

就差乘个投影矩阵画出来了

有问题但是起码画了

import { GeometryNode, IApplication, Logger, PubSub } from "chili-core";export class njsgcs_drawingView extends HTMLElement {  private viewportCanvas2d: HTMLCanvasElement | null = null;  private app: IApplication | null = null;  constructor() {  super();  PubSub.default.sub("njsgcs_drawview", (app: IApplication) => {  Logger.info("njsgcs_drawview event triggered");  if (this.viewportCanvas2d) {this.removeChild(this.viewportCanvas2d);this.viewportCanvas2d = null;}this.app = app;  const canvas = this.createCanvas();  this.appendChild(canvas);  });  }  private createCanvas() {  if (!this.viewportCanvas2d) {  this.viewportCanvas2d = document.createElement('canvas');  this.viewportCanvas2d.width = 900;  this.viewportCanvas2d.height = 600;  this.viewportCanvas2d.style.border = '1px solid #000';  const ctx = this.viewportCanvas2d.getContext('2d');  if (ctx) {  const points = this.getSelectedEntityEdgePoints();  if (points.length > 0) {  // 清空画布  ctx.clearRect(0, 0, 900, 600);  ctx.strokeStyle = 'black';  ctx.lineWidth = 1;  // 绘制三个视图  this.drawFrontView(ctx, points, 150, 150);   // 正视图  this.drawTopView(ctx, points, 450, 150);     // 俯视图    this.drawRightView(ctx, points, 150, 400);   // 右视图  }  }  }  return this.viewportCanvas2d;  }  private getSelectedEntityEdgePoints(): number[] {  const document = this.app!.activeView?.document;  if (!document) return [];  const geometries = document.selection.getSelectedNodes();  const entities = geometries.filter((x) => x instanceof GeometryNode);  let allPoints: number[] = [];  for (const entity of entities) {  const mesh = entity.mesh;  if (mesh.edges?.positions) {  // 应用变换矩阵获取世界坐标  const worldPositions = entity.transform.ofPoints(mesh.edges.positions);  allPoints.push(...worldPositions);  }  }  return allPoints;  }  // 正视图:XY平面投影  private drawFrontView(ctx: CanvasRenderingContext2D, points: number[], offsetX: number, offsetY: number) {  const edges = this.extractEdgesFromPoints(points);  const projectedEdges = edges.map(edge => ({  start: { x: edge.start.x, y: edge.start.y },  end: { x: edge.end.x, y: edge.end.y }  }));  this.drawView(ctx, projectedEdges, offsetX, offsetY, "正视图");  }  // 俯视图:XZ平面投影(Z映射到Y轴)  private drawTopView(ctx: CanvasRenderingContext2D, points: number[], offsetX: number, offsetY: number) {  const edges = this.extractEdgesFromPoints(points);  const projectedEdges = edges.map(edge => ({  start: { x: edge.start.x, y: edge.start.z },  end: { x: edge.end.x, y: edge.end.z }  }));  this.drawView(ctx, projectedEdges, offsetX, offsetY, "俯视图");  }  // 右视图:YZ平面投影(Z映射到X轴)  private drawRightView(ctx: CanvasRenderingContext2D, points: number[], offsetX: number, offsetY: number) {  const edges = this.extractEdgesFromPoints(points);  const projectedEdges = edges.map(edge => ({  start: { x: edge.start.z, y: edge.start.y },  end: { x: edge.end.z, y: edge.end.y }  }));  this.drawView(ctx, projectedEdges, offsetX, offsetY, "右视图");  }  // 从点数组中提取边信息  private extractEdgesFromPoints(points: number[]): Array<{start: {x: number, y: number, z: number}, end: {x: number, y: number, z: number}}> {  const edges = [];  for (let i = 0; i < points.length; i += 6) {  edges.push({  start: { x: points[i], y: points[i + 1], z: points[i + 2] },  end: { x: points[i + 3], y: points[i + 4], z: points[i + 5] }  });  }  return edges;  }  // 绘制单个视图  private drawView(ctx: CanvasRenderingContext2D, edges: Array<{start: {x: number, y: number}, end: {x: number, y: number}}>,   offsetX: number, offsetY: number, title: string) {  if (edges.length === 0) return;  // 过滤重复边  const uniqueEdges = this.filterDuplicateEdges(edges);  // 计算边界框  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;  for (const edge of uniqueEdges) {  minX = Math.min(minX, edge.start.x, edge.end.x);  maxX = Math.max(maxX, edge.start.x, edge.end.x);  minY = Math.min(minY, edge.start.y, edge.end.y);  maxY = Math.max(maxY, edge.start.y, edge.end.y);  }  // 计算缩放比例  const viewSize = 100;  const scaleX = (maxX - minX) > 0 ? viewSize / (maxX - minX) : 1;  const scaleY = (maxY - minY) > 0 ? viewSize / (maxY - minY) : 1;  const scale = Math.min(scaleX, scaleY) * 0.8; // 留一些边距  const centerX = (minX + maxX) / 2;  const centerY = (minY + maxY) / 2;  // 绘制标题  ctx.fillStyle = 'black';  ctx.font = '12px Arial';  ctx.fillText(title, offsetX - 20, offsetY - 70);  // 绘制边  ctx.strokeStyle = 'blue';  ctx.lineWidth = 1;  for (const edge of uniqueEdges) {  const x1 = (edge.start.x - centerX) * scale + offsetX;  const y1 = -(edge.start.y - centerY) * scale + offsetY; // Y轴翻转  const x2 = (edge.end.x - centerX) * scale + offsetX;  const y2 = -(edge.end.y - centerY) * scale + offsetY;   // Y轴翻转  ctx.beginPath();  ctx.moveTo(x1, y1);  ctx.lineTo(x2, y2);  ctx.stroke();  }  }  // 过滤重复边  private filterDuplicateEdges(edges: Array<{start: {x: number, y: number}, end: {x: number, y: number}}>): Array<{start: {x: number, y: number}, end: {x: number, y: number}}> {  const uniqueEdges: Array<{ start: { x: number; y: number }, end: { x: number; y: number } }> = [];  const tolerance = 0.001;  for (const edge of edges) {  const isDuplicate = uniqueEdges.some(existingEdge =>   this.areEdgesEqual(edge, existingEdge, tolerance)  );  if (!isDuplicate) {  uniqueEdges.push(edge);  }  }  return uniqueEdges;  }  // 判断两条边是否相等(考虑方向)  private areEdgesEqual(edge1: {start: {x: number, y: number}, end: {x: number, y: number}},   edge2: {start: {x: number, y: number}, end: {x: number, y: number}},   tolerance: number): boolean {  // 正向比较  const dist1 = Math.abs(edge1.start.x - edge2.start.x) + Math.abs(edge1.start.y - edge2.start.y) +  Math.abs(edge1.end.x - edge2.end.x) + Math.abs(edge1.end.y - edge2.end.y);  // 反向比较  const dist2 = Math.abs(edge1.start.x - edge2.end.x) + Math.abs(edge1.start.y - edge2.end.y) +  Math.abs(edge1.end.x - edge2.start.x) + Math.abs(edge1.end.y - edge2.start.y);  return dist1 < tolerance || dist2 < tolerance;  }  
}  customElements.define('njsgcs-drawing-view', njsgcs_drawingView);

2025-05-28 16-34-27 chili3d 生成投影视图

还要分实线虚线

相关文章:

  • 【MySQL】第12节|MySQL 8.0 主从复制原理分析与实战(二)
  • 基于BERT和GPT2的实现来理解Transformer的结构和原理
  • UART通信HAL库API
  • Pydantic 是一个 Python 库,核心是做数据验证、设置管理和数据转换
  • 知行之桥如何将消息推送到钉钉群?
  • php中配置variables_order详解
  • 监控 Oracle Cloud 负载均衡器:使用 Applications Manager 释放最佳性能
  • 使用Nginx + Keepalived配置实现Web站点高可用方案
  • UE5 编辑器工具蓝图
  • Chroma 向量数据库使用示例
  • 可视化图解算法46:用两个栈实现队列
  • 6.4.2_3最短路径问题_Floyd算法
  • Open3D上可视化Nuscenes 数据集
  • 操作系统(Operator System)
  • 【Python】 -- 趣味代码 - 佩奇
  • 数据结构-代码总结
  • golang 柯里化(Currying)
  • 嵌入式开发学习(第二阶段 C语言笔记)
  • Golang | gRPC索引服务
  • Java jdk8版本特性(未完成版)
  • wordpress上传文件大小/seo sem是什么意思
  • 网站建设的相关技术/竞价排名深度解析
  • 安徽省建设厅网站资料下载/seo优化快速排名
  • 长春网站建设方案服务/seo实战密码电子版
  • 有什么做任务拿钱的网站/成都网站seo诊断
  • 找工作附近上8小时的双休/广州seo排名收费