三視圖轉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.pswp.cn/diannao/73194.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73194.shtml
英文地址,請注明出處:http://en.pswp.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…