Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jllemur813/roco_electrical
1 result
Show changes
Showing
with 1742 additions and 338 deletions
WARNING: Could not open directory ''
WARNING: Could not open directory ''
WARNING: Could not open directory ''
ERROR: Unable to find part NodeMCU_1.0 in library ESP8266.
ERROR: Can't open file: linear.
WARNING: Could not load KiCad schematic library "linear", falling back to backup library.
ERROR: Unable to find part NodeMCU_1.0 in library ESP8266.lib.
ERROR: Can't open file: /home/jingyan/kicad/libraries/kicad-ESP8266.
WARNING: Could not load KiCad schematic library "/home/jingyan/kicad/libraries/kicad-ESP8266", falling back to backup library.
WARNING: Could not open directory ''
ERROR: Unable to find part NodeMCU_1.0_(ESP-12E) in library ESP8266.
WARNING: Could not open directory ''
WARNING: Could not open directory ''
ERROR: Unable to find part NodeMCU_1.0_ in library ESP8266.
WARNING: Could not open directory ''
WARNING: Could not open directory ''
WARNING: Could not open directory ''
WARNING: Could not open directory ''
#!/usr/bin/env python
import numpy as np
import ezdxf
import random
from math import sqrt
import copy
from LayoutEditor import LayoutScript
from LayoutScript import *
l=project.newLayout();
#rename a layer
layers.num(6).name="new text"
c=l.drawing.currentCell
c.cellName="test-cell-python"
c.addBox(0,0,5000,7000,5)
c.addRoundedBox(10000,0,5000,7000,500,5)
c.addChamferedBox(20000,0,5000,7000,500,5)
c.addCircleBox(point(0,10000),point(5000,17000),5)
c.addEllipse(5,point(12500,15000),2500,3500)
c.addPolygonArc(point(22500,15000),2500,3500,0,340,5)
e=c.addText(5,point(25,25000),layers.num(6).name)
e.setWidth(1000)
l.drawing.saveFile("/home/jingyan/Documents/summer_intern_lemur/roco_electrical/testout.dsn")
print("Python script completed")
\ No newline at end of file
#!/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
import copy
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import cm
class auto_rounter:
def __init__(self,path,dxf_file):
self.dwg=ezdxf.readfile(path+dxf_file)
self.msp=self.dwg.modelspace()
self.dxf_name='silhouette_ele.dxf'
self.fail_flag=False #return True when path not found
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)
self.matrix_shape=(270,210)
self.read_dxf_as_matrix()
# self.connections_list=np.array([[0,0],[0,0]]).reshape(1,2,2)
# connection_amount=4
# 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:]
############for testing and demo purpose #############
self.connections_list=self.test_connections()
# self.matrix_temp=copy.deepcopy(self.matrix)
# self.img=plt.imshow(self.matrix_temp,interpolation='nearest',cmap=cm.Spectral)
# ani=animation.FuncAnimation(self.fig,self.find_multi_path,interval=10)
# plt.show()
self.find_multi_path(1)
self.dwg.saveas(self.dxf_name)
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:]
# print(self.center_arr)
def remove_wheels(self):
#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
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'})
def read_dxf_as_matrix(self):
"""unit: mm
accuracy issue expected atm (mm round up)
"""
self.matrix=np.ones(self.matrix_shape)
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
self.matrix[j,i]=0
while i!=end[0]:
if i<end[0]:
i+=1
else:
i-=1
self.matrix[j,i]=0
elif i==end[0]: #this line is a vertical line
self.matrix[j,i]=0
while j!=end[1]:
if j<end[1]:
j+=1
else:
j-=1
self.matrix[j,i]=0
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"""
#draw on matrix:
for point in path:
matrix[point[1],point[0]]=0
#draw on dxf:
if dxf:
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: #if no path found
print('one path not found')
self.fail_flag=True
cost=1000
else: cost=len(path)
return cost
def find_multi_path(self,i):
"""connection list shape : NX2X2 """
E=20
print("==========Auto rounting start===========")
for episode in range(E):
print 'episode:',episode+1,'(/',E,')==========='
self.matrix_temp=copy.deepcopy(self.matrix)
self.Q=0
self.fail_flag=False
random_ix=random.randint(0,len(self.connections_list)-1)
init_s=self.connections_list[random_ix]
current_solving=np.array([init_s]).reshape(1,2,2)
con_list_temp=np.delete(self.connections_list,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)
# self.img.set_array(self.matrix_temp)
cost=self.get_cost(cur_path)
self.Q=self.Q+cost
curpath_temp=[cur_path]
while len(con_list_temp)!=0:
random_ix=random.randint(0,len(con_list_temp)-1)
next_conn=con_list_temp[random_ix]
current_solving=np.append(current_solving,next_conn.reshape(1,2,2),axis=0)
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)
curpath_temp.append(curpath)
# self.img.set_array(self.matrix_temp)
cost=self.get_cost(curpath)
self.Q=self.Q+cost
if episode==0:
self.Q_buff=copy.deepcopy(self.Q)
if self.Q<=self.Q_buff:
self.Q_buff=copy.deepcopy(self.Q)
self.final_solving=current_solving
self.final_path=curpath_temp
self.final_fail=self.fail_flag
print 'Current cost:',self.Q,'Best cost',self.Q_buff
episode+=1
if not self.final_fail:
for i in range(len(self.final_path)):
self.draw_a_path(self.final_path[i],self.matrix,True)
else:
print 'One or more path cannot be solved'
def test_connections(self):
y=97
x=90
arti_pin_array=np.empty((1,2))
center_pin_conn=np.empty((1,2))
pin_conn=np.empty((1,2,2))
for i in range(10):
arti_pin=(x+i,y)
arti_pin_array=np.append(arti_pin_array,[arti_pin],axis=0)
arti_pin_array=arti_pin_array[1:]
for i in range(len(self.center_arr)):
if self.center_arr[i][1]<60:
center_pin_conn=np.append(center_pin_conn,self.center_arr[i].reshape(1,2),axis=0)
if len(center_pin_conn)>10: break
center_pin_conn=center_pin_conn[1:]
for i in range(10):
pin_conn_temp=np.array([arti_pin_array[i],center_pin_conn[i]]).reshape(1,2,2)
pin_conn=np.append(pin_conn,pin_conn_temp,axis=0)
pin_conn=pin_conn[1:]
return pin_conn
# def main():
path='/home/jingyan/Documents/summer_intern_lemur/roco_electrical/'
dxf_file='graph-silhouette.dxf'
router=auto_rounter(path,dxf_file)
# animation.FuncAnimation(edit.fig,plt.imshow(edit.matrix_temp))
# plt.show()
# if __name__ == '__main__':
# main()
This diff is collapsed.
# dsn_python
File added
File added
File added
File added
File added
File added
File added
from pykicad.sexpr import *
import numpy as np
class load_drawing():
def __init__(self,afile):
import ezdxf
self.dwg=ezdxf.readfile(afile)
self.msp=self.dwg.modelspace()
def load_all(self):
return [self.load_line,self.load_polygon]
def load_line(self):
startlist=[]
endlist=[]
line_list=[]
for e in self.msp.query('LINE'):
startlist.append(e.dxf.start[:2])
endlist.append(e.dxf.end[:2])
for i in range(len(startlist)):
line_list.append(startlist[i])
line_list.append(endlist[i])
line_list=np.array(line_list)
# line_list[:,1]*=-1
line_list*=1000
line_list=line_list.flatten()
line_list=list(line_list)
return line_list
def load_polygon(self):
pts_list=[]
for e in self.msp.query('LWPOLYLINE'):
pts_list.append(np.array(e.get_points()))
for i in range(len(pts_list)):
pts_list[i]=pts_list[i][:,:2]
# pts_list[i][:,1]*=-1
##Unit = um
pts_list[i]=pts_list[i]*1000
pts_list[i]=pts_list[i].flatten()
pts_list[i]=list(pts_list[i])
return pts_list
def load_line_as_polygon(self):
pts_list=self.load_polygon()
ply_list=[]
for i in range(len(pts_list)):
for j in range(len(pts_list[i])):
ply_list.append(pts_list[i][j])
return ply_list
class Boundary(AST):
tag='boundary'
schema={
'path pcb':{
'0':{
'_parser':integer,
'_attr':'brd_index'
},
'1':{
'_parser': number,
'_attr': 'path'
},
}
}
def __init__(self,path,brd_index=0):
super(Boundary,self).__init__(path=path,brd_index=brd_index)
class Keepout(AST):
tag='keepout'
schema={
'0':{
'0':{
'_parser':text,
'_attr':'name'
},
' ':{
'0': {
'_parser':text,
'_attr':'shape'
},
'1':{
'_parser':text,
'_attr':'typex'
},
'2':{
'_parser':integer,
'_attr':'brd_index'
},
'3':{
'_parser': number,
'_attr':'path'
},
},
},
}
def __init__(self,path,name='\"\"',brd_index=0,shape='polygon',typex='signal'):
super(Keepout,self).__init__(path=path,name=name,brd_index=brd_index,shape=shape,typex=typex)
\ No newline at end of file
File added
from pykicad.sexpr import *
unit_convert=1000
class Placement(AST):
tag='component'
schema={
'0':{
'_parser':text,
'_attr':'ref1',
# '_multiple':True
},
'place':{
'0':{
'_parser':text,
'_attr':'ref2',
},
'1':{
'_parser':number + number,
'_attr':'at'
},
'2':{
'_parser':text,
'_attr':'flip'
},
'3':{
'_parser':integer,
'_attr':'orientation'
},
'PN':{
'_parser':text,
'_attr':'name'
}
}
}
def __init__(self,ref1,at=[0,0],ref2=None,flip='front',orientation=0,name=None):
# at[1]=-at[1] #flip y for dsn
ref2=ref1
super(Placement,self).__init__(ref1=ref1,ref2=ref2,at=at,flip=flip,orientation=orientation,name=name)
class Outline(AST):
tag='outline'
schema={
'0':{
'path signal':{
'0':{
'_parser':integer,
'_attr':'width'
},
'1':{
'_parser':integer,
'_attr':'outline_start'
},
'2':{
'_parser':integer,
'_attr':'outline_end'
}
}
}
}
def __init__(self,width=None,outline_start=None,outline_end=None):
super(Outline,self).__init__(width=width,outline_start=outline_start,outline_end=outline_end)
class Pin(AST):
tag='pin'
schema={
'0':{
'_parser':text,
'_attr':'pin_type',
},
'1':{
'_parser':integer,
'_attr':'pin_index',
},
'2':{
'_parser':number+number,
'_attr':'pin_at',
}
}
def __init__(self,pin_index=None,pin_at=None,pin_type='Round[A]Pad_1524_um'):
super(Pin,self).__init__(pin_type=pin_type,pin_index=pin_index,pin_at=pin_at)
class Shape(AST):
tag='shape'
schema={
' ':{
'0':{
'_parser': text,
'_attr':'shape'
},
'1':{
'_parser': text,
'_attr':'layer'
},
'2':{
'_parser': integer,
'_attr': 'size'
}
}
}
def __init__(self,shape='circle',layer=None,size=1524):
super(Shape,self).__init__(shape=shape,layer=layer,size=size)
class Padstack(AST):
tag='padstack'
schema={
'0':{
'_parser': text,
'_attr': 'pin_type'
},
'1':{
'shape':{
'_parser':Shape,
'_multiple':True
},
},
'attach':{
'_parser': text
}
}
def __init__(self,pin_type='Round[A]Pad_1524_um',shape=None,attach='off'):
shape=self.init_list(shape,[])
super(Padstack,self).__init__(pin_type=pin_type,shape=shape,attach=attach)
@classmethod
def auto_detect(cls,path,attach='off'):
"""
load a module footprint file and auto detect pad info
output: padstack class
"""
from pykicad.module import Module as mod
import numpy as np
module=mod.from_file(path)
pad_types=[]
for i in range(len(module.pads)):
pad=module.pads[i]
combo=[pad.shape,pad.layers,int(pad.size[0]*unit_convert)]
if not combo in pad_types:
pad_types.append(combo)
padstack=[]
for i in range(len(pad_types)):
shape_class=[]
for layer in pad_types[i][1]:
if '*' in layer:
layer_ext=layer.split('.')[-1]
shape_class.append(Shape(pad_types[i][0],'F.'+layer_ext,pad_types[i][2]))
shape_class.append(Shape(pad_types[i][0],'B.'+layer_ext,pad_types[i][2]))
else:
shape_class.append(Shape(pad_types[i][0],layer,pad_types[i][2]))
pin_type='Round[A]Pad_'+str(int(pad_types[i][2]))+'_um'
padstack_class=cls(pin_type,shape_class,attach)
padstack.append(padstack_class)
return padstack
class Footprint(AST):
tag='image'
schema={
'0':{
'_parser':text,
'_attr':'ref',
},
'outline':{
'_parser':Outline,
'_multiple':True
},
'pin':{
'_parser':Pin,
'_multiple':True
}
}
def __init__(self,ref=None,outline=None,pin=None):
outline=self.init_list(outline,[])
pin=self.init_list(pin,[])
super(Footprint,self).__init__(ref=ref,outline=outline,pin=pin)
@classmethod
def from_file(cls,path,ref='REF**'):
"""
load module footprint from a '.kicad_mod' file
path: afile
ref: ref name of module eg. U1
output: footprint class
"""
from pykicad.module import Module as mod
import numpy as np
module=mod.from_file(path)
outlines=[]
for i in range(len(module.lines)):
outline=module.lines[i]
width=outline.width*unit_convert
outline_start=np.array(outline.start)*unit_convert
# outline_start[1]*=-1
outline_start=list(outline_start)
outline_end=np.array(outline.end)*unit_convert
# outline_end[1]*=-1
outline_end=list(outline_end)
outline_class=Outline(width,outline_start,outline_end)
outlines.append(outline_class)
pads=[]
for i in range(len(module.pads)):
pad=module.pads[i]
pin_index=int(pad.name)
pin_at=np.array(pad.at)*unit_convert
pin_at[1]*=-1
pin_at=list(pin_at)
pin_size=pad.size[0]*unit_convert
pin_type='Round[A]Pad_'+str(int(pin_size))+'_um'
pin_class=Pin(pin_index,pin_at,pin_type)
pads.append(pin_class)
return cls(ref=ref,outline=outlines,pin=pads)
from pykicad.sexpr import *
class Net(AST):
tag='net'
schema={
'0':{
'_parser': text,
'_attr': 'net_name'
},
'1':{
'pins':{
'0':{
'_parser':text +text,
'_attr':'conn_pins'
},
}
}
}
def __init__(self,net_name,conn_pins=None):
super(Net,self).__init__(net_name=net_name,conn_pins=conn_pins)
class NetClass(AST):
tag='class'
schema={
'0':{
'0':{
'_parser':text,
'_attr':'net_class_name'
},
'1':{
'_parser':text+text,
'_attr':'nets_name'
},
},
'circuit':{
'0':{
'use_via':{
'_parser':text,
'_attr':'via_name'
}
}
},
'rule':{
'width':{
'_parser':integer
},
'clearance':{
'_parser': number
}
}
}
def __init__(self,net_class_name='default',nets_name=None,
via_name='',width=3000,clearance=200.1):
super(NetClass,self).__init__(net_class_name=net_class_name,nets_name=nets_name,
via_name=via_name,width=width,clearance=clearance)
from pykicad.sexpr import *
class Clearance(AST):
tag='clearance'
schema={
'0':{
'_parser':number,
'_attr':'number'
},
'1':{
'type':{
'_parser':text,
'_attr':'typex'
},
'_optional':True
},
}
def __init__(self,number=200.1,typex=None):
super(Clearance,self).__init__(number=number,typex=typex)
class Rule(AST):
tag='rule'
schema={
'0':{
'width':{
'_parser': number
},
},
'1':{
'clearance':{
'_parser':Clearance,
'_multiple':True
},
},
}
def __init__(self,width=250,clearance=None):
clearance=self.init_list(clearance,[])
super(Rule,self).__init__(width=width,clearance=clearance)
\ No newline at end of file
#!/usr/bin/env python3
from pykicad.sexpr import *
from dsn_rule import *
from dsn_module import Placement,Footprint, Padstack
import dsn_module as module
from dsn_net import *
from dsn_geo import *
class Parser(AST):
tag = 'parser'
schema = {
'string_quote' : {
'_parser' : text,
'_attr' : 'quote_char'
},
'space_in_quoted_tokens' : {
'_parser': yes_no,
'_attr' : 'tokens_on_off'
},
'host_cad':{
'_parser': text
},
'host_version':{
'_parser':text
}
}
def __init__(self,
quote_char='\"',
tokens_on_off='on',
host_cad= "KiCad's Pcbnew",
host_version="5.1.3-ffb9f22~84~ubuntu18.04.1"):
super(Parser,self).__init__(quote_char=quote_char,
tokens_on_off=tokens_on_off,
host_cad=host_cad,
host_version=host_version)
class Layer(AST):
tag='layer'
schema={
'0':{
'_parser': text,
'_attr': 'name'
},
'type':{
'_parser': Literal('signal') | 'power' | 'mixed' | 'jumper' | 'user',
'_attr': 'typex'
},
'property':{
'index':{
'_parser':text,
'_attr':'index'
},
},
}
index_ctr=0
def __init__(self,name,typex='signal',index=None):
index=Layer.index_ctr
Layer.index_ctr+=1
super(Layer,self).__init__(name=name,typex=typex,index=index)
class Dsn(AST):
tag = 'PCB "kicad_board"'
schema = {
'0':{
'parser' : {
'_parser': Parser
},
},
'1':{
'resolution':{
'_parser': text + integer
},
},
'2':{
'unit':{
'_parser': text
},
},
'3':{
'structure':{
'0':{
'layers':{
'_parser':Layer,
'_multiple':True
},
},
'1':{
'boundary':{
'_parser':Boundary,
'_multiple':False
},
},
'2':{
'keepout':{
'_parser': Keepout,
'_multiple': True
},
},
'3':{
'via':{
'_parser': text,
'_attr': 'via_type'
},
},
'4':{
'rule':{
'_parser': Rule
}
}
},
'_optional':True
},
'4':{
'placement':{
'0':{
'placement':{
'_parser':Placement,
'_multiple':True
},
},
},
},
'5':{
'library':{
'0':{
'image':{
'_parser': Footprint,
'_multiple': True
},
},
'1':{
'_parser':Padstack,
'_multiple': True,
'_attr':'padstack'
}
}
},
'6':{
'network':{
'net':{
'_parser':Net,
'_multiple':True
},
'netclass':{
'_parser':NetClass,
'_multiple':True
}
}
},
'7':{
'wiring':{
'_parser':text, #not available before auto-routing, code can be modificed if want to set route from script manually
}
}
}
def __init__(self,
resolution=['um',10],
unit='um',
parser=None,
layers=None,
boundary=None,
keepout=None,
via_type=None,
rule=None,
placement=None,
image=None,
padstack=None,
net=None,
netclass=None,
wiring= None
):
layers=self.init_list(layers,[])
parser=self.init_list(parser,[])
boundary=self.init_list(boundary,[])
keepout=self.init_list(keepout,[])
placement=self.init_list(placement,[])
image=self.init_list(image,[])
padstack=self.init_list(padstack,[])
net=self.init_list(net,[])
net=self.init_list(netclass,[])
super(Dsn,self).__init__(
resolution=resolution,
unit=unit,
parser=parser,
layers=layers,
boundary=boundary,
keepout=keepout,
via_type=via_type,
rule=rule,
placement=placement,
image=image,
padstack=padstack,
net=net,
netclass=netclass,
wiring=wiring
)
def to_file(self, path):
if not path.endswith('.dsn'):
path += '.dsn'
with open(path, 'w', encoding='utf-8') as f:
f.write(self.to_string())
@classmethod
def from_file(cls, path):
return cls.parse(open(path, encoding='utf-8').read())
\ No newline at end of file
File added
(gui_defaults
(windows
(board_frame
visible
(bounds
351 29 1150 916
)
)
(color_manager
not_visible
(bounds
0 600 1110 134
)
)
(layer_visibility
not_visible
(bounds
0 450 359 162
)
)
(object_visibility
not_visible
(bounds
0 550 395 396
)
)
(display_miscellanious
not_visible
(bounds
0 350 241 333
)
)
(snapshots
not_visible
(bounds
0 250 230 255
)
)
(select_parameter
not_visible
(bounds
0 0 246 467
)
)
(route_parameter
not_visible
(bounds
0 100 261 542
)
)
(manual_rules
not_visible
(bounds
0 27 284 196
)
)
(route_details
not_visible
(bounds
0 27 263 240
)
)
(move_parameter
not_visible
(bounds
0 50 304 139
)
)
(clearance_matrix
not_visible
(bounds
0 150 470 257
)
)
(via_rules
not_visible
(bounds
50 150 335 450
)
)
(edit_vias
not_visible
(bounds
100 150 413 87
)
)
(edit_net_rules
not_visible
(bounds
100 200 913 103
)
)
(assign_net_rules
not_visible
(bounds
100 250 213 84
)
)
(padstack_info
not_visible
(bounds
100 30 0 0
)
)
(package_info
not_visible
(bounds
200 30 0 0
)
)
(component_info
not_visible
(bounds
300 30 0 0
)
)
(net_info
not_visible
(bounds
350 30 0 0
)
)
(incompletes_info
not_visible
(bounds
400 30 0 0
)
)
(violations_info
not_visible
(bounds
500 30 0 0
)
)
)
(colors
(background
204 204 204
)
(hilight 1.0
0 0 204
)
(incompletes 1.0
0 153 153
)
(outline
0 0 0
)
(component_front
0 0 255
)
(component_back
255 0 0
)
(violations
255 0 255
)
(length_matching 1.0
0 255 0
)
(traces 1.0
255 0 0
0 0 255
)
(fixed_traces 1.0
255 0 0
0 0 255
)
(vias 1.0
200 200 0
200 200 0
)
(fixed_vias 1.0
200 200 0
200 200 0
)
(pins 1.0
150 50 0
160 80 0
)
(conduction 1.0
0 150 0
100 100 0
)
(keepout 1.0
0 110 110
0 100 160
)
(via_keepout 1.0
100 100 100
100 100 100
)
)
(parameter
(selection_layers
all_visible
)
(selectable_items
TRACES VIAS PINS FIXED UNFIXED
)
(via_snap_to_smd_center
on
)
(route_mode
dynamic
)
(shove_enabled
on
)
(drag_components_enabled
on
)
(hilight_routing_obstacle
off
)
(pull_tight_region
2147483647
)
(pull_tight_accuracy
500
)
(clearance_compensation
off
)
(ignore_conduction_areas
on
)
(automatic_layer_dimming
0.7
)
(deselected_snapshot_attributes
)
)
)
\ No newline at end of file