Python通過(guò)dxfgrabber庫(kù)實(shí)現(xiàn)獲取CAD信息
前言
最近需要通過(guò)python來(lái)獲取cad模型的內(nèi)容信息,然而筆者也沒(méi)學(xué)過(guò)python,只能用過(guò)查詢(xún)+動(dòng)手摸索一步一步進(jìn)行下去,然后通過(guò)dxfgrabber進(jìn)行本次的學(xué)習(xí)與實(shí)踐,在通過(guò)Java去執(zhí)行腳本獲取值。以下就是筆者對(duì)本次學(xué)習(xí)與工作的記錄。
dxfgrabber庫(kù)
dxfgrabber 是一個(gè) Python 庫(kù),用于讀取和解析 AutoCAD DXF(Drawing Exchange Format)文件。DXF 是一種常用的 CAD 文件格式,用于存儲(chǔ)和交換二維和三維圖形數(shù)據(jù)。dxfgrabber 提供了一個(gè)簡(jiǎn)單而強(qiáng)大的接口,用于從 DXF 文件中提取圖形對(duì)象的信息,如線(xiàn)段、圓、多邊形、文本等。它可以讀取 DXF 文件的實(shí)體(entities)、圖層(layers)、塊(blocks)、屬性(attributes)等元素,并提供了方便的方法來(lái)訪(fǎng)問(wèn)和操作這些數(shù)據(jù)。使用 dxfgrabber,你可以編寫(xiě) Python 腳本來(lái)讀取和分析 DXF 文件,提取其中的幾何信息、屬性數(shù)據(jù)或其他圖形元素。這使得你可以輕松地處理和轉(zhuǎn)換 DXF 數(shù)據(jù),進(jìn)行自動(dòng)化的 CAD 數(shù)據(jù)處理、生成報(bào)告、可視化或其他相關(guān)任務(wù)??傊琩xfgrabber 是一個(gè)方便的工具,使你能夠輕松地處理和分析 DXF 文件,從中提取所需的圖形和屬性信息。
具體內(nèi)容與api可以看一下官方文檔:dxfgrabber — dxfgrabber 1.0.0 documentation
DXF的內(nèi)容
在解析CAD模型時(shí),我們是通過(guò)轉(zhuǎn)成DXF文件,通過(guò)對(duì)DXF文件進(jìn)行解析,從而得到所需的數(shù)據(jù)集。
我們通過(guò)讀取.dxf文件獲得一個(gè)dxf對(duì)象,這里我準(zhǔn)備了一個(gè)dxf文件
dxf = dxfgrabber.readfile("D:\\Code\\draft.dxf")
接著我們?cè)谙乱恍写騻€(gè)斷點(diǎn),可以查看讀到得文件得對(duì)象都有什么屬性。
從Expression中就已經(jīng)可以之間看到有那些數(shù)據(jù)了。
dxfgrabber中的entities
先看一下entities,在 dxfgrabber 中,entities 是一個(gè) DXF 文件中所有實(shí)體對(duì)象的集合。每個(gè)實(shí)體對(duì)象都具有一組特定的屬性,可以通過(guò)訪(fǎng)問(wèn)這些屬性來(lái)獲取有關(guān)實(shí)體的信息,他的基類(lèi)是Shape
通過(guò)斷點(diǎn)查看屬性,但是不管是實(shí)體內(nèi)部還是實(shí)體各種類(lèi)型下的屬性,不同的DXF文件可能包含其他自定義屬性或應(yīng)用特定的標(biāo)準(zhǔn)屬性,這取決于創(chuàng)建DXF文件的工具和設(shè)置。
但是,不同得圖形類(lèi)型就會(huì)呈現(xiàn)不同的數(shù)據(jù)屬性。
LINE類(lèi)型的數(shù)據(jù)
首先看一下line類(lèi)型的數(shù)據(jù),通過(guò)expression可以看出線(xiàn)形的某些數(shù)據(jù),其中start和end是其起始坐標(biāo)。以及顏色等其他屬性。
這里我調(diào)用其方法打印出來(lái)每條線(xiàn)的起始位置坐標(biāo),這個(gè)如果是需要繪制那種特定的路線(xiàn),那么可以根據(jù)他的顏色值來(lái)進(jìn)行判斷。如下代碼,我通過(guò)每個(gè)實(shí)體的dxftype去判斷是何種類(lèi)型,以下只是判斷了線(xiàn)型,并且獲取其起點(diǎn)坐標(biāo),以及顏色數(shù)值。
# -*- coding: utf-8 -*- import dxfgrabber def get_line_coordinates(): dxf = dxfgrabber.readfile("D:\\Code\\draft.dxf") coordinates = [] for e in dxf.entities: if e.dxftype == 'LINE': start_x = e.start[0] start_y = e.start[1] start_z = e.start[2] color = e.color coordinates.append((start_x, start_y, start_z)) print(u"顏色:" + str(color) + u", " + e.dxftype + u" - 起點(diǎn)坐標(biāo):" + str(start_x) + u", " + str(start_y) + u", " + str(start_z)); return coordinates line_coordinates = get_line_coordinates() print(line_coordinates)
結(jié)果如下的打印輸出
6547608e022&title=&width=810.6666666666666)
CIRCLE類(lèi)型的數(shù)據(jù)
通過(guò)斷點(diǎn)的方式來(lái)查看circle類(lèi)型中存在著那些屬性,其中最常見(jiàn)的就是以下屬性:
- center:圓心坐標(biāo),表示為一個(gè)包含X、Y、Z值的元組或點(diǎn)對(duì)象。
- radius:圓的半徑,表示為一個(gè)浮點(diǎn)數(shù)。
- thickness:圓的厚度,表示為一個(gè)浮點(diǎn)數(shù)。通常在2D繪圖中為0。
- color:圓的顏色,表示為一個(gè)整數(shù)值。可以使用顏色表進(jìn)行解釋。
- layer:圓所在的圖層名稱(chēng),表示為一個(gè)字符串。
- linetype:圓的線(xiàn)型名稱(chēng),表示為一個(gè)字符串。例如,"CONTINUOUS"表示實(shí)線(xiàn)。
- linetype_scale:圓的線(xiàn)型比例,表示為一個(gè)浮點(diǎn)數(shù)。
- extrusion:圓的擠壓方向,表示為一個(gè)包含X、Y、Z值的元組或向量對(duì)象。通常在2D繪圖中為(0, 0, 1)。
- start_angle:圓的起始角度,表示為一個(gè)浮點(diǎn)數(shù)。默認(rèn)為0度,以弧度為單位。
- end_angle:圓的結(jié)束角度,表示為一個(gè)浮點(diǎn)數(shù)。默認(rèn)為2π(360度),以弧度為單位。
這里接下來(lái)就不演示代碼了,需要查看屬性可以通過(guò)斷點(diǎn)的形式去查看,通過(guò)點(diǎn)屬性的方式得到相應(yīng)的值,就只是介紹可能存在的屬性字段。
POLYLINE類(lèi)型的數(shù)據(jù)
每個(gè)實(shí)體類(lèi)型為POLYLINE(多段線(xiàn))的實(shí)體對(duì)象具有以下常見(jiàn)屬性:
- points:多段線(xiàn)的頂點(diǎn)坐標(biāo)列表,表示為包含X、Y、Z值的元組或點(diǎn)對(duì)象。
- closed:指示多段線(xiàn)是否閉合的布爾值。
- thickness:多段線(xiàn)的厚度,表示為一個(gè)浮點(diǎn)數(shù)。通常在2D繪圖中為0。
- color:多段線(xiàn)的顏色,表示為一個(gè)整數(shù)值。可以使用顏色表進(jìn)行解釋。
- layer:多段線(xiàn)所在的圖層名稱(chēng),表示為一個(gè)字符串。
- linetype:多段線(xiàn)的線(xiàn)型名稱(chēng),表示為一個(gè)字符串。例如,"CONTINUOUS"表示實(shí)線(xiàn)。
- linetype_scale:多段線(xiàn)的線(xiàn)型比例,表示為一個(gè)浮點(diǎn)數(shù)。
- extrusion:多段線(xiàn)的擠壓方向,表示為一個(gè)包含X、Y、Z值的元組或向量對(duì)象。通常在2D繪圖中為(0, 0, 1)。
- elevation:多段線(xiàn)的高度(Z軸值),表示為一個(gè)浮點(diǎn)數(shù)。通常在2D繪圖中為0。
POINT類(lèi)型的數(shù)據(jù)
每個(gè)實(shí)體類(lèi)型為POINT(點(diǎn))的實(shí)體對(duì)象具有以下常見(jiàn)屬性:
- point:點(diǎn)的坐標(biāo),表示為一個(gè)包含X、Y、Z值的元組或點(diǎn)對(duì)象。
- thickness:點(diǎn)的厚度,表示為一個(gè)浮點(diǎn)數(shù)。通常在2D繪圖中為0。
- color:點(diǎn)的顏色,表示為一個(gè)整數(shù)值??梢允褂妙伾磉M(jìn)行解釋。
- layer:點(diǎn)所在的圖層名稱(chēng),表示為一個(gè)字符串。
還有許多數(shù)據(jù)類(lèi)型就不一一介紹,根據(jù)具體的DXF文件,不同文件可能存在不同數(shù)據(jù)。
dxfgrabber中的layers
layers,在dxfgrabber庫(kù)中,要查看圖層的相關(guān)信息,可以通過(guò)庫(kù)里面的layers來(lái)獲取他包含所有圖層的列表。
通過(guò)斷點(diǎn)可以看到其內(nèi)部有哪些屬性,不同的dxf文件,屬性都可能不同。以下是我這個(gè)dxf文件所有的屬性
- name:圖層的名稱(chēng),表示為一個(gè)字符串。
- color:圖層的顏色,表示為一個(gè)整數(shù)值。可以使用顏色表進(jìn)行解釋。
- linetype:圖層的線(xiàn)型名稱(chēng),表示為一個(gè)字符串。例如,"CONTINUOUS"表示實(shí)線(xiàn)。
- frozen:一個(gè)布爾值,指示圖層是否被凍結(jié)(不可見(jiàn))。
- on:屬性用于表示圖層是否處于打開(kāi)狀態(tài)。
- locked:一個(gè)布爾值,指示圖層是否被鎖定,即無(wú)法進(jìn)行編輯。
dxfgrabber中的blocks
DXF文件的塊(Blocks)信息可以通過(guò)訪(fǎng)問(wèn)blocks屬性來(lái)獲取。blocks是一個(gè)包含所有塊的字典,其中鍵是塊的名稱(chēng),值是表示塊的對(duì)象。
每個(gè)塊對(duì)象具有以下常見(jiàn)屬性和方法:
- name:塊的名稱(chēng),表示為一個(gè)字符串。
- entities:塊中的實(shí)體對(duì)象列表。
- basepoint:塊的基點(diǎn)坐標(biāo),表示為一個(gè)包含X、Y、Z值的元組或點(diǎn)對(duì)象。
- insertion_points:塊的插入點(diǎn)坐標(biāo)列表,表示為包含X、Y、Z值的元組或點(diǎn)對(duì)象。
- has_attributes:一個(gè)布爾值,指示塊是否包含屬性定義。
- get_attribute(tag):獲取塊的屬性值,其中tag為屬性的標(biāo)簽。
- extrusion:實(shí)體對(duì)象的擠出方向。
- is_xref:屬性用于表示實(shí)體對(duì)象是否來(lái)自外部引用,外部引用是一種將其他DXF文件中的實(shí)體對(duì)象鏈接到當(dāng)前DXF文件的機(jī)制。
案例
本次案例是編寫(xiě)一個(gè)腳本,再通過(guò)Java來(lái)執(zhí)行這段代碼。用的環(huán)境是python2.7,jdk1.8。雖然比較老了,下次再把python升到3.10。
python代碼
首先是python代碼,本次編寫(xiě)邏輯很簡(jiǎn)單,只是單純的使用dxfgrabber庫(kù)讀取dxf文件,并且以json的形式把值返回回去,這里只是判斷實(shí)體的類(lèi)型為L(zhǎng)INE,輸出類(lèi)型與起點(diǎn)的x,y坐標(biāo)值。
# -*- coding: utf-8 -*- import sys import json import dxfgrabber def get_line_coordinates(): dxf = dxfgrabber.readfile("D:\\Code\\draft.dxf") coordinates = [] for e in dxf.entities: if e.dxftype == 'LINE': data = { "type": e.dxftype, "x": e.start[0], "y": e.start[1] } coordinates.append(data) return coordinates line_coordinates = get_line_coordinates() # 將結(jié)果寫(xiě)入到標(biāo)準(zhǔn)輸出,而不是打印 sys.stdout.write(json.dumps(line_coordinates))
Java代碼
因?yàn)樵贘ava環(huán)境中執(zhí)行python代碼,會(huì)出現(xiàn)環(huán)境不同,找不到庫(kù),所以需要設(shè)置一下環(huán)境路徑,以及python的解釋器路徑。通過(guò)PythonInterpreter.get方法去執(zhí)行函數(shù),需要攜帶兩個(gè)參數(shù),一個(gè)是函數(shù)名,另一個(gè)是返回的對(duì)象類(lèi)型,這里我們用PyFunction類(lèi)來(lái)進(jìn)行返回,通過(guò)調(diào)用__call__來(lái)獲得一個(gè)python對(duì)象,我們返回的是一個(gè)數(shù)組對(duì)象,所以這里可以轉(zhuǎn)成PyList對(duì)象。后面通過(guò)alibaba.fastjson來(lái)轉(zhuǎn)成JSONArray對(duì)象。
這些代碼也就只是為了學(xué)習(xí)而制作,身為一名python小白,對(duì)這些還不夠理解,可能常規(guī)做法并不這樣做,因此后續(xù)還需要更多的嘗試。
/** * @Author: lyd * @Description: 執(zhí)行代碼 * @Date: 2023/5/31 */ public class JavaExecutorPythonUtils { // TODO Auto-generated method stub public static void main(String[] args) throws JsonProcessingException { System.setProperty("python.path", "C:\\Users\\14194\\.windows-build-tools\\python27\\Lib\\site-packages"); PythonInterpreter interpreter = new PythonInterpreter(); interpreter.execfile("D:\\Code\\test.py"); // 設(shè)置 Python 解釋器路徑 interpreter.exec("import sys"); interpreter.exec("sys.path.append('C:\\Users\\14194\\.windows-build-tools\\python27')"); // 第一個(gè)參數(shù)為需要執(zhí)行的函數(shù)(變量)的名字,第二個(gè)參數(shù)為期望返回的對(duì)象類(lèi)型 PyFunction pyFunction = interpreter.get("get_line_coordinates", PyFunction.class); //調(diào)用函數(shù),如果函數(shù)需要參數(shù),在Java中必須先將參數(shù)轉(zhuǎn)化為對(duì)應(yīng)的“Python類(lèi)型” PyObject pyobj = pyFunction.__call__(); PyList pyList = (PyList) pyobj; ObjectMapper objectMapper = new ObjectMapper(); String s = objectMapper.writeValueAsString(pyList); JSONArray jsonArray = JSON.parseArray(s); System.out.println("the anwser is: " + jsonArray); } }
運(yùn)行結(jié)果
總結(jié)
本次就是第一次對(duì)python讀取cad信息進(jìn)行摸索,好多都不是很會(huì),也沒(méi)有學(xué)過(guò)python,對(duì)python語(yǔ)言還是不夠理解,這也就導(dǎo)致了在Java中執(zhí)行腳本的時(shí)候有些摸不著頭腦,也希望看到本篇文章的讀者能夠給一些建議與信息提示??偟膩?lái)說(shuō),就是用過(guò)dxfgrabber庫(kù)獲取文件對(duì)象,在讀取所需的內(nèi)容,工作使用肯定不可能如此簡(jiǎn)單就完成,我的需求是獲取cad中的某些路徑,就差不多是cad圖中描繪了車(chē)的行動(dòng)軌跡路線(xiàn),然后我想把這些行動(dòng)軌跡的坐標(biāo)獲取出來(lái),通過(guò)后端的一些處理在傳到前端web界面顯示。希望路過(guò)的伙伴給個(gè)建議或提示。
以上就是Python通過(guò)dxfgrabber庫(kù)實(shí)現(xiàn)獲取CAD信息的詳細(xì)內(nèi)容,更多關(guān)于Python獲取CAD信息的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中使用__hash__和__eq__方法的問(wèn)題
這篇文章主要介紹了Python中使用__hash__和__eq__方法的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09簡(jiǎn)介二分查找算法與相關(guān)的Python實(shí)現(xiàn)示例
這篇文章主要介紹了二分查找算法與相關(guān)的Python實(shí)現(xiàn)示例,Binary Search同時(shí)也是算法學(xué)習(xí)當(dāng)中最基礎(chǔ)的知識(shí),需要的朋友可以參考下2015-08-08Python基礎(chǔ)知識(shí)_淺談?dòng)脩?hù)交互
下面小編就為大家?guī)?lái)一篇Python基礎(chǔ)知識(shí)_淺談?dòng)脩?hù)交互。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05對(duì)python數(shù)據(jù)清洗容易遇到的函數(shù)-re.sub bytes string詳解
今天小編就為大家分享一篇對(duì)python數(shù)據(jù)清洗容易遇到的函數(shù)-re.sub bytes string詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07python使用cartopy在地圖中添加經(jīng)緯線(xiàn)的示例代碼
gridlines可以根據(jù)坐標(biāo)系,自動(dòng)繪制網(wǎng)格線(xiàn),這對(duì)于普通繪圖來(lái)說(shuō)顯然不必單獨(dú)拿出來(lái)說(shuō)說(shuō),但在地圖中,經(jīng)緯線(xiàn)幾乎是必不可少的,本文將給大家介紹了python使用cartopy在地圖中添加經(jīng)緯線(xiàn)的方法,需要的朋友可以參考下2024-01-01Python中map,reduce,filter和sorted函數(shù)的使用方法
這篇文章主要介紹了Python中map,reduce,filter和sorted函數(shù)的使用方法,是Python入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08Python使用matplotlib實(shí)現(xiàn)的圖像讀取、切割裁剪功能示例
這篇文章主要介紹了Python使用matplotlib實(shí)現(xiàn)的圖像讀取、切割裁剪功能,結(jié)合實(shí)例形式分析了Python基于matplotlib操作圖片的加載、讀取、坐標(biāo)控制及裁剪相關(guān)操作技巧,需要的朋友可以參考下2018-04-04