三视图转stl导出 空心面片体 networkx shapely triangle numpy-stl

from shapely.geometry import Polygon
import triangle
from shapely.ops import unary_union
from stl import mesh
import numpy as np
from collections import defaultdict
from 三维投影线段寻找 import get_adjusted_clusters,get_clusters,get_intersect_lines
import networkx as nx
if __name__ == "__main__":dxf_file_path = 'a.dxf'clusters=get_clusters(dxf_file_path)adjusted_clusters,yz中间面线段集,xy上下面线段集,xz左右面线段集  =get_adjusted_clusters(clusters)intersect_lines=get_intersect_lines(xz左右面线段集,yz中间面线段集,xy上下面线段集)intersect_lines1,intersect_lines2,intersect_lines3 = intersect_lines
# 定义一个函数来消除坐标差异
def align_coordinates(lines, step):aligned_lines = []for line in lines:# 四舍五入坐标到最近的step的倍数aligned_line = ((np.round(line[0][0] / step) * step, np.round(line[0][1] / step) * step, np.round(line[0][2] / step) * step),(np.round(line[1][0] / step) * step, np.round(line[1][1] / step) * step, np.round(line[1][2] / step) * step),)aligned_lines.append(aligned_line)return aligned_lines# 使用函数消除坐标差异,这里以0.2为步长
aligned_intersectlines1 = align_coordinates(intersect_lines1, 0.2)
aligned_intersectlines2 = align_coordinates(intersect_lines2, 0.2)
aligned_intersectlines3 = align_coordinates(intersect_lines3, 0.2)
lines_grouped_by_y = defaultdict(list)
lines_grouped_by_x = defaultdict(list)
lines_grouped_by_z = defaultdict(list)
for line in aligned_intersectlines1:y = line[0][1]  # 假设y值是线段第一个点的y坐标lines_grouped_by_y[y].append(line)
for line in aligned_intersectlines2:z = line[0][2]  # 假设y值是线段第一个点的y坐标lines_grouped_by_z[z].append(line)
for line in aligned_intersectlines3:x = line[0][0]  # 假设y值是线段第一个点的y坐标lines_grouped_by_x[x].append(line)
print(f"y找到了{len(lines_grouped_by_y )}个面")
print(f"z找到了{len(lines_grouped_by_z )}个面")
print(f"x找到了{len(lines_grouped_by_x )}个面")def get_2d_polygon(d,nodes):if d==0:polygon = Polygon([(y,z) for x,y, z in nodes])elif d==1:polygon = Polygon([(x,z) for x,y, z in  nodes])else:polygon = Polygon([(x,y) for x,y, z in  nodes])return polygon
def get_3dvertices_array(d,t, vertices):if d==0:vertices_array = np.array([(t, y, z) for y, z in vertices])elif d==1:vertices_array = np.array([(x, t, z) for x, z in vertices])else :vertices_array = np.array([(x, y, t) for x, y in vertices])return vertices_arraydef polygon_to_mesh(d,t,polygon):vertices = list(polygon.exterior.coords)[:-1]# 创建外环边界的线段列表segments = [[i, i+1] for i in range(0,len(vertices)-1 )]segments.append([len(vertices) - 1, 0]) tridict = {'vertices': vertices,'segments': segments,  # 注意:segments 应该是一个列表的列表                   }tri = triangle.triangulate(tridict, 'p')triangles = tri['triangles']vertices=tri['vertices']# print("  triangles",  triangles)#  print(" vertices2", vertices)faces_array = np.array(triangles)  # STL 文件中的索引是从1开始的vertices_array=get_3dvertices_array(d,t,vertices)# 创建 mesh 对象triangle_mesh = mesh.Mesh(np.zeros(faces_array.shape[0], dtype=mesh.Mesh.dtype))for i, fa in enumerate(faces_array):for j in range(3):triangle_mesh.vectors[i][j] = vertices_array[fa[j], :]return triangle_mesh
def merge_meshes(meshes_to_merge):# 合并所有网格的顶点combined_data = []for m in meshes_to_merge:combined_data.append(m.data)combined_mesh = mesh.Mesh(np.concatenate(combined_data))return combined_mesh
def get_closed_subgraphs_in_open_faces(d,lines_grouped_by):meshes_to_merge=[]for t, items in lines_grouped_by.items():polygons=[]G = nx.Graph()G.add_edges_from(items)outer_ring=Noneinner_rings=[]if not nx.is_connected(G):closed_subgraphs_in_current_faces = []# 对于不闭合的面,找到所有的连通分量for component in nx.connected_components(G):# 创建一个子图,只包含当前连通分量中的节点和边subgraph = G.subgraph(component)# 检查子图是否闭合(形成一个环)if nx.is_eulerian(subgraph):print(f"当前面闭合图形数{len(closed_subgraphs_in_current_faces)}")eulerian_circuit = list(nx.eulerian_circuit(subgraph))# 提取顶点列表subgraph_nodes = [edge[0] for edge in eulerian_circuit]subgraph_polygon = get_2d_polygon(d, subgraph_nodes )# 检查是否有环在另一个环内部for other_polygon in closed_subgraphs_in_current_faces:if subgraph_polygon.within( other_polygon):# 如果内环在外环内,则可以在这里处理(例如,进行三角剖分切割)#用shaply对内外环形成的图形内部做三角剖分切割print("这是一个内环")outer_ring= other_polygoninner_rings.append(subgraph_polygon)breakelif other_polygon.within(subgraph_polygon):print("这是一个外环")outer_ring=subgraph_polygoninner_rings.append( other_polygon)breakelse:print("分开环")closed_subgraphs_in_current_faces.append(subgraph_polygon )                        if outer_ring:inner_rings_union = unary_union(inner_rings)poly=outer_ring.difference(inner_rings_union)#  print("poly",poly)# 提取多边形的顶点和边界vertices = list(poly.exterior.coords)[:-1]# 创建外环边界的线段列表segments = [[i, i+1] for i in range(0,len(vertices)-1 )]segments.append([len(vertices) - 1, 0])  # 连接最后一个和第一个外环顶点# 提取所有内环的顶点,并添加到 vertices 列表中for interior_ring in poly.interiors:vertices.extend(list(interior_ring.coords)[:-1])  # 内环顶点,去掉最后一个重复点# 创建内环边界的线段列表for interior_ring in poly.interiors:start_index = len(vertices) - len(interior_ring.coords)+1for i in range(len(interior_ring.coords) - 2):segments.append([start_index + i, start_index + i + 1])segments.append([start_index + len(interior_ring.coords) - 2, start_index])  # 连接最后一个和第一个内环顶点holes = []for interior_ring in poly.interiors:# 可以使用内环的几何中心点作为洞的位置holes.append(list(interior_ring.centroid.coords)[0])# 创建一个三角形库的输入字典tridict = {'vertices': vertices,'segments': segments,  # 注意:segments 应该是一个列表的列表'holes': holes  # 如果没有内环,则不需要这一项}# print(  'vertices', vertices)#  print( 'segments', segments)#  print(  'holes', holes)# 使用 triangle 进行三角划分tri = triangle.triangulate(tridict, 'p')# 假设 tri['triangles'] 包含了三角划分的结果triangles = tri['triangles']vertices=tri['vertices']# print("  triangles",  triangles)# print(" vertices2", vertices)# 创建一个 numpy 数组来保存顶点和三角形信息#draw_3d_p(vertices_array)faces_array = np.array(triangles)  # STL 文件中的索引是从1开始的vertices_array=get_3dvertices_array(d,t,vertices)# 创建 mesh 对象triangle_mesh = mesh.Mesh(np.zeros(faces_array.shape[0], dtype=mesh.Mesh.dtype))for i, fa in enumerate(faces_array):for j in range(3):triangle_mesh.vectors[i][j] = vertices_array[fa[j], :]meshes_to_merge.append(triangle_mesh)else :polygons.extend(closed_subgraphs_in_current_faces)   else: eulerian_circuit = list(nx.eulerian_circuit(G))subgraph_nodes = [edge[0] for edge in eulerian_circuit]eulerian_polygon = get_2d_polygon(d, subgraph_nodes )polygons.append(eulerian_polygon)for polygon in polygons:triangle_mesh=polygon_to_mesh(d,t,polygon)meshes_to_merge.append(triangle_mesh)#我这里也要生成triangle_mesh然后合并起来一起导出return     meshes_to_merge 
meshes_to_merge0=get_closed_subgraphs_in_open_faces(0,lines_grouped_by_x)
meshes_to_merge1=get_closed_subgraphs_in_open_faces(1,lines_grouped_by_y)
meshes_to_merge2=get_closed_subgraphs_in_open_faces(2,lines_grouped_by_z)meshes_to_merge = []# 将其他列表的内容添加到这个列表中
meshes_to_merge.extend(meshes_to_merge0)
meshes_to_merge.extend(meshes_to_merge1)
meshes_to_merge.extend(meshes_to_merge2)# 现在meshes_to_merge包含了所有网格,可以用来合并
mesh_merged = merge_meshes(meshes_to_merge)mesh_merged.save('merged_output_mesh.stl')


