def __init__(self, radius = 25.,curvature_s1= 0.01,curvature_s2= 0.01, curvature_s3= 0.01, thickness_l1= 5, thickness_l2= 5, material_l1=1., material_l2=1.,*args,**kwarks): System.__init__(self,*args,**kwarks) self.radius=radius self.curvature_as= curvature_s1 self.curvature_ms=curvature_s2 self.curvature_ps=curvature_s3 self.thickness_al=thickness_l1 self.thickness_pl=thickness_l2 self.material_al=material_l1 self.material_pl=material_l2 __a_lens= SphericalLens(curvature_s1=self.curvature_as, curvature_s2=self.curvature_ms, thickness=self.thickness_al, radius =self.radius, material=self.material_al) __p_lens= SphericalLens(curvature_s1=self.curvature_ms, curvature_s2=self.curvature_ps, thickness=self.thickness_pl, radius =self.radius, material=self.material_pl) self.complist["C1"]=(__a_lens,(0,0,-self.thickness_pl/2.),(0,0,0)) self.complist["C2"]=(__p_lens,(0,0, self.thickness_al/2.),(0,0,0))
def __init__(self, radius = 25.,curvature_s1= 0.01,curvature_s2= 0.01, curvature_s3= 0.01,curvature_s4= 0.01, thickness_l1= 5,air_gap=5 , thickness_l2= 5, material_l1=1., material_l2=1.,*args,**kwarks): System.__init__(self,*args,**kwarks) self.radius=radius self.curvature_as1= curvature_s1 self.curvature_ps1=curvature_s2 self.curvature_as2=curvature_s3 self.curvature_ps2=curvature_s4 self.thickness_l1=thickness_l1 self.thickness_l2=thickness_l2 self.air_gap=air_gap self.material_l1=material_l1 self.material_l2=material_l2 __a_lens= SphericalLens(curvature_s1=self.curvature_as1, curvature_s2=self.curvature_ps1, thickness=self.thickness_l1, radius =self.radius, material=self.material_l1) __p_lens= SphericalLens(curvature_s1=self.curvature_as2, curvature_s2=self.curvature_ps2, thickness=self.thickness_l2, radius =self.radius, material=self.material_l2) self.complist["C1"]=(__a_lens,(0,0,-(self.thickness_l2+self.air_gap)/2.),(0,0,0)) self.complist["C2"]=(__p_lens,(0,0, (self.thickness_l1+self.air_gap)/2.),(0,0,0))
def evaluate_geometry(): lightsources = [] components = [] apertures = [] for obj_key in bpy.data.objects.keys(): obj = bpy.data.objects[obj_key] if not 'source' in obj.data.name: if 'n' in obj.keys(): # for this to be true, n must be define as custom property in Blender "Object Properties" <- NOT Mesh Properties mw = obj.matrix_world mesh = obj.data mesh.calc_loop_triangles() loop_triangles = mesh.loop_triangles S_list = [] for tri in loop_triangles: tri_center = np.array(mw @ tri.center.to_3d()) # get global vertice coordinate-vectors from mesh by their index tri_vertices = [ mw @ mesh.vertices[index].co for index in tri.vertices ] # convert to arrays vertices = [ np.array(vertice.to_3d()) for vertice in tri_vertices ] S = surfaces.Plane(reflectivity=0, shape=shapes.Triangular( (vertices[0], vertices[1], vertices[2]))) S_list.append(S) C = Component(surflist=S_list, material=np.float(obj['n'])) components.append(C) else: print( obj.name, 'not included in ray-trace; no refractive index defined.') else: mw = obj.matrix_world mesh = obj.data mesh.calc_loop_triangles() loop_triangles = mesh.loop_triangles for tri in loop_triangles: tri_vertices = [ mw @ mesh.vertices[index].co for index in tri.vertices ] # convert to arrays vertices = [ np.array(vertice.to_3d()) for vertice in tri_vertices ] apertures.append(vertices) try: Sys = System(complist=components, n=bpy.data.worlds['World']['n']) except KeyError: Sys = System(complist=components, n=1.0) print('Geometries evaluated.') return Sys, apertures
def __init__(self, size=50.,reflectivity=0.5,material=1., **traits): System.__init__(self,**traits) self.size=size self.reflectivity=reflectivity self.material=material __prism1= RightAnglePrism(width=self.size,height=self.size, material=self.material, reflectivity=self.reflectivity) __prism2= RightAnglePrism(width=self.size,height=self.size, material=self.material,reflectivity=0) self.complist["C1"]=(__prism1,(0,0,0),(0,-pi/2,0)) self.complist["C2"]=(__prism2,(0,0,0),(0,-3*pi/2,0))
def find_ppp(opsys, opaxis): """Function to find the primary principal plane location of a lens or an optical component Arguments: opsys Optical system or optical component whose principal planes are to be found opaxis Ray defining the optical axis of the system For this function to operate, the system should have a rotational symetry around the optical axis. Note: This function is returns the intersection point of the optical axis and the principal plane. """ # Create a system with the component if isinstance(opsys, (Component)): c = opsys opsys = System(complist=[(c, (0, 0, 0), (0, 0, 0))], n=1) # To create a ray parallel to the optical axis, find a displacement vector # perpendicular to the optical axis, and to the XYZ axes d = opaxis.dir pv1 = cross(d, (0, 0, 1)) pv2 = cross(d, (0, 1, 0)) pv3 = cross(d, (1, 0, 0)) pv = [pv1, pv2, pv3] # Search for the longest pv pvn = array((dot(pv1, pv1), dot(pv2, pv2), dot(pv3, pv3))) pvm = pv[pvn.argmax()] # Create parallel ray par_ray = opaxis.copy() par_ray.pos = par_ray.pos + pvm * 0.0001 opsys.clear_ray_list() opsys.ray_add([opaxis, par_ray]) opsys.propagate() par_ray_end = par_ray.get_final_rays(inc_zeros=False) if len(par_ray_end) != 1: raise Exception, "The paraxial ray has more than one final ray" pppl = intersection(par_ray, par_ray_end[0]) # Move the intersection point toward the optical axis ppp = pppl[0] - pvm * 0.0001 return ppp # , pppl[1])
def __init__(self, sd, *args, **kwarks): System.__init__(self, *args, **kwarks) # Calculate the lens total thickness TT = 0 for s in sd[:-1]: TT = TT + s[2] p = -TT / 2 nn = 1 for n in range(1, len(sd)): t0, r0, th0, s0, mc0, mt0 = sd[n - 1] t1, r1, th1, s1, mc1, mt1 = sd[n] if isnan(r0) or r0 == 0: c0 = 0 else: c0 = 1 / r0 if isnan(r1) or r1 == 0: c1 = 0 else: c1 = 1 / r1 if mt0 != "": if mc0 == "Value": mat = float(mt0.replace(",", ".")) else: mat = getattr(material, mc0)[mt0] lens = SphericalLens( curvature_s1=c0, curvature_s2=c1, thickness=th0, radius=s0, material=mat, ) 0, 0, p + th0 / 2 self.complist["C{}".format(nn)] = (lens, (0, 0, p + th0 / 2), (0, 0, 0)) nn = nn + 1 p = p + th0
def getActiveSystem(): objs = FreeCAD.ActiveDocument.Objects rays = [] complist = [] for obj in objs: # Todos los componentes de pyoptools tienen attributo cType if not hasattr(obj, "cType"): print("Object {} not recognized by pyoptools, ignored.".format( obj.Label)) continue if not obj.enabled: continue print("Object {} recognized by pyoptools".format(obj.Label)) pla = obj.getGlobalPlacement() X, Y, Z = pla.Base # No entiendo el orden pero parece que funciona RZ, RY, RX = pla.Rotation.toEuler() # Hay que buscar una mejor forma de hacer esto, es decir como no tener # que pasar obj en los parametros try: e = obj.Proxy.pyoptools_repr(obj) except AttributeError: outputDialog("Object {} can not be read. Check if the conversion\n" "file is correct.") if isinstance(e, list): rays.extend(e) else: complist.append(( e, (X, Y, Z), (radians(RX), radians(RY), radians(RZ)), obj.Label, )) S = System(complist) return S, rays
def get_optical_path_ep(opsys, opaxis, raylist, stop=None, r=None): """Returns the optical path traveled by a ray up to the exit pupil The optical path is measured from the ray origin until it crosses the exit pupil of the system. If a stop (aperture) is not given, the measurement is made up to the primary principal plane. Arguments: opsys Optical system under analisis opaxis Ray indicating the optical axis the origin of the optical axis, must be the position of the object used in the image formation. This is needed to be able to calculate the radius of the reference sphere. raylist List of rays that will be used to sample the optical path stop Aperture stop of the system. It must belong to opsys. In not given it will be assumed that the exit pupil is at the primary principal plane. r If None, measure up to the exit pupil plane. If given, use a reference sphere with a vertex coinciding with the optical vertex. Return Value (hcl,opl,pc) hcl List containing the coordinates of the hits in the pupil coordinate system. opl list containing the optical paths measured pc intersection point between the optical axis, and the pupil plane. hcl[i] corresponds to opl[i] Note: This method only works if the optical axis coincides with the Z axis. This must be corrected. """ if stop != None: enp, exp = pupil_location(opsys, stop, opaxis) else: exp = find_ppp(opsys, opaxis) #Reset the system opsys.clear_ray_list() opsys.reset() # Propagate the rays #print "***", raylist opsys.ray_add(raylist) opsys.propagate() #pf=PlotFrame(opsys=opsys) rl = [] l = [] # Get the optical path up to the final element in the system for i in raylist: a = i.get_final_rays() if a[0].intensity != 0: # Reverse the rays to calculate the optical path from the final element #to the exit pupil nray = a[0].reverse() rl.append(nray) #TODO: This should not be done using the label nray.label = str(a[0].optical_path_parent()) # Create a dummy system to calculate the wavefront at the exit pupil if r == None: #TODO: This ccd should be infinitely big. Have to see how this can be done ccd = CCD(size=(1000, 1000)) else: ccds = Spherical(shape=Circular(radius=0.9 * r), curvature=1. / r) ccd = Component(surflist=[ (ccds, (0, 0, 0), (0, 0, 0)), ]) #print rl dummy = System(complist=[ (ccd, exp, (0, 0, 0)), ], n=1.) #Calculate the optical path from the final element to the exit pupil plane dummy.ray_add(rl) dummy.propagate() #PlotFrame(opsys=dummy) hcl = [] opl = [] for ip, r in ccd.hit_list: #print ip x, y, z = ip #TODO: This should not be done using the label d = float(r.label) - r.optical_path() hcl.append((x, y, z)) opl.append(d) return (hcl, opl, exp)
def find_ppp(opsys, opaxis): """Function to find the primary principal plane location of a lens or an optical component Arguments: opsys Optical system or optical component whose principal planes are to be found opaxis Ray defining the optical axis of the system For this function to operate, the system should have a rotational symmetry around the optical axis. Note: This function is returns the intersection point of the optical axis and the principal plane. """ # Create a system with the component if isinstance(opsys, (Component)): c = opsys opsys = System(complist=[ (c, (0, 0, 0), (0, 0, 0)), ], n=1) # To create a ray parallel to the optical axis, find a displacement vector # perpendicular to the optical axis, and to the XYZ axes d = opaxis.dir pv1 = cross(d, (0, 0, 1)) pv2 = cross(d, (0, 1, 0)) pv3 = cross(d, (1, 0, 0)) pv = [pv1, pv2, pv3] # Search for the longest pv pvn = array((dot(pv1, pv1), dot(pv2, pv2), dot(pv3, pv3))) pvm = pv[pvn.argmax()] # Create parallel ray par_ray = opaxis.copy() par_ray.pos = par_ray.pos + pvm * .0001 opsys.clear_ray_list() opsys.ray_add([opaxis, par_ray]) opsys.propagate() par_ray_end = par_ray.get_final_rays(inc_zeros=False) if len(par_ray_end) != 1: raise Exception("The paraxial ray has more than one final ray") pppl = intersection(par_ray, par_ray_end[0]) #Move the intersection point toward the optical axis ppp = pppl[0] - pvm * .0001 return ppp #, pppl[1])
def get_optical_path_ep(opsys, opaxis, raylist, stop=None, r=None): """Returns the optical path traveled by a ray up to the exit pupil The optical path is measured from the ray origin until it crosses the exit pupil of the system. If a stop (aperture) is not given, the measurement is made up to the primary principal plane. Arguments: opsys Optical system under analisis opaxis Ray indicating the optical axis the origin of the optical axis, must be the position of the object used in the image formation. This is needed to be able to calculate the radius of the reference sphere. raylist List of rays that will be used to sample the optical path stop Aperture stop of the system. It must belong to opsys. In not given it will be assumed that the exit pupil is at the primary principal plane. r If None, measure up to the exit pupil plane. If given, use a reference sphere with a vertex coinciding with the optical vertex. Return Value (hcl,opl,pc) hcl List containing the coordinates of the hits in the pupil coordinate system. opl list containing the optical paths measured pc intersection point between the optical axis, and the pupil plane. hcl[i] corresponds to opl[i] Note: This method only works if the optical axis coincides with the Z axis. This must be corrected. """ if stop != None: enp,exp=pupil_location(opsys,stop,opaxis) else: exp= find_ppp(opsys, opaxis) #Reset the system opsys.clear_ray_list() opsys.reset() # Propagate the rays #print "***", raylist opsys.ray_add(raylist) opsys.propagate() #pf=PlotFrame(opsys=opsys) rl=[] l=[] # Get the optical path up to the final element in the system for i in raylist: a=i.get_final_rays() if a[0].intensity!=0: # Reverse the rays to calculate the optical path from the final element #to the exit pupil nray=a[0].reverse() rl.append(nray) #TODO: This should not be done using the label nray.label=str(a[0].optical_path_parent()) # Create a dummy system to calculate the wavefront at the exit pupil if r==None: #TODO: This ccd should be infinitely big. Have to see how this can be done ccd=CCD(size=(1000,1000)) else: ccds=Spherical(shape=Circular(radius=0.9*r), curvature=1./r) ccd=Component(surflist=[(ccds, (0, 0, 0), (0, 0, 0)), ]) #print rl dummy=System(complist=[(ccd,exp,(0,0,0)), ],n=1.) #Calculate the optical path from the final element to the exit pupil plane dummy.ray_add(rl) dummy.propagate() #PlotFrame(opsys=dummy) hcl=[] opl=[] for ip,r in ccd.hit_list: #print ip x,y,z= ip #TODO: This should not be done using the label d= float(r.label)-r.optical_path() hcl.append((x, y, z)) opl.append(d) return (hcl, opl, exp)
data=temppng.getvalue() temppng.close() #~ print 'Saved image to %s'% (os.path.abspath( filename)) #~ return image return Image(data,embed=True) if __name__ == "__main__": from pyoptools.all import * # Blue r_b= parallel_beam_c(size=(10,10),num_rays=(10,10), wavelength=.470) N_BK7=schott['BK7'] bs=BeamSplitingCube(size=50,material=N_BK7,reflectivity=0.5) #Definition of a detector plane ccd=CCD(size=(20, 20)) os=System(complist=[(bs,(0,0,50),(0,0,0)), (ccd,(0,0,100),(0,0,0)), ],n=1) #Add the ray sources os.ray_add(r_b) #Propagate the rays os.propagate() app = wx.PySimpleApp(0) wx.InitAllImageHandlers() oglFrame = glPlotFrame2(os) app.SetTopWindow(oglFrame) oglFrame.Show() app.MainLoop()