Package parasol :: Module POV_Items
[hide private]
[frames] | no frames]

Source Code for Module parasol.POV_Items

  1  from POV_Basics import * 
  2  from math import * 
  3   
4 -class Item(object):
5 - def __init__(self, texture=None):
6 7 self.texture = texture 8 if texture==None: self.texture=Texture() 9 self.transformList = [] 10 self.volume = 0.0
11
12 - def translate(self, vectL=[1,1,1]):
13 self.transformList.append('translate '+ str(Vector(vectL)))
14
15 - def rotate(self, vectL=[0,20,0]):
16 self.transformList.append('rotate '+ str(Vector(vectL)))
17
18 - def scale(self, scaleL=[2,2,2]):
19 self.transformList.append('scale '+ str(Vector(scaleL))) 20 21 sfact = 1.0 22 for s in scaleL: 23 sfact *= s 24 self.volume *= sfact
25
26 - def transformStr(self):
27 return ' '.join(self.transformList) + ' '
28 29
30 - def __str__(self):
31 return 'NEED TO OVERRIDE THE __str__ definition in Item'
32 33
34 -class DeclaredItem(object):
35 '''Will get a #declare statement in the POV file''' 36
37 - def __init__(self, name='myItem', itemList=None):
38 39 self.name = name 40 self.itemList = [] 41 self.transformList = [] 42 if itemList: 43 for item in itemList: 44 self.itemList.append(item)
45
46 - def positionStr(self):
47 sL = [' object { %s \n'%self.name] 48 for t in self.transformList: 49 sL.append(' ' + t + '\n') 50 sL.append(' }') 51 return ''.join(sL)
52
53 - def pointAlign(self, face="-x", pointL=[0,1,0]):
54 # -x=left side, +x=right side, -y=bottom, +y=top, -z=near, +z=far 55 self.transformList.append('Align_Trans( '+ self.name + ', ' + face + ', ' + str(Vector(pointL)) + ')')
56
57 - def center(self, axes="x+y"):
58 # Doesn't seem to work ??? 59 self.transformList.append('Center_Trans( '+ self.name + ', ' + axes + ')')
60
61 - def alignAxes(self, axis1L=[0,1,0], axis2L=[1,1,1]):
62 self.transformList.append('Reorient_Trans( '+ str(Vector(axis1L)) + ', ' + str(Vector(axis2L)) + ')')
63
64 - def axisRotate(self, vectL=[1,1,1], degrees=45):
65 self.transformList.append('Axis_Rotate_Trans( '+ str(Vector(vectL)) + ', ' + str(degrees) + ')')
66
67 - def pointRotate(self, rotL=[0,45,0], pointL=[1,1,1]):
68 self.transformList.append('Rotate_Around_Trans( '+ str(Vector(rotL)) + ', ' + str(Vector(pointL)) + ')')
69
70 - def translate(self, vectL=[1,1,1]):
71 self.transformList.append('translate '+ str(Vector(vectL)))
72
73 - def rotate(self, vectL=[0,20,0]):
74 self.transformList.append('rotate '+ str(Vector(vectL)))
75
76 - def scale(self, scaleL=[2,2,2]):
77 self.transformList.append('scale '+ str(Vector(scaleL))) 78 79 sfact = 1.0 80 for s in scaleL: 81 sfact *= s 82 for item in self.itemList: 83 item.volume *= sfact
84
85 - def __str__(self):
86 sL = ['#declare %s = \n'%(self.name)] 87 sL.append(' union {') 88 89 for item in self.itemList: 90 s = str(item) 91 sp = s.split('\n') 92 for s in sp: 93 sL.append( ' ' + s + '\n' ) 94 95 sL.append(' }') 96 97 return ' '.join(sL)
98 99
100 -class SurfOfRev(Item):
101 - def __init__(self, texture=None, openSOR=0, 102 radii=[0,1,3,1,0], heights=[0,.5,1.5,2,5] ):
103 # rotated around the y axis. 104 105 Item.__init__(self, texture) 106 107 self.openSOR = openSOR 108 self.pts = zip(radii,heights) 109 while len(self.pts) < 4: 110 self.pts.append( [self.pts[-1][0]+1,self.pts[-1][1]+1] )
111
112 - def __str__(self):
113 114 # eliminate any interior duplicate points 115 goodPts = [ self.pts[0] ] 116 for p in self.pts: 117 if p != goodPts[-1]: 118 goodPts.append(p) 119 120 sL = ['sor { \n'] 121 sL.append(' %i\n'%(len(goodPts)+2,) ) 122 sL.append( ' %s'%str(Vector(goodPts[0])) + '\n' ) # double up on end points 123 for p in goodPts: 124 sL.append( ' %s'%str(Vector(p)) + '\n' ) 125 sL.append( ' %s'%str(Vector(goodPts[-1])) + '\n' ) # double up on end points 126 127 if self.openSOR: 128 sL.append(' open \n') 129 sL.append(' sturm \n') 130 131 sL.append(str(self.texture)+'\n') 132 133 t = self.transformStr() 134 if len( t.strip() )>0: 135 sL.append(' '+t) 136 137 sL.append('}') 138 return ' '.join(sL)
139
140 -class Box(Item):
141 - def __init__(self, texture=None, 142 corner1=[1,1,1], corner2=[-1,-1,-1] ):
143 144 Item.__init__(self, texture) 145 self.corner1 = Vector( corner1 ) 146 self.corner2 = Vector( corner2 ) 147 148 # volume will be changed by any scaling 149 self.volume = abs(corner1[0]-corner2[0]) * abs(corner1[1]-corner2[1]) \ 150 * abs(corner1[2]-corner2[2])
151
152 - def __str__(self):
153 sL = ['box { %s'%(str(self.corner1))] 154 sL.append(' %s\n'% (str(self.corner2)) ) 155 sL.append(str(self.texture)+'\n') 156 157 t = self.transformStr() 158 if len( t.strip() )>0: 159 sL.append(' '+t) 160 161 sL.append('}') 162 return ' '.join(sL)
163
164 -class Sphere(Item):
165 - def __init__(self, texture=None, 166 center=[1,1,1], radius=1.5 ):
167 168 Item.__init__(self, texture) 169 self.center = Vector( center ) 170 self.radius = radius 171 172 # volume will be changed by any scaling 173 self.volume = 4.0 * pi * radius**3 / 3.0
174
175 - def __str__(self):
176 sL = ['sphere { %s'%(str(self.center))] 177 sL.append(' %g\n'% self.radius ) 178 sL.append(str(self.texture)+'\n') 179 180 t = self.transformStr() 181 if len( t.strip() )>0: 182 sL.append(' '+t) 183 184 sL.append('}') 185 return ' '.join(sL)
186
187 -class Torus(Item):
188 '''Created at 0,0,0 by default'''
189 - def __init__(self, texture=None, 190 rmajor=5.0, rminor=1.0 ):
191 192 Item.__init__(self, texture) 193 self.rmajor = rmajor 194 self.rminor = rminor 195 196 # volume will be changed by any scaling 197 self.volume = pi * rminor**2 * 2.0 * pi * rmajor
198
199 - def __str__(self):
200 sL = ['torus { %g %g\n'%(self.rmajor,self.rminor)] 201 sL.append(str(self.texture)+'\n') 202 203 t = self.transformStr() 204 if len( t.strip() )>0: 205 sL.append(' '+t) 206 207 sL.append('}') 208 return ' '.join(sL)
209
210 -class Cylinder(Item):
211 - def __init__(self, texture=None, 212 bottom=[0,0,0], top=[1,1,1], radius=1.5 ):
213 214 Item.__init__(self, texture) 215 self.topV = Vector( top ) 216 self.bottomV = Vector( bottom ) 217 self.radius = radius 218 219 # volume will be changed by any scaling 220 self.h = sqrt( (top[0]-bottom[0])**2 + (top[1]-bottom[1])**2 + (top[2]-bottom[2])**2 ) 221 self.volume = self.h * pi * radius**2
222
223 - def __str__(self):
224 sL = ['cylinder { %s'%(str(self.bottomV))] 225 sL.append(' %s'%(str(self.topV),) ) 226 sL.append(' %g\n'% self.radius ) 227 sL.append(str(self.texture)+'\n') 228 229 t = self.transformStr() 230 if len( t.strip() )>0: 231 sL.append(' '+t) 232 233 sL.append('}') 234 return ' '.join(sL)
235
236 -class HollowCylinder(Item):
237 '''Subtract inner cylinder (slightly longer) from outer cylinder 238 To get a hollow cylinder with desired wall thickness'''
239 - def __init__(self, texture=None, height=1.0, OD=3.0, thickness=0.1 ):
240 # bottom placed at <0,0,0>, height is in y direction <0,height,0> 241 Item.__init__(self, texture) 242 self.height = height 243 self.OD = OD 244 self.thickness = thickness
245 246 247
248 - def __str__(self):
249 sL = ['difference { \n'] 250 bottom = [0,0,0] 251 top = [0,self.height,0] 252 r = self.OD/2.0 253 sL.append( str(Cylinder( texture=self.texture, bottom=bottom, top=top, radius=r ))+'\n' ) 254 255 bottom = [0,-0.1,0] 256 top = [0,self.height+0.1,0] 257 r = self.OD/2.0 - self.thickness 258 259 sL.append( str(Cylinder( texture=self.texture, bottom=bottom, top=top, radius=r ))+'\n' ) 260 261 t = self.transformStr() 262 if len( t.strip() )>0: 263 sL.append(' '+t) 264 265 sL.append('}') 266 return ' '.join(sL)
267 268
269 -class Cone(Item):
270 - def __init__(self, texture=None, 271 bottom=[0,0,0], Rbottom=1.5, top=[1,1,1], Rtop=1.0 ):
272 273 Item.__init__(self, texture) 274 self.topV = Vector( top ) 275 self.bottomV = Vector( bottom ) 276 self.Rbottom = Rbottom 277 self.Rtop = Rtop 278 279 # volume will be changed by any scaling 280 self.h = sqrt( (top[0]-bottom[0])**2 + (top[1]-bottom[1])**2 + (top[2]-bottom[2])**2 ) 281 self.volume = self.h * pi * (Rtop**2 + Rbottom**2 + Rtop*Rbottom) / 3.0
282 283
284 - def __str__(self):
285 sL = ['cone { %s %g '%(str(self.bottomV), self.Rbottom)] 286 sL.append(' %s'%(str(self.topV),) ) 287 sL.append(' %g\n'% self.Rtop ) 288 sL.append(str(self.texture)+'\n') 289 290 t = self.transformStr() 291 if len( t.strip() )>0: 292 sL.append(' '+t) 293 294 sL.append('}') 295 return ' '.join(sL)
296 297
298 -class Plane(Item):
299 - def __init__(self, texture=None, 300 normal=[0,1,0], distToOrigin=0.0 ):
301 302 Item.__init__(self, texture) 303 self.normalV = Vector( normal ) 304 self.distToOrigin = distToOrigin 305 306 self.volume = 0.0
307 308
309 - def __str__(self):
310 sL = ['plane { %s %g \n'%(str(self.normalV), self.distToOrigin)] 311 sL.append(str(self.texture)+'\n') 312 313 t = self.transformStr() 314 if len( t.strip() )>0: 315 sL.append(' '+t) 316 317 sL.append('}') 318 return ' '.join(sL)
319 320
321 -class EllDomeCaveDown(SurfOfRev):
322 ''' a surface of revolution''' 323
324 - def __init__(self, radius=10.0, ellRatio=1.414, texture=None, openSOR=1):
325 326 #Item.__init__(self, texture) 327 self.radius = radius 328 self.ellRatio = ellRatio 329 self.openSOR = openSOR 330 331 N = 21 332 R1 = radius 333 R2 = radius / ellRatio 334 radii = [] 335 heights = [] 336 for i in range(N): 337 ang = i*pi/(N)/2.0 338 radii.append( R1*cos(ang)) 339 heights.append( R2*sin(ang) ) 340 radii.append( 0.0) 341 heights.append( R2 ) 342 343 #self.dome = SurfOfRev( texture=self.texture, radii=radii, heights=heights, openSOR=openSOR ) 344 345 self.h = radius/ellRatio 346 self.w = 2.0*radius 347 self.d = 2.0*radius 348 349 SurfOfRev.__init__(self, texture=texture, openSOR=openSOR, 350 radii=radii, heights=heights )
351 352 #def __str__(self): Uses str definition from SurfOfRev 353
354 -class EllDomeCaveUp(EllDomeCaveDown):
355 ''' a surface of revolution'''
356 - def __init__(self, radius=10.0, ellRatio=1.414, texture=None, openSOR=1):
357 EllDomeCaveDown.__init__(self, radius=radius, ellRatio=ellRatio, 358 texture=texture, openSOR=openSOR) 359 self.rotate( [180.,0.,0.] )
360
361 -class CSE_Tank(Item):
362 ''' made up of a collection of Items''' 363
364 - def __init__(self, radius=10.0, ellRatio=1.414, cylLen=5.0, texture=None):
365 366 Item.__init__(self, texture) 367 self.radius = radius 368 self.ellRatio = ellRatio 369 self.cylLen = cylLen 370 371 N = 21 372 R1 = radius 373 R2 = radius / ellRatio 374 radii = [] 375 heights = [] 376 for i in range(N): 377 ang = i*pi/(N)/2.0 378 radii.append( R1*cos(ang)) 379 heights.append( R2*sin(ang) ) 380 radii.append( 0.0) 381 heights.append( R2 ) 382 383 dome = SurfOfRev( texture=self.texture, radii=radii, heights=heights ) 384 if cylLen>0.0: 385 dome.translate( [0.,cylLen,0.] ) 386 387 dome2 = SurfOfRev( texture=self.texture, radii=radii, heights=heights ) 388 dome2.rotate( [180.,0.,0.] ) 389 390 self.itemsL = [dome, dome2] 391 if cylLen>0.0: 392 cyl = Cylinder( self.texture, [0.,0.,0.], [0.,cylLen,0.], radius ) 393 self.itemsL.append( cyl ) 394 395 self.h = cylLen + 2.0*radius/ellRatio 396 self.w = 2.0*radius 397 self.d = 2.0*radius
398
399 - def __str__(self):
400 sL = ['union { '] 401 for item in self.itemsL: 402 sL.append( str(item) + '\n' ) 403 404 t = self.transformStr() 405 if len( t.strip() )>0: 406 sL.append(' '+t) 407 408 sL.append('}') 409 return ' '.join(sL)
410 411 412 if __name__ == '__main__': 413 414 b = Box(texture=Texture(name="T_Grnt25",ambient=0.5)) 415 print b 416 print 'volume =',b.volume 417 418 s = Sphere(texture=Texture(name="T_Grnt25",ambient=0.5)) 419 print s 420 print 'volume =',s.volume 421 print 422 423 d = DeclaredItem(name='testItem', itemList=[b,s] ) 424 print d 425 426 sor = SurfOfRev() 427 print sor 428 429 c = HollowCylinder(height=1.0, OD=3.0, thickness=0.1 ) 430 print c 431 432 cse = CSE_Tank() 433 print cse 434 435 c = Cone() 436 print c 437 438 plane = Plane() 439 print plane 440 441 torus = Torus() 442 print torus 443