一跑就通,别的ai做得到吗

readdxf: 三视图,工程图转模型

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

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

相关文章

大摩闭门会:250312 学习总结报告

如果图片分辨率不足,可右键图片在新标签打开图片或者下载末尾源文件进行查看 本文只是针对视频做相应学术记录,进行学习讨论使用

【51单片机】程序实验15.DS18B20温度传感器

主要参考学习资料:B站【普中官方】51单片机手把手教学视频 开发资料下载链接:http://www.prechin.cn/gongsixinwen/208.html 单片机套装:普中STC51单片机开发板A4标准版套餐7 目录 DS18B20介绍主要特性内部结构控制时序初始化时序写时序读时序…

ESP32芯片模组方案,设备物联网无线通信,WiFi蓝牙交互控制应用

在当下,物联网正以前所未有的速度席卷全球,从繁华都市的智能建筑,到宁静乡村的智慧农业,从人们日常使用的可穿戴设备,到工业领域复杂精密的自动化生产线,物联网的触角已深入到生活与生产的每一个角落。 而…

Linux第二次练习

1.首先在根下面创建一个名为text的目录 2.在根目录下新建一个text目录,然后在text目录中新建上图的一级目录、二级目录以及三级目录 3.显示/text目录下文件的树形拓扑图 4.将linux树状结构图中列出的所有文件用ll命令列出来

