]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryBuilder.cxx
No more misaligned_geometry
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryBuilder.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *      SigmaEffect_thetadegrees                                                                  *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpeateose. It is      *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17 //
18 // ----------------------------
19 // Class AliMUONGeometryBuilder
20 // ----------------------------
21 // Manager class for geometry construction via geometry builders.
22 // Author: Ivana Hrivnacova, IPN Orsay
23
24 #include "AliMUONGeometryBuilder.h"
25 #include "AliMUONVGeometryBuilder.h"    
26 #include "AliMUONGeometry.h"
27 #include "AliMUONGeometryTransformer.h"
28 #include "AliMUONGeometryModule.h"      
29 #include "AliMUONGeometryModuleTransformer.h"   
30 #include "AliMUONGeometryEnvelope.h"    
31 #include "AliMUONGeometryEnvelopeStore.h"
32 #include "AliMUONGeometryDetElement.h"
33 #include "AliMUONGeometryConstituent.h"
34
35 #include "AliMpDEManager.h"
36
37 #include "AliModule.h"
38 #include "AliLog.h"
39 #include "AliRun.h"
40
41 #include <TObjArray.h>
42 #include <TVirtualMC.h>
43 #include <TGeoManager.h>
44
45 // static data members
46  
47 const TString  AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";   
48 const TString  AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";   
49 const TString  AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";    
50 const TString  AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";    
51
52 /// \cond CLASSIMP
53 ClassImp(AliMUONGeometryBuilder)
54 /// \endcond
55
56 // static functions
57
58 //______________________________________________________________________________
59 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
60                                              const TGeoMatrix& m2)
61 {
62 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
63
64   if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
65   
66   if (m1.IsIdentity()) return m2;
67   
68   if (m2.IsIdentity()) return m1;
69   
70   return m1 * m2;
71 }
72
73 //______________________________________________________________________________
74 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
75                                              const TGeoMatrix& m2,
76                                              const TGeoMatrix& m3)
77 {                                            
78 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
79
80   if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())  
81     return TGeoHMatrix();
82   
83   if (m1.IsIdentity()) return Multiply(m2, m3);
84   
85   if (m2.IsIdentity()) return Multiply(m1, m3);
86   
87   if (m3.IsIdentity()) return Multiply(m1, m2);
88   
89   return m1 * m2 * m3;
90 }
91
92 //______________________________________________________________________________
93 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
94                                              const TGeoMatrix& m2,
95                                              const TGeoMatrix& m3,
96                                              const TGeoMatrix& m4)
97 {                                            
98 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
99
100   if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())  
101     return TGeoHMatrix();
102   
103   if (m1.IsIdentity()) return Multiply(m2, m3, m4);
104   
105   if (m2.IsIdentity()) return Multiply(m1, m3, m4);
106   
107   if (m3.IsIdentity()) return Multiply(m1, m2, m4);
108   
109   if (m4.IsIdentity()) return Multiply(m1, m2, m3);
110   
111   return m1 * m2 * m3 * m4;
112 }
113
114 //______________________________________________________________________________
115 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
116   : TObject(),
117     fModule(module),
118     fAlign(false),
119     fTransformFileName(fgkDefaultTransformFileName),
120     fSVMapFileName(fgkDefaultSVMapFileName),
121     fGlobalTransformation(), 
122     fGeometryBuilders(0),
123     fGeometry(0)
124 {
125 /// Standard constructor
126
127   fGeometryBuilders = new TObjArray();
128   fGeometryBuilders->SetOwner(true);
129   
130   fGeometry = new AliMUONGeometry(true);
131
132   // Define the global transformation:
133   // Transformation from the old ALICE coordinate system to a new one:
134   // x->-x, z->-z 
135   TGeoRotation* rotGlobal 
136     = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
137   fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
138 }
139
140 //______________________________________________________________________________
141 AliMUONGeometryBuilder::AliMUONGeometryBuilder() 
142   : TObject(),
143     fModule(0),
144     fAlign(false),
145     fTransformFileName(),
146     fSVMapFileName(),
147     fGlobalTransformation(),
148     fGeometryBuilders(0),
149     fGeometry(0)
150 {
151 /// Default constructor
152
153
154 //______________________________________________________________________________
155 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
156 {
157 /// Destructor
158   
159   delete fGeometryBuilders;
160   delete fGeometry;
161 }
162
163 //
164 // private functions
165 //
166
167 //______________________________________________________________________________
168 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName, 
169                             Int_t copyNo, const TGeoHMatrix& matrix, 
170                             Int_t npar, Double_t* param, const char* only,
171                             Bool_t makeAssembly) const
172 {
173 /// Place the volume specified by name with the given transformation matrix
174
175   if (makeAssembly)
176     gGeoManager->MakeVolumeAssembly(name.Data());
177
178   TGeoHMatrix transform(matrix);
179   // Do not apply global transformation 
180   // if mother volume was already placed in 
181   // the new system of coordinates (that is MUON in negative Z)
182   // (as it is applied on the mother volume)
183   if (mName == TString("DDIP"))
184     transform = fGlobalTransformation.Inverse() * transform;
185      
186   // Decompose transformation
187   const Double_t* xyz = transform.GetTranslation();
188   const Double_t* rm = transform.GetRotationMatrix();
189         
190   //cout << "Got translation: "
191   //     << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
192         
193   //cout << "Got rotation: "
194   //     << rm[0] << " " << rm[1] << " " << rm[2] << endl
195   //     << rm[3] << " " << rm[4] << " " << rm[5] << endl
196   //     << rm[6] << " " << rm[7] << " " << rm[8] << endl;
197
198   // Check for presence of rotation
199   // (will be nice to be available in TGeo)
200   const Double_t kTolerance = 1e-04;
201   Bool_t isRotation = true; 
202   if (TMath::Abs(rm[0] - 1.) < kTolerance &&
203       TMath::Abs(rm[1] - 0.) < kTolerance &&
204       TMath::Abs(rm[2] - 0.) < kTolerance &&
205       TMath::Abs(rm[3] - 0.) < kTolerance &&
206       TMath::Abs(rm[4] - 1.) < kTolerance &&
207       TMath::Abs(rm[5] - 0.) < kTolerance &&
208       TMath::Abs(rm[6] - 0.) < kTolerance &&
209       TMath::Abs(rm[7] - 0.) < kTolerance &&
210       TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false; 
211
212   Int_t krot = 0;
213   if (isRotation) {
214     TGeoRotation rot;
215     rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
216     Double_t theta1, phi1, theta2, phi2, theta3, phi3;
217     rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
218         
219     //cout << "angles: " 
220     //     << theta1 << " " << phi1 << " "
221     //     << theta2 << " " << phi2 << " "
222     //     << theta3 << " " << phi3 << endl;
223         
224     fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
225   }     
226         
227   // Place the volume
228   if (npar == 0)
229     gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
230   else 
231     gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
232                 param, npar);
233
234
235 //______________________________________________________________________________
236 void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
237 {
238 /// Construct geometry using geometry builders.
239 /// Virtual modules/envelopes are placed as TGeoVolume assembly
240
241   if (fAlign) {
242     // Read transformations from ASCII data file  
243     fGeometry->GetTransformer()
244       ->LoadGeometryData(fTransformFileName);
245   }    
246  
247   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
248
249     // Get the builder
250     AliMUONVGeometryBuilder* builder
251       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
252
253     // Create geometry + envelopes
254     //
255     builder->CreateGeometry();
256     if (!fAlign) builder->SetTransformations();
257     
258     // Place module volumes and envelopes
259     //
260     for (Int_t j=0; j<builder->NofGeometries(); j++) {
261
262       AliMUONGeometryModule* geometry = builder->Geometry(j);
263       AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
264       const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
265       TString volName       = transformer->GetVolumeName(); 
266       TString motherVolName = transformer->GetMotherVolumeName(); 
267       
268       // Place the module volume
269       PlaceVolume(volName, motherVolName, 
270                   1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
271   
272       TGeoCombiTrans appliedGlobalTransform;
273       if (builder->ApplyGlobalTransformation())
274         appliedGlobalTransform = fGlobalTransformation;
275
276       // Loop over envelopes
277       const TObjArray* kEnvelopes 
278         = geometry->GetEnvelopeStore()->GetEnvelopes();
279       for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
280
281         // Get envelope
282         AliMUONGeometryEnvelope* env 
283           = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
284           
285         // Check consistency of detElemId and module Id
286         if ( env->GetUniqueID() > 0 && 
287              AliMpDEManager::GetGeomModuleId(env->GetUniqueID()) 
288              != geometry->GetModuleId() ) {
289              
290           AliErrorStream() 
291             << "Detection element " << env->GetUniqueID() 
292             << " is being placed in geometry module " << geometry->GetModuleId()
293             << " but should go in " 
294             << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
295             <<  endl;
296           AliFatal("Inconsistent IDs");
297         }          
298           
299         const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
300         const char* only = "ONLY";
301         if (env->IsMANY()) only = "MANY";
302
303         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
304           // virtual envelope + nof constituents = 0 
305           //         => not allowed;
306           //            empty virtual envelope has no sense 
307           AliFatal("Virtual envelope must have constituents.");
308           return;
309         }
310
311         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
312           // non virtual envelope + nof constituents > 0 
313           //        => not allowed;
314           //           use VMC to place constituents
315           AliFatal("Non virtual envelope cannot have constituents.");
316           return;
317         }
318
319         // Place envelope in geometry module by composed transformation:
320         // [Tglobal] * Tenv
321         TGeoHMatrix total 
322           = Multiply( appliedGlobalTransform, 
323                      (*kEnvTrans) );
324         PlaceVolume(env->GetName(), volName,
325                     env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
326         
327         if ( env->IsVirtual() )  {
328           //  Place constituents in the envelope
329           for  (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
330             AliMUONGeometryConstituent* constituent
331               = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
332  
333             PlaceVolume(constituent->GetName(), env->GetName(),
334                         constituent->GetCopyNo(),
335                         *constituent->GetTransformation() ,
336                         constituent->GetNpar(), constituent->GetParam(), only);
337           }
338         }
339       } // end of loop over envelopes
340     } // end of loop over builder geometries
341   } // end of loop over builders
342 }
343
344 //______________________________________________________________________________
345 void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
346 {
347 /// Construct geometry using geometry builders.
348 /// Virtual modules/envelopes are not placed
349
350   if (fAlign) {
351     // Read transformations from ASCII data file  
352     fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
353   }     
354
355   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
356
357     // Get the builder
358     AliMUONVGeometryBuilder* builder
359       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
360
361     // Create geometry + envelopes
362     //
363     builder->CreateGeometry();
364     if (!fAlign) builder->SetTransformations();
365     
366     // Place module volumes and envelopes
367     //
368     for (Int_t j=0; j<builder->NofGeometries(); j++) {
369
370       AliMUONGeometryModule* geometry = builder->Geometry(j);
371       AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
372       const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
373       TString volName       = transformer->GetVolumeName(); 
374       TString motherVolName = transformer->GetMotherVolumeName(); 
375       
376       // Place the module volume
377       if ( !geometry->IsVirtual() ) {
378           PlaceVolume(volName, motherVolName, 
379                       1, *kModuleTransform, 0, 0, "ONLY");
380       }               
381   
382       TGeoCombiTrans appliedGlobalTransform;
383       if (builder->ApplyGlobalTransformation())
384         appliedGlobalTransform = fGlobalTransformation;
385
386       // Loop over envelopes
387       const TObjArray* kEnvelopes 
388         = geometry->GetEnvelopeStore()->GetEnvelopes();
389       for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
390
391         // Get envelope
392         AliMUONGeometryEnvelope* env 
393           = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
394           
395         // Check consistency of detElemId and module Id
396         if ( env->GetUniqueID() > 0 && 
397              AliMpDEManager::GetGeomModuleId(env->GetUniqueID()) 
398              != geometry->GetModuleId() ) {
399              
400           AliErrorStream() 
401             << "Detection element " << env->GetUniqueID() 
402             << " is being placed in geometry module " << geometry->GetModuleId()
403             << " but should go in " 
404             << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
405             <<  endl;
406           AliFatal("Inconsistent IDs");
407         }          
408           
409         const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
410         const char* only = "ONLY";
411         if (env->IsMANY()) only = "MANY";
412
413         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
414           // virtual envelope + nof constituents = 0 
415           //         => not allowed;
416           //            empty virtual envelope has no sense 
417           AliFatal("Virtual envelope must have constituents.");
418           return;
419         }
420
421         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
422           // non virtual envelope + nof constituents > 0 
423           //        => not allowed;
424           //           use VMC to place constituents
425           AliFatal("Non virtual envelope cannot have constituents.");
426           return;
427         }
428
429         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
430           // non virtual envelope + nof constituents = 0 
431           //        => place envelope by composed transformation:
432           //           Tch * [Tglobal] * Tenv
433
434           // Compound chamber transformation with the envelope one
435           if (geometry->IsVirtual()) {
436              TGeoHMatrix total 
437                = Multiply( (*kModuleTransform), 
438                             appliedGlobalTransform, 
439                            (*kEnvTrans) );
440              PlaceVolume(env->GetName(), motherVolName,
441                          env->GetCopyNo(), total, 0, 0, only);
442           }
443           else {
444              TGeoHMatrix total 
445                = Multiply( appliedGlobalTransform, 
446                            (*kEnvTrans) );
447              PlaceVolume(env->GetName(), volName,
448                          env->GetCopyNo(), total, 0, 0, only);
449           }                      
450         }
451
452         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
453           // virtual envelope + nof constituents > 0 
454           //         => do not place envelope and place constituents
455           //            by composed transformation:
456           //            Tch * [Tglobal] * Tenv * Tconst   
457
458           for  (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
459             AliMUONGeometryConstituent* constituent
460               = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
461  
462             // Compound chamber transformation with the envelope one + the constituent one
463             if (geometry->IsVirtual()) {
464               TGeoHMatrix total 
465                 = Multiply ( (*kModuleTransform),
466                              appliedGlobalTransform, 
467                              (*kEnvTrans), 
468                              (*constituent->GetTransformation()) );
469
470               PlaceVolume(constituent->GetName(), motherVolName,
471                           constituent->GetCopyNo(), total,
472                           constituent->GetNpar(), constituent->GetParam(), only);
473             }
474             else {                        
475               TGeoHMatrix total 
476                 = Multiply ( appliedGlobalTransform, 
477                              (*kEnvTrans),
478                              (*constituent->GetTransformation()) );
479
480               PlaceVolume(constituent->GetName(), volName,
481                           constituent->GetCopyNo(), total,
482                           constituent->GetNpar(), constituent->GetParam(), only);
483             }                     
484           }
485         }
486       } // end of loop over envelopes
487     } // end of loop over builder geometries
488   } // end of loop over builders
489 }
490
491 //_____________________________________________________________________________
492 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
493 {
494 /// Set align option to all geometry modules associated with the builder
495
496   for (Int_t j=0; j<builder->NofGeometries(); j++) {
497
498     AliMUONGeometryModule* geometry = builder->Geometry(j);
499   
500     geometry->SetAlign(fAlign);
501   }       
502 }            
503
504 //
505 // public functions
506 //
507
508 //_____________________________________________________________________________
509 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
510 {
511 /// Add the geometry builder to the list
512
513   fGeometryBuilders->Add(geomBuilder);
514   
515   // Pass geometry modules created in the to the geometry parametrisation
516   for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
517     fGeometry->AddModule(geomBuilder->Geometry(i));
518   }  
519   
520   if (geomBuilder->ApplyGlobalTransformation())
521     geomBuilder->SetReferenceFrame(fGlobalTransformation);
522   
523   SetAlign(geomBuilder);
524 }
525
526 //______________________________________________________________________________
527 void AliMUONGeometryBuilder::CreateGeometry()
528 {
529 /// Construct geometry using geometry builders.
530
531   if ( gMC->IsRootGeometrySupported() ) {
532        
533    CreateGeometryWithTGeo();
534   } 
535   else
536    CreateGeometryWithoutTGeo();
537
538   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
539
540     // Get the builder
541     AliMUONVGeometryBuilder* builder
542       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
543
544     // Create detection elements from built geometry
545     builder->CreateDetElements();
546   }  
547 }
548
549 //_____________________________________________________________________________
550 void AliMUONGeometryBuilder::CreateMaterials()
551 {
552 /// Construct materials specific to modules via builders
553   
554   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
555
556     // Get the builder
557     AliMUONVGeometryBuilder* builder
558       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
559
560     // Create materials with each builder
561     if (builder) builder->CreateMaterials();
562   }
563 }
564
565 //______________________________________________________________________________
566 void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
567 {
568 /// Initialize geometry
569
570   // Load alignement data from geometry if geometry is read from Root file
571   if ( gAlice->IsRootGeometry() ) {
572     fAlign = true;
573     fGeometry->GetTransformer()->LoadGeometryData();
574  }    
575
576   // Read sensitive volume map from a file
577   fGeometry->ReadSVMap(svmapFileName);
578
579   // Set the chamber (sensitive region) GEANT identifier
580   //
581   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
582
583     // Get the builder
584     AliMUONVGeometryBuilder* builder
585       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
586
587     // Set sensitive volumes with each builder
588     builder->SetSensitiveVolumes();
589   }  
590 }
591
592 //______________________________________________________________________________
593 void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName, 
594                                          Bool_t rebuild, Bool_t writeEnvelopes)
595 {
596 /// Write sensitive volume maps into files per builder
597
598   // Rebuild sv maps
599   //
600   if (rebuild) 
601     for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
602
603       AliMUONVGeometryBuilder* builder
604         = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
605
606       builder->RebuildSVMaps(writeEnvelopes);
607     }  
608     
609   // Write maps in file
610   fGeometry->WriteSVMap(fileName);
611 }
612
613 //_____________________________________________________________________________
614 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
615
616 /// Set the option for alignement
617
618   fAlign = align; 
619
620   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
621
622     AliMUONVGeometryBuilder* builder
623       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
624     
625     SetAlign(builder); 
626   }   
627 }
628
629 //_____________________________________________________________________________
630 void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
631
632 /// Set the option for alignement and the transformations file name
633
634   fTransformFileName = fileName;
635   fAlign = align; 
636
637   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
638
639     AliMUONVGeometryBuilder* builder
640       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
641     
642     SetAlign(builder); 
643   }   
644 }