638b184317878f7ba6035bc829b2d0757b8710d8
[u/mrichter/AliRoot.git] / EVE / Reve / GeoNode.cxx
1 // $Header$
2
3 #include "GeoNode.h"
4 #include <Reve/ReveManager.h>
5 #include <Reve/NLTPolygonSet.h>
6
7 #include "TGeoShapeExtract.h"
8
9 #include <TPad.h>
10 #include <TBuffer3D.h>
11 #include <TVirtualViewer3D.h>
12 #include <TColor.h>
13 #include <TFile.h>
14
15 #include <TGeoShape.h>
16 #include <TGeoVolume.h>
17 #include <TGeoNode.h>
18 #include <TGeoShapeAssembly.h>
19 #include <TGeoManager.h>
20 #include <TVirtualGeoPainter.h>
21
22 using namespace Reve;
23
24
25 //______________________________________________________________________
26 // GeoNodeRnrEl
27 //
28
29 ClassImp(GeoNodeRnrEl)
30
31 GeoNodeRnrEl::GeoNodeRnrEl(TGeoNode* node) :
32   RenderElement(),
33   TObject(),
34   fNode(node)
35 {
36   // Hack!! Should use cint to retrieve TAttLine::fLineColor offset.
37   char* l = (char*) dynamic_cast<TAttLine*>(node->GetVolume());
38   SetMainColorPtr((Color_t*)(l + sizeof(void*)));
39
40   fRnrSelf      = fNode->TGeoAtt::IsVisible();
41 }
42
43 const Text_t* GeoNodeRnrEl::GetName()  const { return fNode->GetName(); }
44 const Text_t* GeoNodeRnrEl::GetTitle() const { return fNode->GetTitle(); }
45
46 /**************************************************************************/
47
48 Int_t GeoNodeRnrEl::ExpandIntoListTree(TGListTree* ltree,
49                                        TGListTreeItem* parent)
50 {
51   // Checks if child-nodes have been imported ... imports them if not.
52   // Then calls RenderElement::ExpandIntoListTree.
53
54   if(fChildren.empty() && fNode->GetVolume()->GetNdaughters() > 0) {
55     TIter next(fNode->GetVolume()->GetNodes());
56     TGeoNode* dnode;
57     while((dnode = (TGeoNode*) next()) != 0) {
58       GeoNodeRnrEl* node_re = new GeoNodeRnrEl(dnode);
59       AddElement(node_re);
60     }
61   }
62   return RenderElement::ExpandIntoListTree(ltree, parent);
63 }
64
65 /**************************************************************************/
66
67 void GeoNodeRnrEl::SetRnrSelf(Bool_t rnr)
68 {
69   RenderElement::SetRnrSelf(rnr);
70   fNode->SetVisibility(rnr);
71 }
72
73 void GeoNodeRnrEl::SetRnrChildren(Bool_t rnr)
74 {
75   RenderElement::SetRnrChildren(rnr);
76   fNode->VisibleDaughters(rnr);
77 }
78
79 void GeoNodeRnrEl::SetRnrState(Bool_t rnr)
80 {
81   RenderElement::SetRnrState(rnr);
82   fNode->SetVisibility(rnr);
83   fNode->VisibleDaughters(rnr);
84 }
85
86 /**************************************************************************/
87
88 void GeoNodeRnrEl::SetMainColor(Color_t color)
89 {
90   fNode->GetVolume()->SetLineColor(color);
91   UpdateItems();
92 }
93
94 void GeoNodeRnrEl::SetMainColor(Pixel_t pixel)
95 {
96   // This one needed for proper calling via CINT (signals).
97
98   SetMainColor(Color_t(TColor::GetColor(pixel)));
99 }
100
101 /**************************************************************************/
102
103 void GeoNodeRnrEl::UpdateNode(TGeoNode* node)
104 {
105   // Updates all reve-browsers having the node in their contents.
106   // All 3D-pads updated if any change found.
107   //
108   // Should (could?) be optimized with some assumptions about
109   // volume/node structure (search for parent, know the same node can not
110   // reoccur on lower level once found).
111
112   static const Exc_t eH("GeoNodeRnrEl::UpdateNode ");
113
114   // printf("%s node %s %p\n", eH.Data(), node->GetName(), node);
115
116   if(fNode == node)
117     UpdateItems();
118
119   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
120     ((GeoNodeRnrEl*)(*i))->UpdateNode(node);
121   }
122
123 }
124
125 void GeoNodeRnrEl::UpdateVolume(TGeoVolume* volume)
126 {
127   // Updates all reve-browsers having the volume in their contents.
128   // All 3D-pads updated if any change found.
129   //
130   // Should (could?) be optimized with some assumptions about
131   // volume/node structure (search for parent, know the same node can not
132   // reoccur on lower level once found).
133
134   static const Exc_t eH("GeoNodeRnrEl::UpdateVolume ");
135
136   // printf("%s volume %s %p\n", eH.Data(), volume->GetName(), volume);
137
138   if(fNode->GetVolume() == volume)
139     UpdateItems();
140
141   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
142     ((GeoNodeRnrEl*)(*i))->UpdateVolume(volume);
143   }
144 }
145
146 /**************************************************************************/
147
148 void GeoNodeRnrEl::Draw(Option_t* option)
149 {
150   TString opt("SAME");
151   opt += option;
152   fNode->GetVolume()->Draw(opt);
153 }
154
155 /**************************************************************************/
156
157 void GeoNodeRnrEl::Save(const char* file, const char* name)
158 {
159   TGeoShapeExtract* gse = DumpShapeTree(this, 0, 0);
160   
161   TFile f(file, "RECREATE");
162   gse->Write(name);
163   f.Close();
164 }
165
166 /**************************************************************************/
167
168 TGeoShapeExtract* GeoNodeRnrEl::DumpShapeTree(GeoNodeRnrEl* geon, TGeoShapeExtract* parent, Int_t level)
169 {
170   printf("dump_shape_tree %s \n", geon->GetName());
171   TGeoNode*   tnode   = 0;
172   TGeoVolume* tvolume = 0;
173   TGeoShape*  tshape  = 0;
174
175   tnode = geon->GetNode();
176   if(tnode == 0) {
177     printf("Null node for %s; assuming it's a holder and descending.\n", geon->GetName());
178     goto do_dump;
179   }
180
181   tvolume = tnode->GetVolume();
182   if(tvolume == 0) {
183     printf("Null volume for %s; skipping.\n", geon->GetName());
184     return 0;
185   }
186
187   tshape  = tvolume->GetShape();
188
189 do_dump:
190   // transformation
191   ZTrans trans;
192   if (parent) if (parent) trans.SetFromArray(parent->GetTrans());
193   TGeoMatrix* gm =  tnode->GetMatrix();
194   const Double_t* rm = gm->GetRotationMatrix();
195   const Double_t* tv = gm->GetTranslation();
196   ZTrans t;
197   t(1,1) = rm[0]; t(1,2) = rm[1]; t(1,3) = rm[2];
198   t(2,1) = rm[3]; t(2,2) = rm[4]; t(2,3) = rm[5];
199   t(3,1) = rm[6]; t(3,2) = rm[7]; t(3,3) = rm[8];
200   t(1,4) = tv[0]; t(2,4) = tv[1]; t(3,4) = tv[2];
201   trans *= t;
202
203   TGeoShapeExtract* gse = new TGeoShapeExtract(geon->GetName(), geon->GetTitle());
204   gse->SetTrans(trans.Array());
205   Int_t ci = 0;
206   if(tvolume) ci = tvolume->GetLineColor();
207   TColor* c = gROOT->GetColor(ci);
208   Float_t rgba[4] = {1, 0, 0, 1};
209   if (c) {
210     rgba[0] = c->GetRed();
211     rgba[1] = c->GetGreen();
212     rgba[2] = c->GetBlue();
213   } 
214   gse->SetRGBA(rgba);
215   Bool_t rnr = geon->GetRnrSelf();
216   if(level > gGeoManager->GetVisLevel())
217     rnr = kFALSE;
218   gse->SetRnrSelf(rnr);
219   gse->SetRnrElements(geon->GetRnrChildren());
220
221   if(dynamic_cast<TGeoShapeAssembly*>(tshape)){
222     //    printf("<TGeoShapeAssembly \n");
223     tshape = 0;
224   }
225   gse->SetShape(tshape);
226   level ++;
227   if ( geon->GetNChildren())
228   {
229     TList* ele = new TList();
230     gse->SetElements(ele);
231     gse->GetElements()->SetOwner(true);
232
233     RenderElement::List_i i = geon->BeginChildren();
234     while (i != geon->EndChildren()) {
235       GeoNodeRnrEl* l = dynamic_cast<GeoNodeRnrEl*>(*i);
236       DumpShapeTree(l, gse, level+1);
237       i++;
238     }
239   }
240
241   if(parent)
242     parent->GetElements()->Add(gse);
243    
244   return gse;
245 }
246 /**************************************************************************/
247 //______________________________________________________________________
248 // GeoTopNodeRnrEl
249 //
250 // A wrapper over a TGeoNode, possibly displaced with a global
251 // trasformation fGlobalTrans (the matrix is owned by this class).
252 /**************************************************************************/
253
254 ClassImp(GeoTopNodeRnrEl)
255
256 GeoTopNodeRnrEl::GeoTopNodeRnrEl(TGeoManager* manager, TGeoNode* node,
257                                  Int_t visopt, Int_t vislvl) :
258   GeoNodeRnrEl (node),
259   fManager     (manager),
260   fGlobalTrans (),
261   fVisOption   (visopt),
262   fVisLevel    (vislvl)
263 {
264   fRnrSelf = true;
265 }
266
267 GeoTopNodeRnrEl::~GeoTopNodeRnrEl()
268 {}
269
270 /**************************************************************************/
271
272 void GeoTopNodeRnrEl::SetGlobalTrans(const TGeoHMatrix* m)
273 {
274   fGlobalTrans.SetFrom(*m);
275 }
276
277 void GeoTopNodeRnrEl::UseNodeTrans()
278 {
279   fGlobalTrans.SetFrom(*fNode->GetMatrix());
280 }
281
282 /**************************************************************************/
283
284 void GeoTopNodeRnrEl::SetVisOption(Int_t visopt)
285 {
286   fVisOption = visopt;
287   gReve->Redraw3D();
288 }
289
290 void GeoTopNodeRnrEl::SetVisLevel(Int_t vislvl)
291 {
292   fVisLevel = vislvl;
293   gReve->Redraw3D();
294 }
295
296 /**************************************************************************/
297
298 void GeoTopNodeRnrEl::SetRnrSelf(Bool_t rnr)
299 {
300   // Revert from GeoNode to back to standard behaviour.
301   RenderElement::SetRnrSelf(rnr);
302 }
303
304 /**************************************************************************/
305
306 void GeoTopNodeRnrEl::Draw(Option_t* option)
307 {
308   AppendPad(option);
309 }
310
311 void GeoTopNodeRnrEl::Paint(Option_t* option)
312 {
313   if(fRnrSelf) {
314     gGeoManager = fManager;
315     TVirtualPad* pad = gPad;
316     gPad = 0;
317     TGeoVolume* top_volume = fManager->GetTopVolume();
318     fManager->SetVisOption(fVisOption);
319     fManager->SetVisLevel(fVisLevel);
320     fManager->SetTopVolume(fNode->GetVolume());
321     gPad = pad;
322     TVirtualGeoPainter* vgp = fManager->GetGeomPainter();
323     if(vgp != 0) {
324       TGeoHMatrix geomat;
325       fGlobalTrans.SetGeoHMatrix(geomat);
326       vgp->PaintNode(fNode, option, &geomat);
327     }
328     fManager->SetTopVolume(top_volume);
329   }
330 }
331
332 /**************************************************************************/
333
334 void GeoTopNodeRnrEl::VolumeVisChanged(TGeoVolume* volume)
335 {
336   static const Exc_t eH("GeoTopNodeRnrEl::VolumeVisChanged ");
337   printf("%s volume %s %p\n", eH.Data(), volume->GetName(), (void*)volume);
338   UpdateVolume(volume);
339 }
340
341 void GeoTopNodeRnrEl::VolumeColChanged(TGeoVolume* volume)
342 {
343   static const Exc_t eH("GeoTopNodeRnrEl::VolumeColChanged ");
344   printf("%s volume %s %p\n", eH.Data(), volume->GetName(), (void*)volume);
345   UpdateVolume(volume);
346 }
347
348 void GeoTopNodeRnrEl::NodeVisChanged(TGeoNode* node)
349 {
350   static const Exc_t eH("GeoTopNodeRnrEl::NodeVisChanged ");
351   printf("%s node %s %p\n", eH.Data(), node->GetName(), (void*)node);
352   UpdateNode(node);
353 }
354
355
356 /**************************************************************************/
357 //______________________________________________________________________
358 // GeoShapeRnrEl
359 //
360 // Minimal shape-wrapper allowing import of stuff from gled and retaining
361 // user-set visibility, colors and transparency.
362 /**************************************************************************/
363
364 ClassImp(GeoShapeRnrEl)
365
366 GeoShapeRnrEl::GeoShapeRnrEl(const Text_t* name, const Text_t* title) :
367   RenderElement(),
368   TNamed        (name, title),
369   fHMTrans      (),
370   fColor        (0),
371   fTransparency (0),
372   fShape        (0)
373 {
374   fMainColorPtr = &fColor;
375 }
376
377 GeoShapeRnrEl::~GeoShapeRnrEl()
378 {
379   if (fShape) {
380     fShape->SetUniqueID(fShape->GetUniqueID() - 1);
381     if (fShape->GetUniqueID() == 0)
382       delete fShape;
383   }
384 }
385
386 /**************************************************************************/
387
388 void GeoShapeRnrEl::Paint(Option_t* /*option*/)
389 {
390   if (fShape == 0)
391     return;
392
393   TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D
394     (TBuffer3D::kCore, false);
395
396   buff.fID           = this;
397   buff.fColor        = fColor;
398   buff.fTransparency = fTransparency;
399   fHMTrans.SetBuffer3D(buff);
400   buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).
401
402   fShape->GetBuffer3D(TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific, true);
403
404   Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);
405
406   if (reqSec != TBuffer3D::kNone) {
407     fShape->GetBuffer3D(reqSec, true);
408     reqSec = gPad->GetViewer3D()->AddObject(buff);
409   }
410
411   if (reqSec != TBuffer3D::kNone)
412     printf("spooky reqSec=%d for %s\n", reqSec, GetName());
413 }
414
415 /**************************************************************************/
416
417 void GeoShapeRnrEl::Save(const char* file, const char* name)
418 {
419   TGeoShapeExtract* gse = DumpShapeTree(this, 0);
420   
421   TFile f(file, "RECREATE");
422   gse->Write(name);
423   f.Close();
424 }
425
426 /**************************************************************************/
427
428 TGeoShapeExtract* GeoShapeRnrEl::DumpShapeTree(GeoShapeRnrEl* gsre, TGeoShapeExtract* parent)
429 {
430   //  printf("dump_shape_tree %s \n", gsre->GetName());
431   TGeoShapeExtract* she = new TGeoShapeExtract(gsre->GetName(), gsre->GetTitle());
432   she->SetTrans(gsre->RefHMTrans().Array());
433   Int_t ci = gsre->GetColor();
434   TColor* c = gROOT->GetColor(ci);
435   Float_t rgba[4] = {1, 0, 0, 1 - gsre->GetMainTransparency()/100.};
436   if (c)
437  {
438     rgba[0] = c->GetRed();
439     rgba[1] = c->GetGreen();
440     rgba[2] = c->GetBlue();
441   } 
442   she->SetRGBA(rgba);
443   she->SetRnrSelf(gsre->GetRnrSelf());
444   she->SetRnrElements(gsre->GetRnrChildren());
445   she->SetShape(gsre->GetShape());
446   if ( gsre->GetNChildren())
447   {
448     TList* ele = new TList();
449     she->SetElements(ele);
450     she->GetElements()->SetOwner(true);
451     RenderElement::List_i i = gsre->BeginChildren();
452     while (i != gsre->EndChildren()) {
453       GeoShapeRnrEl* l = dynamic_cast<GeoShapeRnrEl*>(*i);
454       DumpShapeTree(l, she);
455       i++;
456     }
457   }
458   if(parent)
459     parent->GetElements()->Add(she);
460
461   return she; 
462 }
463
464 GeoShapeRnrEl* GeoShapeRnrEl::ImportShapeExtract(TGeoShapeExtract * gse,
465                                         RenderElement    * parent)
466 {
467   gReve->DisableRedraw();
468   GeoShapeRnrEl* gsre = SubImportShapeExtract(gse, parent);
469   gsre->ElementChanged();
470   gReve->EnableRedraw();
471   return gsre;
472 }
473
474
475 GeoShapeRnrEl* GeoShapeRnrEl::SubImportShapeExtract(TGeoShapeExtract * gse,
476                                            RenderElement    * parent)
477 {
478   GeoShapeRnrEl* gsre = new GeoShapeRnrEl(gse->GetName(), gse->GetTitle());
479   gsre->fHMTrans.SetFromArray(gse->GetTrans());
480   const Float_t* rgba = gse->GetRGBA();
481   gsre->fColor        = TColor::GetColor(rgba[0], rgba[1], rgba[2]);
482   gsre->fTransparency = (UChar_t) (100.0f*(1.0f - rgba[3]));
483   gsre->SetRnrSelf(gse->GetRnrSelf());
484   gsre->SetRnrChildren(gse->GetRnrElements());
485   gsre->fShape = gse->GetShape();
486   if (gsre->fShape)
487     gsre->fShape->SetUniqueID(gsre->fShape->GetUniqueID() + 1);
488
489   gReve->AddGlobalRenderElement(gsre, parent);
490
491   if (gse->HasElements())
492   {
493     TIter next(gse->GetElements());
494     TGeoShapeExtract* chld;
495     while ((chld = (TGeoShapeExtract*) next()) != 0)
496      SubImportShapeExtract(chld, gsre);
497   }
498
499   return gsre;
500 }
501
502 /**************************************************************************/
503
504 TClass* GeoShapeRnrEl::ProjectedClass() const
505 {
506    return NLTPolygonSet::Class();
507
508
509 /**************************************************************************/
510
511 TBuffer3D* GeoShapeRnrEl::MakeBuffer3D()
512 {
513   if(fShape == 0) return 0;
514
515   if(dynamic_cast<TGeoShapeAssembly*>(fShape)){
516     // !!!! TGeoShapeAssembly makes a bad TBuffer3D
517     return 0;
518   }
519
520   TBuffer3D* buff  = fShape->MakeBuffer3D();
521   if (fHMTrans.GetUseTrans())
522   {
523     Reve::ZTrans& mx = RefHMTrans();
524     Int_t N = buff->NbPnts();
525     Double_t* pnts = buff->fPnts;
526     for(Int_t k=0; k<N; k++)
527     {
528       mx.MultiplyIP(&pnts[3*k]);
529     }
530   }
531   return buff;
532 }
533
534
535