def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return #bruce 050421 c = self.posn() a = self.axen() xrot = -atan2(a[1], sqrt(1 - a[1] * a[1])) * 180 / pi yrot = atan2(a[0], sqrt(1 - a[0] * a[0])) * 180 / pi file.write("lmotor(" \ + povpoint([self.width * 0.5, self.width * 0.5, self.length * 0.5]) + "," \ + povpoint([self.width * -0.5, self.width * -0.5, self.length * -0.5]) + "," \ + "<0.0, " + str(yrot) + ", 0.0>," \ + "<" + str(xrot) + ", 0.0, 0.0>," \ + povpoint(c) + "," \ + "<" + str(self.color[0]) + "," + str(self.color[1]) + "," + str(self.color[2]) + ">)\n") for a in self.atoms: if vlen( c - a.posn() ) > 0.001: #bruce 060808 add condition to see if this fixes bug 719 (two places in this file) file.write("spoke(" + povpoint(c) + "," + povpoint(a.posn()) + "," + str(self.sradius) + ",<" + str(self.color[0]) + "," + str(self.color[1]) + "," + str(self.color[2]) + ">)\n")
def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return #bruce 050421 c = self.posn() a = self.axen() file.write("rmotor(" + povpoint(c+(self.length / 2.0)*a) + "," + povpoint(c-(self.length / 2.0)*a) + "," + str (self.radius) + ",<" + str(self.color[0]) + "," + str(self.color[1]) + "," + str(self.color[2]) + ">)\n") for a in self.atoms: if vlen(c - a.posn()) > 0.001: #bruce 060808 add condition to see if this fixes bug 719 (two places in this file) file.write("spoke(" + povpoint(c) + "," + povpoint(a.posn()) + "," + str (self.sradius) + ",<" + str(self.color[0]) + "," + str(self.color[1]) + "," + str(self.color[2]) + ">)\n")
def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return if self.picked: c = self.normcolor else: c = self.color for a in self.atoms: disp, rad = a.howdraw(dispdef) grec = ( "gamess(" + povpoint(a.posn()) + "," + str(rad) + ",<" + str(c[0]) + "," + str(c[1]) + "," + str(c[2]) + ">)\n" ) file.write(grec)
def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return if self.picked: c = self.normcolor else: c = self.color for a in self.atoms: disp, rad = a.howdraw(dispdef) grec = "gamess(" + povpoint(a.posn()) + "," + str(rad) + ",<" + str(c[0]) + "," + str(c[1]) + "," + str(c[2]) + ">)\n" file.write(grec)
def writepov(self, file, dispdef): if self.hidden: return if self.is_disabled(): return #bruce 050421 c = self.posn() a = self.axen() xrot = -atan2(a[1], sqrt(1-a[1]*a[1]))*180/pi yrot = atan2(a[0], sqrt(1-a[0]*a[0]))*180/pi file.write("lmotor(" \ + povpoint([self.width * 0.5, self.width * 0.5, self.length * 0.5]) + "," \ + povpoint([self.width * -0.5, self.width * -0.5, self.length * -0.5]) + "," \ + "<0.0, " + str(yrot) + ", 0.0>," \ + "<" + str(xrot) + ", 0.0, 0.0>," \ + povpoint(c) + "," \ + "<" + str(self.color[0]) + "," + str(self.color[1]) + "," + str(self.color[2]) + ">)\n") for a in self.atoms: if vlen(c - a.posn()) > 0.001: #bruce 060808 add condition to see if this fixes bug 719 (two places in this file) file.write("spoke(" + povpoint(c) + "," + povpoint(a.posn()) + "," + str (self.sradius) + ",<" + str(self.color[0]) + "," + str(self.color[1]) + "," + str(self.color[2]) + ">)\n")
def writepovfile(part, glpane, filename): """ write the given part into a new POV-Ray file with the given name, using glpane for lighting, color, etc """ f = open(filename,"w") # POV-Ray images now look correct when Projection = ORTHOGRAPHIC. Mark 051104. if glpane.ortho == PERSPECTIVE: cdist = 6.0 # Camera distance [see also glpane.cdist] else: # ORTHOGRAPHIC cdist = 1600.0 aspect = (glpane.width + 0.0)/(glpane.height + 0.0) zfactor = 0.4 # zoom factor up = V(0.0, zfactor, 0.0) right = V( aspect * zfactor, 0.0, 0.0) ##1.33 angle = 2.0*math.atan2(aspect, cdist)*180.0/math.pi f.write("// Recommended window size: width=%d, height=%d \n"%(glpane.width, glpane.height)) f.write("// Suggested command line switches: +A +W%d +H%d\n\n"%(glpane.width, glpane.height)) f.write(povheader) # Camera info vdist = cdist if aspect < 1.0: vdist = cdist / aspect eyePos = vdist * glpane.scale*glpane.out-glpane.pov f.write("#declare cameraPosition = "+ povpoint(eyePos) + ";\n" + "\ncamera {\n location cameraPosition" + "\n up " + povpoint(up) + "\n right " + povpoint(right) + "\n sky " + povpoint(glpane.up) + "\n angle " + str(angle) + "\n look_at " + povpoint(-glpane.pov) + "\n}\n\n") # Background color. The SkyBlue gradient is supported, but only works correctly when in "Front View". # This is a work in progress (and this implementation is better than nothing). See bug 888 for more info. # Mark 051104. if glpane.backgroundGradient: # SkyBlue. dt = Q(glpane.quat) if not vlen(V(dt.x, dt.y, dt.z)): # This addresses a problem in POV-Ray when dt=0,0,0 for Axis_Rotate_Trans. mark 051111. dt.x = .00001 degY = dt.angle*180.0/math.pi f.write("sky_sphere {\n" + " pigment {\n" + " gradient y\n" + " color_map {\n" + " [(1-cos(radians(" + str(90-angle/2) + ")))/2 color SkyWhite]\n" + " [(1-cos(radians(" + str(90+angle/2) + ")))/2 color SkyBlue]\n" + " }\n" + " scale 2\n" + " translate -1\n" + " }\n" + ' #include "transforms.inc"\n' + " Axis_Rotate_Trans(" + povpoint(V(dt.x, dt.y, dt.z)) + ", " + str(degY) + ")\n" + " }\n") else: # Solid f.write("background {\n color rgb " + povpoint(glpane.backgroundColor*V(1,1,-1)) + "\n}\n") # Lights and Atomic finish. _writepovlighting(f, glpane) # write a union object, which encloses all following objects, so it's # easier to set a global modifier like "Clipped_by" for all objects # Huaicai 1/6/05 f.write("\nunion {\t\n") # Head of the union object # Write atoms and bonds in the part part.writepov(f, glpane.displayMode) #bruce 050421 changed assy.tree to assy.part.topnode to fix an assy/part bug #bruce 050927 changed assy.part -> new part arg #bruce 070928 call part.writepov instead of directly calling part.topnode.writepov, # so the part can prevent external bonds from being drawn twice. # set the near and far clipping plane # removed 050817 josh -- caused crud to appear in the output (and slowed rendering 5x!!) ## farPos = -cdist*glpane.scale*glpane.out*glpane.far + eyePos ## nearPos = -cdist*glpane.scale*glpane.out*glpane.near + eyePos ## pov_out = (glpane.out[0], glpane.out[1], -glpane.out[2]) ## pov_far = (farPos[0], farPos[1], -farPos[2]) ## pov_near = (nearPos[0], nearPos[1], -nearPos[2]) ## pov_in = (-glpane.out[0], -glpane.out[1], glpane.out[2]) ## f.write("clipped_by { plane { " + povpoint(-glpane.out) + ", " + str(dot(pov_in, pov_far)) + " }\n") ## f.write(" plane { " + povpoint(glpane.out) + ", " + str(dot(pov_out, pov_near)) + " } }\n") # [and what was this for? bruce question 071009] ## if glpane.currentCommand.commandName == 'DEPOSIT': ## dt = -glpane.quat ## degY = dt.angle*180.0/pi ## f.write("plane { \n" + ## " z 0\n" + ## " pigment { color rgbf <0.29, 0.7294, 0.8863, 0.6>}\n" + ## ' #include "transforms.inc"\n' + ## " Axis_Rotate_Trans(" + povpoint(V(dt.x, dt.y, dt.z)) + ", " + str(degY) + ")}\n") f.write("}\n\n") f.close() return # from writepovfile
def _writepovlighting(f, glpane): """ Writes a light source record for each light (if enabled) and the 'Atomic' finish record. These records impact the lighting affect. """ # Get the lighting parameters for the 3 lights. (((r0,g0,b0),a0,d0,s0,x0,y0,z0,e0), \ ( (r1,g1,b1),a1,d1,s1,x1,y1,z1,e1), \ ( (r2,g2,b2),a2,d2,s2,x2,y2,z2,e2)) = glpane.getLighting() # For now, we copy the coords of each light here. pos0 = (glpane.right * x0) + (glpane.up *y0) + (glpane.out * z0) pos1 = (glpane.right * x1) + (glpane.up * y1) + (glpane.out * z1) pos2 = (glpane.right * x2) + (glpane.up * y2) + (glpane.out * z2) # The ambient values of only the enabled lights are summed up. # 'ambient' is used in the 'Atomic' finish record. It can have a value # over 1.0 (and makes a difference). ambient = 0.25 # Add 0.25; matches better with NE1 default lighting. # The diffuse values of only the enabled lights are summed up. # 'diffuse' is used in the 'Atomic' finish record. It can have a value # over 1.0 (and makes a difference). diffuse = 0.0 f.write( "\n// Light #0 (Camera Light)" + "\nlight_source {" + "\n cameraPosition" + "\n color <0.3, 0.3, 0.3>" + "\n parallel" + "\n point_at <0.0, 0.0, 0.0>" + "\n}\n") if e0: # Light 1 is On ambient += a0 diffuse += d0 f.write( "\n// Light #1" + "\nlight_source {" + "\n " + povpoint(pos0) + "\n color <" + str(r0*d0) + ", " + str(g0*d0) + ", " + str(b0*d0) + ">" + "\n parallel" + "\n point_at <0.0, 0.0, 0.0>" + "\n}\n") if e1: # Light 2 is On ambient += a1 diffuse += d1 f.write( "\n// Light #2" + "\nlight_source {\n " + povpoint(pos1) + "\n color <" + str(r1*d1) + ", " + str(g1*d1) + ", " + str(b1*d1) + ">" + "\n parallel" + "\n point_at <0.0, 0.0, 0.0>" + "\n}\n") if e2: # Light 3 is On ambient += a2 diffuse += d2 f.write("\n// Light #3" + "\nlight_source {\n " + povpoint(pos2) + "\n color <" + str(r2*d2) + ", " + str(g2*d2) + ", " + str(b2*d2) + ">" + "\n parallel" + "\n point_at <0.0, 0.0, 0.0>" + "\n}\n") # Atomic finish record. # # phong determines the brightness of the highlight, while phong_size determines its size. # # phong: 0.0 (no highlight) to 1.0 (saturated highlight) # # phong_size: 1 (very dull) to 250 (highly polished) # The larger the phong size the tighter, or smaller, the highlight and # the shinier the appearance. The smaller the phong size the looser, # or larger, the highlight and the less glossy the appearance. # # Good values: # brushed metal: phong .25, phong_size 12 # plastic: .7, phong_size 17 # # so phong ranges from .25 - .7 # and phong_size ranges from 12-17 # if env.prefs[material_specular_highlights_prefs_key]: # whiteness: 0.0-1.0, where 0 = metal and 1 = plastic phong = 0.25 + (env.prefs[material_specular_finish_prefs_key] * 0.45) # .25-.7 phong_size = 12.0 + (env.prefs[material_specular_finish_prefs_key] * 5.0) # 12-17 else: phong = 0.0 # No specular highlights phong_size = 0.0 f.write( "\n#declare Atomic =" + "\nfinish {" + "\n ambient 0.1" + # str(ambient) + # Mark 060929 "\n diffuse " + str(diffuse) + "\n phong " + str(phong) + "\n phong_size " + str(phong_size) + "\n}\n") return # from _writepovlighting