python导出dxf图_在PDMS中使用python直接生成管口方位图(开源分享第三集)
生活随笔
收集整理的這篇文章主要介紹了
python导出dxf图_在PDMS中使用python直接生成管口方位图(开源分享第三集)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在PDMS中使用python直接生成管口方位圖(開源分享第三集)
? ?距離上一次發推送已有5個月之久,上周立了冬,這二季我為五斗米折了腰,最近才緩過氣來。
? ?令我沒想到的是,大家竟然對這個主題這么有興趣,有關注者幾次在私信詢問我什么時候更新,大家的期盼無形之中給了我繼續分享的動力。
上一集給大家介紹了如何生成設備的輪廓及相位中心線。
? ?這一集里要完成生成3個頂部管口的平面圖形及位號標注功能。
其主要步驟如下:
1:提取設備管口的基本信息(這里可以通過宏文件在PDMS提取,本集不做詳細介紹),其提取的信息要包含如下內容:管口號,管口端面型式,端面坐標,管口朝向,管口法蘭OD值及管口接管的OD值;
2:生成管口圖形,其圖形將以2個同心圓表示,這兩個同心圓分別表示法蘭外徑及接管端的外徑;
3:生成管口位號標簽(管口號外面以一個圈的型式表示)。
本集主要的精華部分在將管口圖形及管口位號標簽以塊的型式生成,特別是管口位號標簽塊是以屬性塊的型式表示(如下圖所示)。
其對應視頻如下:
原代碼如下(本集代碼與上一集代碼的增加集中在第81行至116行):
| 1 | __author__ = 'fenchane@wo.cn' |
| 2 | # date@2020-11-16 |
| 3 | import ezdxf? # 導入ezdxf模塊 |
| 4 | import math? # 導入math模塊 |
| 5 | # ezdxf ?文檔網址為https://ezdxf.mozman.at/docs/ |
| 6 | dxfile = ?'d:\\nozzdraft.dxf'? # 將要生成的NOZZ方位文件 |
| 7 | doc = ezdxf.new('R2010', ?setup=True)? # 2010 格式, ?setup值為True時會加載默認的線型等設置,建議設置為True |
| 8 | doc.header['$INSUNITS'] = 4? # 文件為mm為單位 |
| 9 | msp = doc.modelspace() # ?modelspace 與CAD里的model模型相對應 |
| 10 | |
| 11 | # layer setting 下面將定義層新建一個列表 |
| 12 | #?????????? [層名稱???????? 線型???? 顏色索引?? ?線寬(-1表示默認,30表示的的是0.3mm, 線寬依次類推] |
| 13 | layerset = (['level_cl', ?'CENTER2', 255, -1],???????? # 中心線用 |
| 14 | ??????????? ['level_nozz', 'CONTINUOUS', 3, ?30],????? # 管口圖型用 |
| 15 | ??????????? ['level_outline', 'CONTINUOUS', ?1, 30],?? # 設備外形用 |
| 16 | ??????????? ['level_tagText', 'CONTINUOUS', ?2, -1],?? # 管口TAG用 |
| 17 | ??????????? ['level_Dim', 'CONTINUOUS', 1, ?-1],?????? # 標注用 |
| 18 | ??????????? ['level_brd', 'CONTINUOUS', 5, ?30])?????? # 圖框用 |
| 19 | for layer in layerset: # ?循環向圖形中加載列表中的層設置 |
| 20 | ??? #?????????????????? 名稱???????? 屬性????????? 線型???????????????? 顏色??????????????? 線寬 |
| 21 | ??? doc.layers.new(name=layer[0], ?dxfattribs={'linetype': layer[1], 'color': layer[2], 'lineweight': layer[3]}) |
| 22 | |
| 23 | # fonts setting 字體設置/新建一個列表 |
| 24 | #??????? 【字體名稱???????? 西文字體????? 中文字體??? ?字體大小 寬度因子】 |
| 25 | fonts = (['nozz_Style', ?'Tssdeng.shx', 'TSSDCHN.shx', 50, 0.75], |
| 26 | ???????? ['table_Style', 'romand.shx', ?'TSSDCHN.shx', 50, 0.75],) |
| 27 | |
| 28 | for font in fonts:? # 循環向圖形中加載字體設置 |
| 29 | ??? doc.styles.new(font[0], ?dxfattribs={'font': font[1], 'bigfont': font[2], 'height': font[3], 'width': ?font[4]}) |
| 30 | ??? styles = doc.styles |
| 31 | # /TK-2020,CYLI,13000mm,E 0mm N ?0mm U 7250mm WRT /*,13500mm |
| 32 | # ?以上為設備信息通過PML語言可以從PDMS提取,并以“,”為分隔依次表示設備位號, |
| 33 | # /TK-2020 |
| 34 | # 直徑13000mm |
| 35 | # CYLI表示PDMS中的元件類型圓柱, |
| 36 | # 坐標E 0mm N 0mm U 7250mm WRT /* |
| 37 | # 13500mm高 |
| 38 | # ?為簡化處理過程這次我們直接改寫成最終我們需要的列表型式,我們只需要設備位號,坐標X/Y對應該E/N, 圓柱直徑 |
| 39 | #eqpinfo = ['TK-2020', (0, 0), ?13000] |
| 40 | eqpinfo = ['TK-2020', (0, 0), ?13000] |
| 41 | eqpname = eqpinfo[0]? # 設備名稱 |
| 42 | eqpori = eqpinfo[1]?? # 設備原點X/Y對應該E/N坐標 |
| 43 | eqpradius = eqpinfo[2]/2? # 設備半徑 |
| 44 | ### |
| 45 | # ?以下為使用add_circle()函數向dxf圖形中添加設備的外圓圈 |
| 46 | msp.add_circle(eqpori, ?eqpradius, dxfattribs={'layer': 'level_outline'})? # level_outline來自layerset |
| 47 | |
| 48 | # ?為畫出過圓心的中心線先定義一個函數linecoordinate(ori, cllen, ?angle)可以根據圓的中心點個中心線長及角度算出線起點和終點的坐標 |
| 49 | def linecoordinate(ori, cllen, ?angle): #ori:線要過的中心點坐示, clen:中心線長,angle在笛卡爾坐標系中的角度,今后會提到極坐標 |
| 50 | ??? clenhalf = 0.5*cllen |
| 51 | ??? angle = math.radians(angle) |
| 52 | ??? pointsv = ?(ori[0]-clenhalf*math.cos(angle), ori[1]-clenhalf*math.sin(angle)) |
| 53 | ??? pointev = ?(ori[0]+clenhalf*math.cos(angle), ori[1]+clenhalf*math.sin(angle)) |
| 54 | ??? return pointsv, pointev |
| 55 | |
| 56 | |
| 57 | # 以下將為使用add_line()函數為設備的外圓圈添加中心線 |
| 58 | pointendarr = [] ?#pointendarr用來接收中心線起始點的坐標。 |
| 59 | for deg in [0, 90]: #中心線就是0和90度 |
| 60 | #clhorpoint[0], clhorpoint[1], ?dxfattribs={'layer': layercl, 'ltscale': ltscale} |
| 61 | ??? cllen = 1.2*eqpradius*2? #中心線按圓形的直徑1.2倍 |
| 62 | ??? cllinepoint = linecoordinate(eqpori, ?cllen, deg) |
| 63 | ??? msp.add_line(cllinepoint[0], ?cllinepoint[1], dxfattribs={'layer': 'layer_cl', 'linetype': 'CENTER2',? 'ltscale': 1000}) |
| 64 | ??? pointendarr.append(cllinepoint)? # ?把0°/90°起始點收到pointendarr列表中,下面為中心線端部添加0°,90°,180°, 270°文字要用到 |
| 65 | ?????????????? # cllinepoint[0]表示起點, ?cllinepoint[1]表示終點 |
| 66 | ??????????????? # 'layer_cl'來自layerset |
| 67 | ??????????????? # ltscale ?表示線形比例為讓點畫線型比較合適表示建議設置為中心線長/10 |
| 68 | #以下將為中心線的兩頭添加0°,90°,180°, ?270°文字, 定義了phase相位角的字典數據庫 |
| 69 | phasedeg = {90: ?(pointendarr[0][1], 'MIDDLE_LEFT'), |
| 70 | ??????????? 0: (pointendarr[1][1], ?'BOTTOM_CENTER'), |
| 71 | ??????????? 270: (pointendarr[0][0], ?'MIDDLE_RIGHT'), |
| 72 | ??????????? 180: (pointendarr[1][0], ?'TOP_CENTER')} |
| 73 | for deg in [0, 90, 180, 270]: |
| 74 | ??? msp.add_text(str(deg) + '%%d', ?dxfattribs={'style': 'nozz_Style', 'height': 500, 'color': 6, 'width': ?0.75}).?set_pos(phasedeg[deg][0], align=phasedeg[deg][1]) |
| 75 | |
| 76 | msp.add_text(eqpname, ?dxfattribs={'style': 'nozz_Style', 'height': 1000, 'color': 4, 'width': ?0.75}).?set_pos(phasedeg[deg][0], align=phasedeg[deg][1]) |
| 77 | ???? |
| 78 | |
| 79 | ########################### ?以下第80行~116行為本次分享所補充的內容,本次要完成3個頂部管口的繪制及管口號的生成 |
| 80 | #Nozzle table 自PDMS中導出,此處不做介紹, ?以下管口M,A,B為頂部的三個管口 |
| 81 | #以下的82~84中信息以逗號為分隔,包括了管口號,管口端面型式,端面坐標,管口朝向,管口法蘭OD及管口管道的OD |
| 82 | nozztable = ?['/TK-2020/M,600mm,FBP,E 0mm N 0mm U 15500mm WRT /*,U WRT /*,812.8,610', |
| 83 | ???????????? '/TK-2020/A,200mm,FBP,E 4000mm N ?4000mm U 15500mm WRT /*,U WRT /*,340,219', |
| 84 | ???????????? '/TK-2020/B,200mm,FBP,W 4000mm N ?4000mm U 15500mm WRT /*,U WRT /*,340,219'] |
| 85 | #以下的列表中元組表示需要對PDMS抽出來的坐標進行處理,如W, ?S, D表示“-” |
| 86 | directsign = [('WRT /*',''), ?('E', ''), ('N', ''), ('U', ''), ('W', '-'), ('S', '-'), ('D', '-'), (' ', ?''), ('mm', ',')] |
| 87 | #以下開始遍歷第46中的列表,提取管口號,管口位置,管口外徑等信息。 |
| 88 | for nozz in nozztable: |
| 89 | ??? nozzarr = nozz.split(',') |
| 90 | ??? nozzblkname = ?'nozz'+nozzarr[0].replace('/', '_') #定義管口圖形block塊的名稱定義 |
| 91 | ??? print(nozzblkname) |
| 92 | ??? nozzpos = nozzarr[3] |
| 93 | ??? for direct in directsign: |
| 94 | ??????? nozzpos = nozzpos.replace(direct[0], ?direct[1]) |
| 95 | ??? nozzcoordinate = ?(float(nozzpos.split(',')[0]), float(nozzpos.split(',')[1])) |
| 96 | ??? nozzflgOD = float(nozzarr[5]) ?#管口法蘭外徑,就是管口圖形中的外圈 |
| 97 | ??? nozzpipeOD = float(nozzarr[6]) ?#管口接管的外徑,就是管口圖形中的內圈 |
| 98 | ??? print(nozzcoordinate) |
| 99 | ??? nozzflag = ?doc.blocks.new(name=nozzblkname) #開始向管口圖形block塊中添加圖形元素 |
| 100 | ??? nozzflag.add_circle(eqpori, ?nozzflgOD*0.5, dxfattribs={'layer': 'level_nozz'}) |
| 101 | ??? nozzflag.add_circle(eqpori, nozzpipeOD * ?0.5, dxfattribs={'layer': 'level_nozz'}) |
| 102 | ??? nozzflag.add_point(eqpori, ?dxfattribs={'layer': 'level_nozz', 'lineweight': 13}) |
| 103 | ??? msp.add_blockref(nozzblkname, ?nozzcoordinate) #管口圖形block塊中添加圖形元素結束 |
| 104 | |
| 105 | ??? tagblk = 'tag'+nozzarr[0].replace('/', ?'_') #定義管口位號(帶屬性)block名稱 |
| 106 | ??? tagflag = doc.blocks.new(name=tagblk) ?#開始向管口位號block屬性塊中添加圖形元素 |
| 107 | ??? tagflag.add_circle(eqpori, 150, ?dxfattribs={'layer': 'level_tagText'}) #管口號屬性塊的外圈 |
| 108 | ??? tagflag.add_attdef('NAME', eqpori, ?dxfattribs={'style': 'nozz_Style', 'layer': 'level_tagText', 'height': ?150}).\ |
| 109 | ??????? set_pos(eqpori,) #定義一個'NAME'字段做為屬性塊來存儲管號號 |
| 110 | ??? inserttagPosX = nozzcoordinate[0] |
| 111 | ??? inserttagPosY = nozzcoordinate[1] + 50 + ?nozzflgOD |
| 112 | ??? insertagPos = (inserttagPosX, ?inserttagPosY) #這表示管口號屬性塊在圖面中的位置,其實就是位于管口號的正上方,看第75行, Y坐標有偏移 |
| 113 | ??? blockref = msp.add_blockref(tagblk, ?insertagPos) #管口號屬性塊元素添加結束 |
| 114 | ??? values = {'NAME': ?nozzarr[0].split('/')[2]} #為管口號屬性塊的"NAME"字段添加文字,如管口號"A" |
| 115 | ??? blockref.add_auto_attribs(values) ?#管口號屬性塊的"NAME"字段屬性添加結束 |
| 116 | ########################### |
| 117 | doc.saveas(dxfile)? # ?保存以上所有操作進dxf文件中,下面可以去查看'd:\\nozzdraft.dxf'下生成的文件了 |
往期回顧:
在PDMS中使用python直接生成管口方位圖(開源分享第二集)
在PDMS中使用python直接生成管口方位圖(開源分享第一集)
總結
以上是生活随笔為你收集整理的python导出dxf图_在PDMS中使用python直接生成管口方位图(开源分享第三集)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 广发南航明珠信用卡:商务人士出行必备
- 下一篇: python向空列表添加列表_Pytho