Latest version
[u/mrichter/AliRoot.git] / GEODB / AliGNode.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
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 purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 */
19
20 /**********************************************/
21 /*                                            */
22 /* FILE: AliGNode.cxx                         */
23 /* PURPOSE: Tree elemnt of the geometry       */
24 /* LANGUAGE: C++                              */
25 /* COMPILER: CC for HP-UX 9.x and 10.         */
26 /* AUTHOR: Joana && David                     */
27 /* DATE: May 28, 1999                         */
28 /* ADDRESS: jesanto@cern.ch, dcollado@cern.ch */
29 /*                                            */
30 /**********************************************/
31
32 #include <TCanvas.h>
33 #include <TView.h>
34 #include <TPadView3D.h>
35 #include <iostream.h>
36 #include <TFile.h>
37 #include <TROOT.h>
38 #include "AliGeometry.h"
39 #include "AliGBox.h"
40 #include "AliGCone.h"
41 #include "AliGPCone.h"
42 #include "AliGSphere.h"
43 #include "AliGNode.h"
44
45 const Int_t kSonsInvisible = BIT(17);
46 Text_t* ROOT_FILE = "AliGeoDB.root";
47
48 ClassImp(AliGNode)
49
50 //----------------------------------------------------------------------
51
52 AliGNode::AliGNode( AliGNode* node ) 
53 {
54
55     if( node ) {
56         /* Copy Constructor */
57         fConfig   = new AliGConfig( node->fConfig );
58         fId       = node->fId;
59         fMaterial = new AliGMaterial( node->fMaterial );
60         fName     = node->fName;
61         fNcopy    = new TArrayI( *(node->fNcopy) );
62         fNname    = node->fNname;
63         fNnode    = new TArrayI( *(node->fNnode) );
64         fNode     = new TObjArray( *(node->fNode) );
65         fNsons    = node->fNsons;
66         fNtrans   = new TArrayI( *(node->fNtrans) );
67         fParent   = node->fParent;
68         fVis      = node->fVis;
69         fTitle    = node->fTitle;
70         fTrans    = new TObjArray(*(node->fTrans));
71         //        fParent   = new AliGNode(node->fParent);
72
73         if (node->fShape) {
74             if( !strcmp(node->fShape->ClassName(), "AliGBox") ) {
75                 fShape = new AliGBox( (AliGBox*) node->fShape );
76                 //fShape = new AliGBox(*(AliGBox*)node->fShape);
77             }
78             else {
79                 if( !strcmp(node->fShape->ClassName(), "AliGSphere") )
80                     fShape = new AliGSphere( (AliGSphere*) node->fShape );
81                 else {
82                     if( !strcmp(node->fShape->ClassName(), "AliGTube") )
83                         fShape = new AliGTube( (AliGTube*) node->fShape );
84                     else {
85                         if( !strcmp(node->fShape->ClassName(), "AliGCone") )
86                             fShape = new AliGCone( (AliGCone*) node->fShape );
87                         else {
88                             if( !strcmp(node->fShape->ClassName(), "AliGPCone") )
89                                 fShape = new AliGPCone( (AliGPCone*) node->fShape );
90                             else {
91                                 if( !strcmp(node->fShape->ClassName(), "AliGTRD1") ) 
92                                     fShape = new AliGTRD1( (AliGTRD1*) node->fShape );
93                             }
94                         }
95                     }
96                 }
97             }
98         }
99         else
100             fShape = NULL;
101
102         /*cout << endl << " Comparacion." << endl;
103         cout << " El que paso por parametro:" << endl;
104         node->Dump();
105         cout << " El resultado de la copia:" << endl;
106         this->Dump();*/
107
108     }
109     else {
110         /* Default Constructor */
111         fConfig   = NULL;
112         fId       = 0;
113         fMaterial = NULL;
114         fName     = "";
115         fNcopy    = NULL;
116         fNname    = "";
117         fNnode    = NULL;
118         fNode     = new TObjArray();
119         fNsons    = 0;
120         fNtrans   = NULL;
121         fParent   = NULL;
122         fShape    = NULL;
123         fTitle    = "";
124         fTrans    = new TObjArray();
125         fVis      = 0;
126     }
127 }
128
129 //----------------------------------------------------------------------
130
131 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGBox* box, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
132 {
133     /* AliGNode Constructor for AliGBox shape */
134
135     if( box )
136         fShape = new AliGBox(box); // Shape inside node
137     else
138         fShape = NULL;
139
140     EndConstructor( name, id, title, material, matrixname, config );
141 }
142
143 //----------------------------------------------------------------------
144
145 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGSphere* sphere, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
146 {
147     /* AliGNode Constructor for AliGSphere shape */
148
149     if( sphere )
150         fShape = new AliGSphere(sphere); // Shape inside node
151     else
152         fShape = NULL;
153
154     EndConstructor( name, id, title, material, matrixname, config );
155 }
156
157 //----------------------------------------------------------------------
158
159 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGTube* tube, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
160 {
161     /* AliGNode Constructor for AliGTube shape */
162
163     if( tube )
164         fShape = new AliGTube(tube); // Shape inside node
165     else
166         fShape = NULL;
167
168     EndConstructor( name, id, title, material, matrixname, config );
169 }
170
171 //----------------------------------------------------------------------
172
173 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGCone* cone, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
174 {
175     /* AliGNode Constructor for AliGCone shape */
176
177     if( cone )
178         fShape = new AliGCone(cone); // Shape inside node
179     else
180         fShape = NULL;
181
182     EndConstructor( name, id, title, material, matrixname, config );
183 }
184
185 //----------------------------------------------------------------------
186
187
188 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGPCone* pcone, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
189 {
190     /* AliGNode Constructor for AliGPCone shape */
191
192     if( pcone )
193         fShape = new AliGPCone(pcone); // Shape inside node
194     else
195         fShape = NULL;
196
197     EndConstructor( name, id, title, material, matrixname, config );
198 }
199
200 //----------------------------------------------------------------------
201
202
203 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGTRD1* trd1, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
204 {
205     /* AliGNode Constructor for AliGTRD1 shape */
206
207     if( trd1 )
208         fShape = new AliGTRD1(trd1); // Shape inside node
209     else
210         fShape = NULL;
211
212     EndConstructor( name, id, title, material, matrixname, config );
213 }
214
215 //----------------------------------------------------------------------
216
217 void AliGNode::EndConstructor( Text_t* name, Int_t id, Text_t* title, AliGMaterial *material, const Text_t *matrixname, AliGConfig* config )
218 {
219     /* Finish the construction of AliGNodes */
220     
221     fConfig   = new AliGConfig(config);
222     fId       = id;                         // Node id number
223     fMaterial = new AliGMaterial(material); // Material inside shape
224
225     char*  TmpName  = new char[strlen(name)+int(TMath::Log10((double) id)+3)];
226     sprintf(TmpName,"%s_%d",name,id);
227     fName     = TmpName;             // Complete node name
228     delete [] TmpName;
229
230     fNcopy    = new TArrayI(50);            // Array of integers containing the copy number (by family name)
231     fNname    = name;                       // Node family name
232     fNnode    = new TArrayI(50);            // Array of integers containing every node son index
233     fNode     = new TObjArray(100,0);       // Array containing every (different)node son   
234     fNsons    = 0;
235     fNtrans   = new TArrayI(50);            // Array of integers containing every transformation index
236     fParent   = NULL;
237     fTitle    = title;
238     fTrans    = new TObjArray(100,0);       // Array containing every (different)transformation used
239     fVis      = 1;
240
241 }
242
243 //-----------------------------------------------------------------------
244
245 AliGNode::AliGNode( Text_t* name, Int_t id, Text_t* title, AliGShape* shape, AliGMaterial* material, const Text_t* matrixname, AliGConfig* config ) 
246 {
247     /* AliGNode Constructor for an AliGShape */
248
249     fShape = NULL;
250
251     EndConstructor( name, id, title, material, matrixname, config );
252 }
253
254
255 //----------------------------------------------------------------------
256
257 AliGNode::~AliGNode()
258 {
259     /* Destructor */
260
261     if(fConfig)   delete fConfig;
262     if(fMaterial) delete fMaterial;
263     if(fNcopy)    delete fNcopy;
264     if(fNnode)    delete fNnode;
265     if(fNode)     delete fNode;
266     if(fNtrans)   delete fNtrans;
267     if(fShape)    delete fShape;
268     if(fTrans)    delete fTrans;
269 }
270
271 //----------------------------------------------------------------------
272
273 AliGNode* AliGNode::operator=( const AliGNode* node )
274 {
275     if( this == node ) return this; // special case.
276
277     fConfig   = node->fConfig;
278     fId       = node->fId;
279     fMaterial = node->fMaterial;
280     fName     = node->fName;
281     fNcopy    = node->fNcopy;
282     fNname    = node->fNname;
283     fNnode    = node->fNnode;
284
285     if( fNode ) fNode->Delete();
286
287     if( node->fNode ) {
288       //for( int i=0; i<node->fNode->GetSize(); i++ )
289         for( int i=0; i<node->fNode->GetSize(); i++ )
290             fNode->AddLast(node->fNode->At(i));
291     }
292
293     fNsons    = node->fNsons;
294     fNtrans   = node->fNtrans;
295     fParent   = node->fParent;
296     fShape    = node->fShape;
297     fTitle    = node->fTitle;
298
299     if( fTrans ) fTrans->Delete();
300     if( node->fTrans ) {
301         for( int i=0; i<node->fTrans->GetSize(); i++ )
302             fTrans->AddLast(node->fTrans->At(i));
303     }
304     //fTrans    = node->fTrans;
305
306     return this;
307 }
308
309 //----------------------------------------------------------------------
310
311 void AliGNode::Add(AliGNode* son, AliGTransform* tran)
312 {
313     
314     Int_t index = fNode->IndexOf((TObject*)son);
315     
316     if( index == -1 ) {
317         fNode->Add(son);  // fNode is TObjArray
318         index = fNode->IndexOf((TObject*)son);
319         son->fParent = this;
320     }
321
322     Int_t tranumber = fTrans->IndexOf((TObject*)tran); 
323     if( tranumber == -1 ) {
324         fTrans->Add( tran );
325         tranumber = fTrans->IndexOf((TObject*)tran);
326     }
327
328     Int_t Nsons = this->GetfNsons();
329     Int_t copy = 1;
330    
331     for( Int_t i = 0; i<Nsons; i++ ) {
332         if( index == fNnode->At(i) ) {
333             if( fNtrans->At(i) == tranumber ) {
334               cout << "Error: Node already exists!";
335                 return;
336             }
337         }
338         
339         
340         if( ((AliGNode*)fNode->At(fNnode->At(i)))->fNname == son->fNname ) 
341             copy++;
342             
343     }
344
345     if( fNnode->GetSize() == Nsons ) {
346     
347         IncreaseSize( Nsons+100, *fNnode  );
348         IncreaseSize( Nsons+100, *fNtrans );
349         IncreaseSize( Nsons+100, *fNcopy  );
350         
351     }
352     fNnode->AddAt( index, Nsons ); // Add value of index at position Nsons
353     
354     fNtrans->AddAt( tranumber, Nsons ); 
355     fNcopy->AddAt( copy, Nsons );
356     fNsons++; // Because we have added a new node
357    
358 }
359
360 //----------------------------------------------------------------------   
361
362 void AliGNode::IncreaseSize(Int_t total,TArrayI &array)
363 {
364     TArrayI *newarray = new TArrayI(array);
365     array.Set(total);    
366
367     for( int i=0; i<newarray->GetSize(); i++ )
368         array[i] = (*newarray)[i];
369         
370     delete newarray;
371 }
372
373 //----------------------------------------------------------------------
374
375 Text_t* AliGNode::GetPath()
376 {
377     const int kMAXDEPTH = 128;
378     const AliGNode* d[kMAXDEPTH];
379     AliGNode* node = this;
380     int depth = 0, len = 0;
381
382     d[depth++] = node;
383     len = strlen(node->GetName()) + 1;
384
385     while (node->fParent && depth < kMAXDEPTH) {
386         node = node->fParent;     
387         d[depth++] = node;
388         len += strlen (node->GetName()) + 1;
389     }
390
391     char* path = new char[len + 2];
392
393     for (int i = depth-1; i>=0; i--) {
394         if (i == depth-1) {   // file or TROOT name 
395             strcpy(path, d[i]->GetName());
396             if (i == 0) strcat(path, "/");
397         } 
398         else {
399             strcat(path, "/");
400             strcat(path, d[i]->GetName());
401         }
402     }
403  
404     return path;  
405
406
407
408 //----------------------------------------------------------------------
409
410 void AliGNode::Save( TFile* file )
411 {
412     if( fParent ) { // it's not the root node
413         // So I must check if the father node is in disk
414
415         if( file->cd(fParent->GetPath()) ) {
416
417             if( !gDirectory->Get(GetName()) )
418                 file->mkdir( GetName() );
419
420             file->cd( GetPath() );
421
422             if( !gDirectory->Get( fShape->GetName() ) )
423                 if ( fShape ) {
424 /*                    const Text_t* shapetype = fShape->ClassName();
425                     if( !strcmp(shapetype,"AliGBox") ) {
426                         fShape->Write();
427                     }
428                     else {
429                         if (!strcmp(shapetype,"AliGSphere")) {
430                             fShape->Write();
431                         }
432                         else {
433                             if (!strcmp(shapetype,"AliGTube")) {
434                                 fShape->Write();
435                             }
436                             else {
437                                 if (!strcmp(shapetype,"AliGCone")) {
438                                     fShape->Write();
439                                 }
440                                 else {
441                                     if (!strcmp(shapetype,"AliGPCone")) {
442                                         cout << " Saving an AliGPCone:" << endl;
443                                         fShape->Dump();
444                                         cout << endl;
445                                         fShape->Write();
446                                     }
447                                     else {
448                                         if (!strcmp(shapetype,"AliGTRD1")) {
449                                             fShape->Write();
450                                         }
451                                     }
452                                 }
453                             }
454                         }
455                     }*/
456                     fShape->Write();
457                 }
458
459
460             if( !gDirectory->Get( fMaterial->GetName() ) )
461                 if ( fMaterial )
462                     fMaterial->Write();
463
464             if ( fConfig ) {
465                 /*cout << " Con capacidad: " << fConfig->GetFormula().Capacity() << " voy a grabar esta configuracion: " << fConfig->GetFormula().Data() << endl;*/
466                 fConfig->Write();
467             }
468
469             if ( fTrans )
470                 fTrans->Write();
471         }
472         else
473             cout << " ERROR : Father exists but I can't find it. See AliGNode::Save, please..." << endl;
474     }
475     else { // if it's the root node
476         file->mkdir( GetName() );
477         file->cd( GetPath() );
478
479         if ( fShape )
480             fShape->Write();
481
482         if ( fMaterial )
483             fMaterial->Write();
484
485         if ( fConfig ) {
486             /*cout << " Con capacidad: " << fConfig->GetFormula().Capacity() << " voy a grabar esta configuracion: " << fConfig->GetFormula().Data() << endl;*/
487             fConfig->Write();
488         }
489
490         if ( fTrans )
491             fTrans->Write();
492     }
493
494     fflush(stdout);
495     file->Write();
496 }
497
498 //----------------------------------------------------------------------
499
500 void AliGNode::SaveAll( TFile* file )
501 {
502 /*    if( fParent )
503         file->cd( fParent->GetPath() );
504     else
505         file->cd();
506
507     Save( file );
508
509     for( int i=0; i<fNsons; i++ ) {
510         cout << " Saving node: " << GetPath() << " with copy number " << << endl;
511         GetNodeFromfNnode(i)->SaveAll( file );
512     }
513 */
514
515     if( !gDirectory->Get(GetName()) ) {
516         Save( file );
517
518         for( int i=0; i<fNsons; i++ )
519             GetNodeFromfNnode(i)->SaveAll( file );
520     }
521
522 /*    if (!file->cd(GetPath()))  {
523         Save( file );
524
525         for( int i=0; i<fNsons; i++ )
526             GetNodeFromfNnode(i)->SaveAll( file );
527     }
528 */
529 }
530
531 //----------------------------------------------------------------------
532
533 void AliGNode::AddConfig( Text_t* name, Text_t* title, Text_t* detail, Int_t beg, Int_t end )
534 {
535     Int_t Nsons = GetfNsons();
536
537     TStringLong formula = "";
538
539     for( int i=0; i<Nsons; i++ ) {
540         Int_t index = fNnode->At(i);  // Gets every node son's index
541         const Text_t* NodeName = ((AliGNode*)fNode->At(index))->GetName();
542         Int_t tranumber = fNtrans->At(i); // And the correspondent transform
543         const Text_t* TransfName = ((AliGTransform*)fTrans->At(tranumber))->GetName();
544
545         formula.Append(NodeName);
546         formula.Append(":");
547         formula.Append(TransfName);
548
549         if( i != fNsons-1 )
550             formula.Append("+");
551     }
552
553     //cout << " Acabo de crear la formula: " << formula << endl << endl;
554
555     const Text_t* shapetype    = fShape->ClassName();
556     const Text_t* shapename    = fShape->GetName();
557     const Text_t* materialname = fMaterial->GetName();
558
559     AliGConfig* tmp = new AliGConfig( name, title, formula, detail, shapetype, shapename, materialname, beg, end );
560
561     //if(fConfig) delete fConfig;
562
563     fConfig = tmp;
564 }
565
566 //----------------------------------------------------------------------
567
568 /*void AliGNode::AddConfig( Text_t* name, Text_t* title, Text_t* detail, Int_t beg, Int_t end )
569 {
570     // Creates the configuration of a node using the information passed as arguments
571     // and building the formula of the level below by building the list of its sons
572     // recursively.
573
574     Int_t Nsons = GetfNsons();
575
576     char* formula = NULL;
577
578     cout << " Nsons = " << Nsons << endl;
579
580     for( int i=0; i<Nsons; i++ ) {
581         Int_t index = fNnode->At(i);  // Gets every node son's index
582         const Text_t* NodeName = ((AliGNode*)fNode->At(index))->GetName();
583         Int_t tranumber = fNtrans->At(i); // And the correspondent transform
584         const Text_t* TransfName = ((AliGTransform*)fTrans->At(tranumber))->GetName();
585
586         int lenF, lenN, lenT;
587         lenF = lenN = lenT = 0;
588
589         cout << " i = " << i << " and fNsons = " << fNsons << endl;
590
591         if ( formula ) {
592             lenF = strlen(formula);
593             cout << " formula = #" << formula << "#" << endl;
594         }
595         
596         if ( NodeName ) {
597             lenN = strlen(NodeName);
598             cout << " NodeName = #" << NodeName << "#" << endl;
599         }
600         
601         if ( TransfName ) {
602             lenT = strlen(TransfName);
603             cout << " TransfName = #" << TransfName << "#" << endl;
604         }
605         
606         cout << " lenF: " << lenF << " - lenN: " << lenN << " - lenT: " << lenT << endl;
607
608         char* formula2;
609
610         if( i != fNsons-1 ) {
611             cout << " Arriba" << endl;
612             formula2 = new char[lenF+lenN+lenT+2];
613         }
614         else {
615             cout << " Embaixo" << endl;
616             formula2 = new char[lenF+lenN+lenT+1];
617         }
618         
619         formula2[0] = '\x0';
620
621         cout << "@@@ :) @@@" << endl;
622
623         if ( formula ) {
624             strcpy( formula2, formula );
625             cout << "1 formula2 = #" << formula2 << "#" << endl;
626         }
627
628         if( NodeName ) {
629             strcat( formula2, NodeName );
630             cout << "2 formula2 = #" << formula2 << "#" << endl;
631         }
632       
633         strcat( formula2, ":" );
634
635         if( TransfName ) {
636             strcat( formula2, TransfName );
637             cout << "3 formula2 = #" << formula2 << "#" << endl;
638         }
639
640         if( i != fNsons-1 ) {
641             strcat( formula2, "+" );
642             cout << "4 formula2 = #" << formula2 << "#" << endl;
643         }
644
645         //strcat( formula2, "\x0" );
646         //cout << "5 formula2 = #" << formula2 << "#" << endl;        
647
648         cout << " Y formula2 tiene un tamanyo de: " << strlen(formula2) << " caracteres." << endl;
649
650         //if( formula )  delete [] formula;
651         formula = new char[strlen(formula2)];
652         strcpy( formula, formula2 );
653         if( formula2 ) delete [] formula2;
654     }
655
656     const Text_t* shapetype    = fShape->ClassName();
657     const Text_t* shapename    = fShape->GetName();
658     const Text_t* materialname = fMaterial->GetName();
659
660     AliGConfig* tmp = new AliGConfig( name, title, formula, detail, shapetype, shapename, materialname, beg, end );
661
662     if(fConfig) delete fConfig;
663
664     fConfig = tmp;
665 }
666 */
667
668 //-------------------------------------------------------------------------
669
670 void AliGNode::DrawShape(Option_t *option)
671 {
672     Draw(option);
673     gPad->Update();
674 }
675
676 //----------------------------------------------------------------------
677
678 void AliGNode::Draw(Option_t* option)
679 {
680
681    TString opt = option;
682    opt.ToLower();
683 //*-*- Clear pad if option "same" not given
684    if (!gPad) {
685       if (!gROOT->GetMakeDefCanvas()) return;
686       (gROOT->GetMakeDefCanvas())();
687    }
688    if (!opt.Contains("same")) gPad->Clear();
689
690 //*-*- Draw Referenced node
691    //gGeometry->SetGeomLevel();
692    //gGeometry->UpdateTempMatrix();
693
694    AppendPad(option);
695
696 //*-*- Create a 3-D View
697    TView *view = gPad->GetView();
698    if (!view) {
699       view = new TView(1);
700       view->SetAutoRange(kTRUE);
701       Paint(option);
702       view->SetAutoRange(kFALSE);
703    }
704 }
705
706 //------------------------------------------------------------------
707
708 void AliGNode::Paint(Option_t *option)
709
710   //     Print();
711      TPadView3D *view3D=gPad->GetView3D();
712
713    //Int_t level = gGeometry->GeomLevel();
714 // restrict the levels for "range" option
715    //if (level > 3 && strcmp(option,"range") == 0) return;
716 //*-*- Update translation vector and rotation matrix for new level
717    //if (level) {
718    //   gGeometry->UpdateTempMatrix(fX,fY,fZ,fMatrix->GetMatrix(),fMatrix->IsReflection());
719    //   if (view3D)
720    //       view3D->UpdateNodeMatrix(this,option);
721   // }
722   
723 //*-*- Paint Referenced shape
724 //   Int_t vis = fShape->GetVisibility();
725 //   if ( vis == -1) return;
726 //   if (vis == -3) {
727 //     if (nsons == 0) vis = 1;
728 //     else            vis = 0;
729 //   }
730
731   // TAttLine::Modify();
732   // TAttFill::Modify();
733    //if (fVisibility && fShape->GetVisibility()) {
734       gNode = this;
735       //fShape->SetLineColor(GetLineColor());
736       //fShape->SetLineStyle(GetLineStyle());
737       //fShape->SetLineWidth(GetLineWidth());
738       //fShape->SetFillColor(GetFillColor());
739       //fShape->SetFillStyle(GetFillStyle());
740       
741    Int_t nsons = 0;
742    if (fNnode) nsons = GetfNsons();
743       if (view3D)
744          view3D->SetAttNode((TNode*)this,option);
745       
746      
747     if(fVis) {
748         if( fShape )
749             fShape->Paint(option);
750         else
751             cout << " Intente dibujar donde no habia shape!!! " << endl;
752    }
753    //}
754    if ( TestBit(kSonsInvisible) ) return;
755
756 //*-*- Paint all sons
757    if(!nsons) return;
758     
759    //gGeometry->PushLevel();
760    for( int i=0; i<nsons; i++ ) {
761       
762         gAliGeometry->PushMatrix(gMatrix);
763
764         AliGNode* node = (AliGNode*) fNode->At(fNnode->At(i));
765         
766         AliGTransform* trans = (AliGTransform*) fTrans->At(fNtrans->At(i));
767         gAliGeometry->UpdateMatrix(trans);
768         node->Paint(option);
769         gAliGeometry->PopMatrix();
770         
771     }
772    //gGeometry->PopLevel();
773    
774 }
775    
776    
777 //--------------------------------------------------------------------
778
779 Int_t AliGNode::DistancetoPrimitive(Int_t px, Int_t py)
780 {
781     TView *view = gPad->GetView();
782     gPad->SetSelected(view);
783     return 0;
784 }
785
786 //--------------------------------------------------------------------
787