Newer
Older
#!/usr/bin/env python
import numpy as np
import ezdxf
import random
from pathfinding.core.diagonal_movement import DiagonalMovement
from pathfinding.core.grid import Grid
from pathfinding.finder.a_star import AStarFinder
import copy
import matplotlib.pyplot as plt
import matplotlib.animation as animation
class dxf_editor:
def __init__(self,path,dxf_file):
self.dwg=ezdxf.readfile(path+dxf_file)
self.msp=self.dwg.modelspace()
self.create_layer('Cut',5)
self.create_layer('Circuit',1)
self.create_layer('Label',3)
self.create_layer('Fold',4)
self.create_layer('Pin_temp',6)
self.layer_rearrange() ## reagrrange cut and fold lines to corresponding layers
self.remove_wheels() ##remove wheel drawings for this design, no need to call for other designs
self.find_pin()
isolength=2.6 #mm
self.draw_on_pin(isolength)
# start_point_arr=np.rint(self.center_arr[1])
# end_point_arr=(120,172)
# start_point=[start_point_arr[0],start_point_arr[1]]
# end_point=[end_point_arr[0],end_point_arr[1]]
# self.path=self.find_a_path(self.matrix,start_point,end_point)
# self.draw_a_path(self.path,self.matrix,True)
self.connections_list=np.array([[0,0],[0,0]]).reshape(1,2,2)
connection_amount=5
for i in range(connection_amount):
s=random.randint(0,len(self.center_arr)-1)
e=random.randint(0,len(self.center_arr)-1)
connections=np.array([[self.center_arr[s],self.center_arr[e]]]).reshape(1,2,2)
self.connections_list=np.append(self.connections_list,connections,axis=0)
self.connections_list=np.rint(self.connections_list)[1:]
self.find_multi_path(self.connections_list)
self.dwg.saveas(self.dxf_name)
# os.system("inkscape -f silhouette_ele.dxf -e silouette_ele.png")
# self.img=cv2.imread(path+self.img_name)
# print(self.img)
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
def create_layer(self,layer_name,color):
if not layer_name in self.dwg.layers:
self.dwg.layers.new(name=layer_name,dxfattribs={'color':color})
def layer_rearrange(self):
# put fold lines to the new layer 'Fold'
# put cut lines to the new layer 'Cut
for e in self.msp.query('LINE'):
if e.dxf.color!=5:
e.dxf.layer='Fold'
else:
e.dxf.layer='Cut'
def find_pin(self):
tolerance=0.05 #mm
pincutsize=1 #mm
pin_edge_arr=np.array([[0,0],[0,0]]).reshape(1,2,2)
self.center_arr=np.array([[0,0]])
for e in self.msp.query('LINE[layer=="Cut"]'):
length= sqrt((e.dxf.start[0]-e.dxf.end[0])**2+(e.dxf.start[1]-e.dxf.end[1])**2)
if length > pincutsize-tolerance and length < pincutsize + tolerance:
e.dxf.layer='Pin_temp'
if e.dxf.start[1]==e.dxf.end[1]: ##this line is horizontal
pin_edge=np.array([e.dxf.start,e.dxf.end])[:,:2]
pin_edge_arr=np.concatenate((pin_edge_arr,pin_edge.reshape(1,2,2)),axis=0)
pin_edge_arr=pin_edge_arr[1:]
# print(pin_edge_arr)
for i in range(len(pin_edge_arr)):
for e in np.delete(pin_edge_arr,i,axis=0):
if pin_edge_arr[i][0,1]-e[0,1]==1.0:
center_x=pin_edge_arr[i][0,0]-0.5
center_y=pin_edge_arr[i][0,1]-0.5
center=np.array([center_x,center_y]).reshape(1,2)
self.center_arr=np.append(self.center_arr,center,axis=0)
self.center_arr=np.unique(self.center_arr,axis=0)
self.center_arr=self.center_arr[1:]
#no need to call this function for other design
for e in self.msp.query('Arc LINE[layer=="Cut"]'):
if e.dxf.start[0]>=179:
self.msp.delete_entity(e)
def draw_on_pin(self,fulllength): #isolation
iso=self.dwg.blocks.new(name='ISO_BLK')
isolength=fulllength/2
iso.add_line((-isolength,isolength),(isolength,isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,-isolength),(isolength,-isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,-isolength),(-isolength,isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((isolength,-isolength),(isolength,isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,-trace_w/2),(-(isolength+5),-trace_w/2),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,trace_w/2),(-(isolength+5),trace_w/2),dxfattribs={'linetype':'DASHDOT'})
for center_point in self.center_arr:
self.msp.add_blockref('ISO_BLK',center_point,dxfattribs={'layer':'Circuit'})
def read_dxf_as_matrix(self):
"""unit: mm
accuracy issue expected atm (mm round up)
"""
for line in self.msp.query('LINE[layer!="Fold" & layer!="Label" & layer!="Pin_temp"]'):
start=np.rint(line.dxf.start)
end=np.rint(line.dxf.end)
i=int(start[0])
j=int(start[1])
#can draw horizontal or vertical lines only
if j==end[1]: #this line is a horizontal line
while i!=end[0]:
if i<end[0]:
i+=1
else:
i-=1
while j!=end[1]:
if j<end[1]:
j+=1
else:
j-=1
def find_a_path(self,matrixws,start_point,end_point):
"""
find a path between two points on img=matrix
start_point and end_point shape: (2,)
"""
#DEBUG:
# if not np.array_equal(matrixws,self.matrix):
# print('Map updated')
grid = Grid(matrix=matrixws)
start=grid.node(int(start_point[0]),int(start_point[1]))
end=grid.node(int(end_point[0]),int(end_point[1]))
finder = AStarFinder(diagonal_movement=4)
path, runs = finder.find_path(start, end, grid)
return path
def draw_a_path(self,path,matrix,dxf=False):
""" draw a path on img=matrix, or on dxf file too"""
for i in range(len(path)-1):
self.msp.add_line(path[i],path[i+1],dxfattribs={
'layer':'Circuit',
'linetype':'DASHDOT'})
def get_cost(self,path):
if len(path)==0:
cost=1000
else: cost=len(path)
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def find_multi_path(self,pin_connections):
"""pin_connection shape : NX2X2 """
E=2
for episode in range(E):
self.matrix_temp=copy.deepcopy(self.matrix)
self.Q=0
random_ix=random.randint(0,len(pin_connections)-1)
init_s=pin_connections[random_ix]
con_list_temp=np.delete(pin_connections,random_ix,axis=0)
cur_path=self.find_a_path(self.matrix_temp,init_s[0],init_s[1])
self.draw_a_path(cur_path,self.matrix_temp,True)
cost=self.get_cost(cur_path)
self.Q=self.Q+cost
while len(con_list_temp)!=0:
random_ix=random.randint(0,len(con_list_temp)-1)
next_conn=con_list_temp[random_ix]
con_list_temp=np.delete(con_list_temp,random_ix,axis=0)
curpath=self.find_a_path(self.matrix_temp,next_conn[0],next_conn[1])
self.draw_a_path(curpath,self.matrix_temp,True)
cost=self.get_cost(curpath)
self.Q=self.Q+cost
episode+=1
plt.imshow(self.matrix_temp)
plt.show()
# def main():
path='/home/jingyan/Documents/summer_intern_lemur/roco_electrical/'
dxf_file='graph-silhouette.dxf'
edit=dxf_editor(path,dxf_file)
# animation.FuncAnimation(edit.fig,plt.imshow(edit.matrix_temp))
# plt.show()