Skip to content
Snippets Groups Projects
analyze_dxf.py 6.28 KiB
Newer Older
#!/usr/bin/env python

import numpy as np
import ezdxf 
import random
from math import sqrt
import cv2
import os
from pathfinding.core.diagonal_movement import DiagonalMovement
from pathfinding.core.grid import Grid
from pathfinding.finder.a_star import AStarFinder

class dxf_editor:
    def __init__(self,path,dxf_file):
        self.dwg=ezdxf.readfile(path+dxf_file)
        self.msp=self.dwg.modelspace()
        self.dxf_name='silhouette_ele.dxf'
Jingyan Ling's avatar
Jingyan Ling committed
        # self.img_name='silouette_ele.png'
        
        
        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
Jingyan Ling's avatar
Jingyan Ling committed
        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)

        self.matrix_shape=(270,210)
Jingyan Ling's avatar
Jingyan Ling committed
        self.read_dxf_as_matrix()

Jingyan Ling's avatar
Jingyan Ling committed
        start_point_arr=(120,60)
        end_point_arr=(120,172)
        start_point=[int(start_point_arr[0]),int(start_point_arr[1])]
        end_point=[int(end_point_arr[0]),int(end_point_arr[1])]

        self.path=self.find_a_path(start_point,end_point)

        self.draw_a_path(self.path)
Jingyan Ling's avatar
Jingyan Ling committed


        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)

    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:]
Jingyan Ling's avatar
Jingyan Ling committed
        # print(self.center_arr)
    def remove_wheels(self):
Jingyan Ling's avatar
Jingyan Ling committed
        #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)

Jingyan Ling's avatar
Jingyan Ling committed

    def draw_on_pin(self,fulllength): #isolation
        iso=self.dwg.blocks.new(name='ISO_BLK')
        isolength=fulllength/2
        trace_w=0.8
        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'})

Jingyan Ling's avatar
Jingyan Ling committed
    
    def read_dxf_as_matrix(self): 
        """unit: mm 
            accuracy issue expected atm (mm round up)
        """
Jingyan Ling's avatar
Jingyan Ling committed
        self.matrix=np.ones(self.matrix_shape)
Jingyan Ling's avatar
Jingyan Ling committed

Jingyan Ling's avatar
Jingyan Ling committed
        for line in self.msp.query('LINE[layer!="Fold" & layer!="Label" & layer!="Pin_temp"]'):
Jingyan Ling's avatar
Jingyan Ling committed
            start=np.rint(line.dxf.start)
            end=np.rint(line.dxf.end)
Jingyan Ling's avatar
Jingyan Ling committed
            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
                self.matrix[j,i]=0
Jingyan Ling's avatar
Jingyan Ling committed
                while i!=end[0]:
                    if i<end[0]:
                        i+=1
                    else:
                        i-=1
                    self.matrix[j,i]=0
Jingyan Ling's avatar
Jingyan Ling committed
            elif i==end[0]: #this line is a vertical line
                self.matrix[j,i]=0
Jingyan Ling's avatar
Jingyan Ling committed
                while j!=end[1]:
                    if j<end[1]:
                        j+=1
                    else:
                        j-=1
                    self.matrix[j,i]=0
        
    def find_a_path(self,start_point,end_point):

        grid = Grid(matrix=self.matrix)
        start=grid.node(start_point[0],start_point[1])
        end=grid.node(end_point[0],end_point[1])
        finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
        path, runs = finder.find_path(start, end, grid)

        return path
    def draw_a_path(self,path):
        #draw on matrix:
        for point in path:
            self.matrix[point[1],point[0]]=-1
        #draw on dxf:
        for i in range(len(path)-1):
            self.msp.add_line(path[i],path[i+1],dxfattribs={
                'layer':'Circuit',
                'linetype':'DASHDOT'})
             
Jingyan Ling's avatar
Jingyan Ling committed

        # print(self.matrix)
Jingyan Ling's avatar
Jingyan Ling committed
# def main():
path='/home/jingyan/Documents/summer_intern_lemur/roco_electrical/'
dxf_file='graph-silhouette.dxf'
edit=dxf_editor(path,dxf_file)
Jingyan Ling's avatar
Jingyan Ling committed
# if __name__ == '__main__':
#     main()