summaryrefslogtreecommitdiff
path: root/src/converter/schematic_converters/lib/PythonLib/design.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/converter/schematic_converters/lib/PythonLib/design.py')
-rw-r--r--src/converter/schematic_converters/lib/PythonLib/design.py354
1 files changed, 354 insertions, 0 deletions
diff --git a/src/converter/schematic_converters/lib/PythonLib/design.py b/src/converter/schematic_converters/lib/PythonLib/design.py
new file mode 100644
index 00000000..75899869
--- /dev/null
+++ b/src/converter/schematic_converters/lib/PythonLib/design.py
@@ -0,0 +1,354 @@
+#The MIT License (MIT)
+
+#PSpice to Oscad Schematic Converter
+#This code is written by Suryavamshi Tenneti, FOSSEE, IIT Bombay
+#The code is modified by Sumanto Kar and Gloria Nandihal, FOSSEE, IIT Bombay
+
+
+from header import *
+import math
+
+
+# In the constructors of Line, Arc, Circle and Rectangle, the input parameters shiftx and shifty have already been scaled.
+class Line: #Constructor of Line.
+ npoints = 0
+ x = []
+ y = []
+ def __init__(self, input_stream, shiftx, shifty): #This gets called when the first character of a line is "v".This function assumes "v" and the next character(usually 0) have already been read and are NOT in the stream.
+ t = 0
+ temp = input_stream.readline().strip()
+ self.npoints = 0
+ self.x = []
+ self.y = []
+ while(temp!=';'):
+ #t = temp
+ #print('Line->',temp)
+ t = temp.split()
+ self.x.append(int(t[0]))
+ #t = input_stream.read(1)
+ self.y.append(int(t[1]))
+ #tmp = input_stream.readline().strip() .The first line, i.e.the one that contains the 'v'
+ temp = input_stream.readline().strip()
+
+ self.x[self.npoints]*= MULT
+ self.y[self.npoints]*= -1*MULT
+
+ self.x[self.npoints]-=shiftx
+ self.y[self.npoints]-= -1*shifty
+
+ self.npoints+=1
+
+ if temp != ';':
+ print('Error! \";\" not found\n')# The last character in the description of a line is ";"
+
+
+ def print(self, output_stream):
+ output_stream.write('P '+str(self.npoints)+' 0 1 0 ')
+ for i in range(self.npoints):
+ output_stream.write(str(self.x[i])+' '+str(self.y[i])+' ')
+ output_stream.write('N\n')
+
+class Rectangle: ## Constructor of Rectangle.
+ x1 = 0
+ y1 = 0
+ x2 = 0
+ y2 = 0
+ def __init__(self, input_stream, shiftx, shifty):
+ input_line = input_stream.readline().strip()
+ #print('Rect->',input_line)
+ self.x1, self.y1,self.x2,self.y2 = input_line.split()[:4] # The line that contains the 'r'
+
+ self.x1 = (int(self.x1) * MULT) - shiftx
+ self.x2 = (int(self.x2) * MULT) - shiftx
+ self.y1 = (int(self.y1) * -1 * MULT) - (-1*shifty)
+ self.y2 = (int(self.y2) * -1 * MULT) - (-1*shifty)
+
+ def print(self, output_stream):
+ output_stream.write('S '+str(self.x1)+' '+str(self.y1)+' '+str(self.x2)+' '+str(self.y2)+' 0 1 0 N\n')
+
+
+class Circle: # Constructor of Circle.
+ x = 0
+ y = 0
+ r = 0
+ def __init__(self, input_stream, shiftx, shifty):
+ self.x, self.y, self.r = map(int,input_stream.readline().strip().split())
+ #tmp = input_stream.readline().strip()
+ #print('Circle->','x=',self.x,'y=',self.y,'r=',self.r)
+ self.x*= MULT
+ self.x-= shiftx
+ self.y*=-1*MULT
+ self.y-=-1*shifty
+ self.r*= MULT
+
+ def print(self, output_stream):
+ output_stream.write('C '+str(self.x)+' '+str(self.y)+' '+str(self.r)+' 0 1 0 N\n')
+
+
+class Arc: # Constructor of Arc.
+ x = 0
+ y = 0
+ r = 0
+ sa = 0
+ ea = 0
+ x1 = 0
+ y1 = 0
+ x2 = 0
+ y2 = 0 ## See Line::Line(istream & in , int shiftx, int shifty) above.#From pspice library, get the 3 points that describe the arc.
+
+ def __init__(self, input_stream, shiftx, shifty): # Midpoints of the arcs:
+ xA = 0.0
+ yA = 0.0
+ xB = 0.0
+ yB = 0.0
+ xC = 0.0
+ yC = 0.0
+ xmAB = 0
+ xmBC = 0
+ ymAB = 0
+ ymBC = 0
+ input_line = input_stream.readline().strip()
+ #print('Arc->',input_line)
+ xA,yA,xB,yB,xC,yC = map(float, input_line.split())
+ #tmp = input_stream.readline().strip()
+ yA*= -1
+ yB*= -1
+ yC*= -1
+
+ xmAB = (xA+xB)/2 # The perpendicular bisectors of any two chords of a circle meet at the centre
+ ymAB = (yA+yB)/2
+ xmBC = (xC+xB)/2
+ ymBC = (yC+yB)/2
+
+ mperpAB = -(xB - xA)/(yB - yA)# Get x and y by solving the two lines(perpendicular bisectors)
+ mperpBC = -(xB - xC)/(yB - yC)
+
+ try:
+ self.x = math.trunc((ymBC - ymAB - mperpBC * xmBC + mperpAB * xmAB)/(-mperpBC + mperpAB))
+ except ZeroDivisionError:
+ self.x = float('inf')
+ try:
+ self.y = math.trunc((xmBC - xmAB + (ymAB/mperpAB) - (ymBC/mperpBC))/((1.0/mperpAB)-(1.0/mperpBC)))
+ except ZeroDivisionError:
+ if mperpBC == 0.0:
+ self.y = -float('inf')
+ else:
+ self.y = float('inf')
+
+
+ if not math.isinf(self.y) and not math.isinf(self.x) and not math.isnan(self.x) and not math.isnan(self.y): # Get the radius:
+ self.r = math.trunc(((self.x-xA) * (self.x-xA) + (self.y-yA) * (self.y-yA))**0.5)
+ else:
+ self.r = 0
+
+ a = math.atan2(yA-self.y, xA-self.x)/math.pi*10.0*180.0 # Following code is used to decide which among A and C is the starting point(and thus determines "sa")
+ b = math.atan2(yB-self.y, xB-self.x)/math.pi*10.0*180.0
+ c = math.atan2(yC-self.y, xC-self.x)/math.pi*10.0*180.0
+
+ if b < max(a,c) and b > min(a,c): #b is between a and c# print('*1')
+ #print('*1')
+ self.sa = math.trunc(min(a,c))
+ self.ea = math.trunc(max(a,c))
+
+ if b > max(a,c): #b is largest# print('*2')
+ #print('*2')
+ self.sa = math.trunc(max(a,c))
+ self.ea = math.trunc(min(a,c) + 3600.0)
+
+ if b < min(a,c): #b is smallest# print('*3')
+ #print('*3')
+ self.sa = math.trunc(max(a,c) - 3600.0)
+ self.ea = math.trunc(min(a,c))
+
+ flag_x_inf = False
+ flag_y_inf = False
+
+ if math.isinf(self.x) or math.isnan(self.x):
+ #self.x = shiftx
+ flag_x_inf = True
+
+ if math.isinf(self.y) or math.isnan(self.y):
+ #self.y = shifty
+ flag_y_inf = True
+
+
+ xA = self.x + self.r*math.cos(self.sa*math.pi/1800.0)
+ yA = self.y + self.r*math.sin(self.sa*math.pi/1800.0)
+ xC = self.x + self.r*math.cos(self.ea*math.pi/1800.0)
+ yC = self.y + self.r*math.sin(self.ea*math.pi/1800.0)
+
+ self.sa+=1
+ self.ea-=1
+
+ self.r*=MULT
+
+ self.x1 = (xA*MULT)-shiftx
+ self.y1 = ((yA*MULT)-(-1)*shifty)
+ self.x2 = ((xC*MULT)-shiftx)
+ self.y2 = ((yC*MULT)-(-1)*shifty)
+
+ if not flag_x_inf:
+ self.x*=MULT
+ self.x-=shiftx
+
+ else:
+ self.x = shiftx
+
+ if not flag_y_inf:
+ self.y*=MULT
+ self.y-=(-1)*shifty
+
+ else:
+ self.y = shifty
+ # scale and shift: #startx, starty, endx, endy are redundant.May not even be in use.Haven 't been fixed.
+
+ if math.isinf(self.x1) or math.isnan(self.x1) or math.isinf(self.y1) or math.isnan(self.y1) or math.isinf(self.x2) or math.isnan(self.x2) or math.isinf(self.y2) or math.isnan(self.y2):
+ self.x1 = -(2**31)
+ self.x2 = -(2**31)
+ self.y1 = -(2**31)
+ self.y2 = -(2**31)
+
+ else:
+ self.x1 = math.trunc(self.x1)
+ self.y1 = math.trunc(self.y1)
+ self.x2 = math.trunc(self.x2)
+ self.y2 = math.trunc(self.y2)
+
+ '''
+ if mperpAB == 0 or mperpBC == 0:
+ print('mperpAB=',mperpAB, 'mperpBC=', mperpBC)
+ print('X=',self.x,'Y=',self.y)
+ print('Radius=',self.r)
+ print('a=',a,'b=',b,'c=',c)
+ print('xA=',xA,'yA=',yA,'xC=',xC,'yC=',yC)
+ print('x=',self.x,'y=',self.y)
+ print('x1=',self.x1,'x2=',self.x2,'y1=',self.y1,'y2=',self.y2)
+ print('sa=',self.sa,'ea=',self.ea)
+ '''
+ def print(self,output_stream):
+ output_stream.write('A '+str(math.trunc(self.x))+' '+str(math.trunc(self.y))+' '+str(int(self.r))+' '+str(int(self.sa))+' '+str(int(self.ea))+' '+' 0 1 0 N '+str(int(self.x1))+' '+str(int(self.y1))+' '+str(int(self.x2))+' '+str(int(self.y2))+' '+'\n')
+
+
+class Text: #Constructor of Circle.
+ x = 0
+ y = 0
+ text = ''
+ orient = ''
+
+ def __init__(self,input_stream, shiftx, shifty):
+ input_line = input_stream.readline().strip().split()
+ self.x,self.y,self.orient = input_line[:3]
+ self.x = int(self.x)
+ self.y = int(self.y)
+ #tmp = input_stream.readline().strip()
+
+ self.text = input_stream.readline().strip()
+ self.x*=MULT
+ self.y*=-1*MULT
+ self.x-=shiftx
+ self.y-=-1*shifty
+
+ def print(self,output_stream):
+ output_stream.write('T ') # The line that contains the 't'
+ if self.orient[0] == 'h':
+ output_stream.write('0 ')
+ elif self.orient[0] == 'v':
+ output_stream.write('900 ')
+ output_stream.write(str(self.x)+' '+str(self.y)+' '+str(30)+' 0 0 0 '+self.text+'\n')
+
+
+class Design: #Constructor of Design.
+ shiftx = 0
+ shifty = 0
+ lines = []
+ rects = []
+ circles = []
+ arcs = []
+ texts = [] # Reads the whole design, makes Line, Circle, etc.objects and stores them in the appropriate container(appropriate vector)
+ def __init__(self, input_stream):
+ g = 0
+ tmp = ''
+ t = 0
+ tint = ''
+ tmp = input_stream.readline().strip()
+ #print('Design->', tmp)
+ if('@graphics' not in tmp):
+ print('Design not found!')
+ return
+ #print('Graphics->',tmp.split())
+ self.lines = []
+ self.rects = []
+ self.circles = []
+ self.arcs = []
+ self.texts = []
+ tmp = tmp.split()
+ tint,tint,tint,self.shiftx,self.shifty= map(str,tmp[:5])
+ if len(tmp) > 5:
+ tmp = ''.join(tmp[5:])
+ self.shiftx = int(self.shiftx)*MULT # print('shiftx->', self.shiftx, 'shifty->', self.shifty)
+ self.shifty = int(self.shifty)*MULT
+ #print('shiftx->',self.shiftx,'shifty->',self.shifty)
+ while(t!= '*'): #As long as we haven 't reached the description of the next Component continue reading the lib file.
+ g = input_stream.tell() # Get the position of the read head, so that we can go back to this position
+ t = input_stream.read(1) # Get the first character of the description, store in "t".This character gives what shape it is.
+ if not t:
+ break
+
+ if t == 'v':
+ #print('Line')
+ input_stream.read(1)
+ input_stream.read(1)
+ input_stream.read(1)
+ l = Line(input_stream, self.shiftx, self.shifty)
+ self.lines.append(l)
+
+ elif t == 'r':
+ #print('Rect')
+ input_stream.read(1)
+ input_stream.read(1)
+ input_stream.read(1)
+ r = Rectangle(input_stream, self.shiftx, self.shifty)
+ self.rects.append(r)
+
+ elif t == 'c':
+ #print('Circle')
+ input_stream.read(1)
+ input_stream.read(1)
+ input_stream.read(1)
+ c = Circle(input_stream, self.shiftx, self.shifty)
+ self.circles.append(c)
+
+ elif t == 'a':
+ #print('Arc')
+ input_stream.read(1)
+ input_stream.read(1)
+ input_stream.read(1)
+ a = Arc(input_stream, self.shiftx, self.shifty)
+ self.arcs.append(a)
+
+ elif t == 'z':
+ #print('Text')
+ input_stream.read(1)
+ input_stream.read(1)
+ input_stream.read(1)
+ z = Text(input_stream, self.shiftx, self.shifty)
+ self.texts.append(z)
+
+ else: #If t is neither 'v', 'r', 'c'
+ tmp = input_stream.readline().strip()
+ g = input_stream.tell()
+
+ input_stream.seek(g)
+
+
+ def print(self, output_stream):
+ for i in range(len(self.lines)):
+ self.lines[i].print(output_stream)
+ for i in range(len(self.rects)):
+ self.rects[i].print(output_stream)
+ for i in range(len(self.circles)):
+ self.circles[i].print(output_stream)
+ for i in range(len(self.arcs)):
+ self.arcs[i].print(output_stream)
+ for i in range(len(self.texts)):
+ self.texts[i].print(output_stream)