百鸡问题-

百鸡问题 #include<stdio.h> int main(){int n;scanf("%d",&n);int x,y,z;for(x0;x<100;x){for(y0;y<100;y){for(z0;z<100;z){if((x*15y*9z)<(3*n) && ((xyz)100)){printf("x%d,y%d,z%d\n",x,y,z);}}}}return 0; }

LVDS(Low Voltage Differential Signaling)电平详解

一、LVDS的定义与核心特性 LVDS&#xff08;低压差分信号&#xff09;是一种 低功耗、高速、抗干扰 的差分信号传输技术&#xff0c;通过一对互补的电压信号&#xff08;正负端差值&#xff09;传递数据。其核心特性包括&#xff1a; 电气特性 电压摆幅&#xff1a;差分电压约…

【OpenFeign 面试专题】

OpenFeign 面试专题 OpenFeign 的核心原理OpenFeign 如何与 Ribbon、Hystrix 集成Ribbon的负载均衡策略如何自定义 OpenFeign 的请求编码和响应解码OpenFeign 如何传递请求头&#xff08;Header&#xff09;信息OpenFeign 如何处理超时和重试OpenFeign 支持哪些 HTTP 客户端实现…

Adobe Acrobat Pro setting

防火墙断网组织弹窗 Adobe软件突然弹窗“THIS APP HAS BEEN DISABLED”&#xff1f;别慌&#xff0c;几步教你轻松解决&#xff01; 禁用代理 解决Adobe出现This unlicensed Photoshop app has been disabled.禁止使用 rules:- DOMAIN-KEYWORD,adobe,REJECT

搜索插入位置(js实现,LeetCode:35)

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入…

5. 前后端实现文件上传与解析

1. 说明 在实际开发中&#xff0c;比较常见的一个功能是需要在前端页面中选择系统中的某个文件上传到服务器中进行解析&#xff0c;解析后的文件内容可以用来在服务器中当作参数&#xff0c;或者传递给其它组件使用&#xff0c;或者需要存储到数据库中。所以本文就提供一种方式…

