diff options
Diffstat (limited to 'src/converter/schematic_converters/lib/PythonLib/design.py')
-rw-r--r-- | src/converter/schematic_converters/lib/PythonLib/design.py | 354 |
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) |