《灵珠觉醒:从零到算法金仙的C++修炼》卷三·天劫试炼(32)万剑归宗破妖阵 - 最长递增子序列(LIS)

《灵珠觉醒:从零到算法金仙的C++修炼》卷三天劫试炼(32)万剑归宗破妖阵 - 最长递增子序列(LIS) 哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的万剑谷,谷中有一座巨大的万剑归宗剑阵,剑阵闪烁着神秘的光芒。谷口有一块巨大的石碑,上面刻着一行文字:…

【redis】使用redis作为缓存时所注意事项

缓存更新策略 在 Redis 缓存中&#xff0c;缓存的更新策略主要有**定期生成&#xff08;定时更新&#xff09;和实时生成&#xff08;即时更新&#xff09;**两种方式。不同的策略适用于不同的业务场景&#xff0c;涉及性能、数据一致性和系统负载等方面的权衡。 1. 定期生成&…

计算机网络:计算机网络的分类

按分布范围分类&#xff1a;广域网&#xff0c;城域网&#xff0c;局域网&#xff0c;个域网 按传输技术分类&#xff1a;广播式网络&#xff0c;点对点网络 按拓扑结构分类&#xff1a;总线型&#xff0c;环形&#xff0c;星形&#xff0c;网状 按传输介质分类&#xff1a;…

解决pip安装uv时下载速度慢

验证优化效果 方案 1&#xff1a;临时使用国内镜像源&#xff08;推荐&#xff09; pip install uv -i https://pypi.tuna.tsinghua.edu.cn/simple 速度提升&#xff1a;镜像源服务器位于国内&#xff0c;带宽充足&#xff0c;通常可达 1-10MB/s 支持源列表&#xff1a; # 清…

SpringCloud Alibaba——入门简介

一、是什么 &#xff08;1&#xff09;诞生 2018.10.31&#xff0c;Spring Cloud Alibaba 正式入驻了 Spring Cloud 官方孵化器&#xff0c;并在 Maven 中央库发布了第一个版本 &#xff08;2&#xff09;介绍 &#xff08;3&#xff09;&#xff1f;何为必须组件 二、能干嘛…

Python完全指南:从基础到实践的编程艺术

引言&#xff1a;数字时代的瑞士军刀 在人工智能与大数据浪潮中&#xff0c;Python如同编程世界的"瑞士军刀"&#xff0c;以其优雅的语法和强大的生态征服全球开发者。本文将从语言哲学到实战应用&#xff0c;为您展开Python编程的全景画卷&#xff0c;揭示这门语言…

Docker 运行 GPUStack 的详细教程

GPUStack GPUStack 是一个用于运行 AI 模型的开源 GPU 集群管理器。它具有广泛的硬件兼容性&#xff0c;支持多种品牌的 GPU&#xff0c;并能在 Apple MacBook、Windows PC 和 Linux 服务器上运行。GPUStack 支持各种 AI 模型&#xff0c;包括大型语言模型&#xff08;LLMs&am…

完整例子和调用关系qt OpenGL

项目结构 首先&#xff0c;你需要在 Qt 项目中创建一个类&#xff0c;继承自 QOpenGLWidget 来进行 OpenGL 渲染。文件结构如下&#xff1a; - main.cpp - MyOpenGLWidget.h - MyOpenGLWidget.cpp - vertex_shader.glsl - fragment_shader.glsl 1. main.cpp 这是 Qt 项目的入口…

VSCode 配置优化指南:打造极致高效的前端开发环境

VSCode 配置优化指南&#xff1a;打造极致高效的前端开发环境 一、基础环境配置&#xff1a;让开发更流畅 1. 性能优化设置 // settings.json {"files.autoSave": "afterDelay", // 自动保存&#xff08;延迟1秒&#xff09;"files.exclud…

源IP泄露后如何涅槃重生?高可用架构与自动化防御体系设计

一、架构层解决方案 1. 高防代理架构设计 推荐架构&#xff1a; 用户 → CDN&#xff08;缓存静态资源&#xff09; → 高防IP&#xff08;流量清洗&#xff09; → 源站集群&#xff08;真实IP隐藏&#xff09; ↑ Web应用防火墙&#xff08;WAF&#xff09; 实施要点&a…