]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/GeoNode.cxx
Move implementation of NLTProjectable class for geometry into GeoNode
[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
14 #include <TGeoShape.h>
15 #include <TGeoVolume.h>
16 #include <TGeoNode.h>
17 #include <TGeoShapeAssembly.h>
18 #include <TGeoManager.h>
19 #include <TVirtualGeoPainter.h>
20
21 using namespace Reve;
22 //______________________________________________________________________
23 // GeoNodeRnrEl
24 //
25
26 ClassImp(GeoRnrEl)
27
28 TClass* GeoRnrEl::ProjectedClass() const
29 {
30    return NLTPolygonSet::Class();
31 }
32
33 //______________________________________________________________________
34 // GeoNodeRnrEl
35 //
36
37 ClassImp(GeoNodeRnrEl)
38
39 GeoNodeRnrEl::GeoNodeRnrEl(TGeoNode* node) :
40   GeoRnrEl(),
41   TObject(),
42   fNode(node)
43 {
44   // Hack!! Should use cint to retrieve TAttLine::fLineColor offset.
45   char* l = (char*) dynamic_cast<TAttLine*>(node->GetVolume());
46   SetMainColorPtr((Color_t*)(l + sizeof(void*)));
47
48   fRnrSelf      = fNode->TGeoAtt::IsVisible();
49 }
50
51 const Text_t* GeoNodeRnrEl::GetName()  const { return fNode->GetName(); }
52 const Text_t* GeoNodeRnrEl::GetTitle() const { return fNode->GetTitle(); }
53
54 /**************************************************************************/
55
56 Int_t GeoNodeRnrEl::ExpandIntoListTree(TGListTree* ltree,
57                                        TGListTreeItem* parent)
58 {
59   // Checks if child-nodes have been imported ... imports them if not.
60   // Then calls RenderElement::ExpandIntoListTree.
61
62   if(fChildren.empty() && fNode->GetVolume()->GetNdaughters() > 0) {
63     TIter next(fNode->GetVolume()->GetNodes());
64     TGeoNode* dnode;
65     while((dnode = (TGeoNode*) next()) != 0) {
66       GeoNodeRnrEl* node_re = new GeoNodeRnrEl(dnode);
67       AddElement(node_re);
68     }
69   }
70   return RenderElement::ExpandIntoListTree(ltree, parent);
71 }
72
73 /**************************************************************************/
74
75 void GeoNodeRnrEl::SetRnrSelf(Bool_t rnr)
76 {
77   RenderElement::SetRnrSelf(rnr);
78   fNode->SetVisibility(rnr);
79 }
80
81 void GeoNodeRnrEl::SetRnrChildren(Bool_t rnr)
82 {
83   RenderElement::SetRnrChildren(rnr);
84   fNode->VisibleDaughters(rnr);
85 }
86
87 void GeoNodeRnrEl::SetRnrState(Bool_t rnr)
88 {
89   RenderElement::SetRnrState(rnr);
90   fNode->SetVisibility(rnr);
91   fNode->VisibleDaughters(rnr);
92 }
93
94 /**************************************************************************/
95
96 void GeoNodeRnrEl::SetMainColor(Color_t color)
97 {
98   fNode->GetVolume()->SetLineColor(color);
99   UpdateItems();
100 }
101
102 void GeoNodeRnrEl::SetMainColor(Pixel_t pixel)
103 {
104   // This one needed for proper calling via CINT (signals).
105
106   SetMainColor(Color_t(TColor::GetColor(pixel)));
107 }
108
109 /**************************************************************************/
110
111 void GeoNodeRnrEl::UpdateNode(TGeoNode* node)
112 {
113   // Updates all reve-browsers having the node in their contents.
114   // All 3D-pads updated if any change found.
115   //
116   // Should (could?) be optimized with some assumptions about
117   // volume/node structure (search for parent, know the same node can not
118   // reoccur on lower level once found).
119
120   static const Exc_t eH("GeoNodeRnrEl::UpdateNode ");
121
122   // printf("%s node %s %p\n", eH.Data(), node->GetName(), node);
123
124   if(fNode == node)
125     UpdateItems();
126
127   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
128     ((GeoNodeRnrEl*)(*i))->UpdateNode(node);
129   }
130
131 }
132
133 void GeoNodeRnrEl::UpdateVolume(TGeoVolume* volume)
134 {
135   // Updates all reve-browsers having the volume in their contents.
136   // All 3D-pads updated if any change found.
137   //
138   // Should (could?) be optimized with some assumptions about
139   // volume/node structure (search for parent, know the same node can not
140   // reoccur on lower level once found).
141
142   static const Exc_t eH("GeoNodeRnrEl::UpdateVolume ");
143
144   // printf("%s volume %s %p\n", eH.Data(), volume->GetName(), volume);
145
146   if(fNode->GetVolume() == volume)
147     UpdateItems();
148
149   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
150     ((GeoNodeRnrEl*)(*i))->UpdateVolume(volume);
151   }
152 }
153
154 /**************************************************************************/
155
156 void GeoNodeRnrEl::Draw(Option_t* option)
157 {
158   TString opt("SAME");
159   opt += option;
160   fNode->GetVolume()->Draw(opt);
161 }
162
163 /**************************************************************************/
164
165 TBuffer3D* GeoNodeRnrEl::MakeBuffer3D()
166 {
167   TGeoShape* shape = fNode->GetVolume()->GetShape();
168   if(shape == 0) return 0;
169
170   if(dynamic_cast<TGeoShapeAssembly*>(shape)){
171     // !!!! TGeoShapeAssembly makes a bad TBuffer3D
172     return 0;
173   }
174
175   printf("eoNodeRnrEl::MakeBuffer3D() \n");
176   TBuffer3D* buff  = shape->MakeBuffer3D();
177   TGeoMatrix* mx = fNode->GetMatrix();
178   Int_t N = buff->NbPnts();
179   Double_t* pnts = buff->fPnts;
180   Double_t  master[4];
181   for(Int_t i = 0; i<N; i++)
182   {
183     mx->LocalToMaster(&pnts[3*i], master);
184     pnts[3*i] =   master[0];
185     pnts[3*i+1] = master[1];
186     pnts[3*i+2] = master[2];
187   }
188   return buff;
189 }
190 /**************************************************************************/
191 //______________________________________________________________________
192 // GeoTopNodeRnrEl
193 //
194 // A wrapper over a TGeoNode, possibly displaced with a global
195 // trasformation fGlobalTrans (the matrix is owned by this class).
196 /**************************************************************************/
197
198 ClassImp(GeoTopNodeRnrEl)
199
200 GeoTopNodeRnrEl::GeoTopNodeRnrEl(TGeoManager* manager, TGeoNode* node,
201                                  Int_t visopt, Int_t vislvl) :
202   GeoNodeRnrEl (node),
203   fManager     (manager),
204   fGlobalTrans (),
205   fVisOption   (visopt),
206   fVisLevel    (vislvl)
207 {
208   fRnrSelf = true;
209 }
210
211 GeoTopNodeRnrEl::~GeoTopNodeRnrEl()
212 {}
213
214 /**************************************************************************/
215
216 void GeoTopNodeRnrEl::SetGlobalTrans(const TGeoHMatrix* m)
217 {
218   fGlobalTrans.SetFrom(*m);
219 }
220
221 void GeoTopNodeRnrEl::UseNodeTrans()
222 {
223   fGlobalTrans.SetFrom(*fNode->GetMatrix());
224 }
225
226 /**************************************************************************/
227
228 void GeoTopNodeRnrEl::SetVisOption(Int_t visopt)
229 {
230   fVisOption = visopt;
231   gReve->Redraw3D();
232 }
233
234 void GeoTopNodeRnrEl::SetVisLevel(Int_t vislvl)
235 {
236   fVisLevel = vislvl;
237   gReve->Redraw3D();
238 }
239
240 /**************************************************************************/
241
242 void GeoTopNodeRnrEl::SetRnrSelf(Bool_t rnr)
243 {
244   // Revert from GeoNode to back to standard behaviour.
245   RenderElement::SetRnrSelf(rnr);
246 }
247
248 /**************************************************************************/
249
250 void GeoTopNodeRnrEl::Draw(Option_t* option)
251 {
252   AppendPad(option);
253 }
254
255 void GeoTopNodeRnrEl::Paint(Option_t* option)
256 {
257   if(fRnrSelf) {
258     gGeoManager = fManager;
259     TVirtualPad* pad = gPad;
260     gPad = 0;
261     TGeoVolume* top_volume = fManager->GetTopVolume();
262     fManager->SetVisOption(fVisOption);
263     fManager->SetVisLevel(fVisLevel);
264     fManager->SetTopVolume(fNode->GetVolume());
265     gPad = pad;
266     TVirtualGeoPainter* vgp = fManager->GetGeomPainter();
267     if(vgp != 0) {
268       TGeoHMatrix geomat;
269       fGlobalTrans.SetGeoHMatrix(geomat);
270       vgp->PaintNode(fNode, option, &geomat);
271     }
272     fManager->SetTopVolume(top_volume);
273   }
274 }
275
276 /**************************************************************************/
277
278 void GeoTopNodeRnrEl::VolumeVisChanged(TGeoVolume* volume)
279 {
280   static const Exc_t eH("GeoTopNodeRnrEl::VolumeVisChanged ");
281   printf("%s volume %s %p\n", eH.Data(), volume->GetName(), (void*)volume);
282   UpdateVolume(volume);
283 }
284
285 void GeoTopNodeRnrEl::VolumeColChanged(TGeoVolume* volume)
286 {
287   static const Exc_t eH("GeoTopNodeRnrEl::VolumeColChanged ");
288   printf("%s volume %s %p\n", eH.Data(), volume->GetName(), (void*)volume);
289   UpdateVolume(volume);
290 }
291
292 void GeoTopNodeRnrEl::NodeVisChanged(TGeoNode* node)
293 {
294   static const Exc_t eH("GeoTopNodeRnrEl::NodeVisChanged ");
295   printf("%s node %s %p\n", eH.Data(), node->GetName(), (void*)node);
296   UpdateNode(node);
297 }
298
299
300 /**************************************************************************/
301 //______________________________________________________________________
302 // GeoShapeRnrEl
303 //
304 // Minimal shape-wrapper allowing import of stuff from gled and retaining
305 // user-set visibility, colors and transparency.
306 /**************************************************************************/
307
308 ClassImp(GeoShapeRnrEl)
309
310 GeoShapeRnrEl::GeoShapeRnrEl(const Text_t* name, const Text_t* title) :
311   GeoRnrEl(),
312   TNamed        (name, title),
313   fHMTrans      (),
314   fColor        (0),
315   fTransparency (0),
316   fShape        (0)
317 {
318   fMainColorPtr = &fColor;
319 }
320
321 GeoShapeRnrEl::~GeoShapeRnrEl()
322 {
323   if (fShape) {
324     fShape->SetUniqueID(fShape->GetUniqueID() - 1);
325     if (fShape->GetUniqueID() == 0)
326       delete fShape;
327   }
328 }
329
330 /**************************************************************************/
331
332 void GeoShapeRnrEl::Paint(Option_t* /*option*/)
333 {
334   if (fShape == 0)
335     return;
336
337   TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D
338     (TBuffer3D::kCore, false);
339
340   buff.fID           = this;
341   buff.fColor        = fColor;
342   buff.fTransparency = fTransparency;
343   fHMTrans.SetBuffer3D(buff);
344   buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).
345
346   fShape->GetBuffer3D(TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific, true);
347
348   Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);
349
350   if (reqSec != TBuffer3D::kNone) {
351     fShape->GetBuffer3D(reqSec, true);
352     reqSec = gPad->GetViewer3D()->AddObject(buff);
353   }
354
355   if (reqSec != TBuffer3D::kNone)
356     printf("spooky reqSec=%d for %s\n", reqSec, GetName());
357 }
358
359 /**************************************************************************/
360
361 GeoShapeRnrEl* GeoShapeRnrEl::ImportShapeExtract(TGeoShapeExtract * gse,
362                                         RenderElement    * parent)
363 {
364   gReve->DisableRedraw();
365   GeoShapeRnrEl* gsre = SubImportShapeExtract(gse, parent);
366   gsre->ElementChanged();
367   gReve->EnableRedraw();
368   return gsre;
369 }
370
371
372 GeoShapeRnrEl* GeoShapeRnrEl::SubImportShapeExtract(TGeoShapeExtract * gse,
373                                            RenderElement    * parent)
374 {
375   GeoShapeRnrEl* gsre = new GeoShapeRnrEl(gse->GetName(), gse->GetTitle());
376   gsre->fHMTrans.SetFromArray(gse->GetTrans());
377   const Float_t* rgba = gse->GetRGBA();
378   gsre->fColor        = TColor::GetColor(rgba[0], rgba[1], rgba[2]);
379   gsre->fTransparency = (UChar_t) (100.0f*(1.0f - rgba[3]));
380   gsre->SetRnrSelf(gse->GetRnrSelf());
381   gsre->SetRnrChildren(gse->GetRnrElements());
382   gsre->fShape = gse->GetShape();
383   if (gsre->fShape)
384     gsre->fShape->SetUniqueID(gsre->fShape->GetUniqueID() + 1);
385
386   gReve->AddGlobalRenderElement(gsre, parent);
387
388   if (gse->HasElements())
389   {
390     TIter next(gse->GetElements());
391     TGeoShapeExtract* chld;
392     while ((chld = (TGeoShapeExtract*) next()) != 0)
393      SubImportShapeExtract(chld, gsre);
394   }
395
396   return gsre;
397 }
398
399 /**************************************************************************/
400
401 TBuffer3D* GeoShapeRnrEl::MakeBuffer3D()
402 {
403   if(fShape == 0) return 0;
404
405   if(dynamic_cast<TGeoShapeAssembly*>(fShape)){
406     // !!!! TGeoShapeAssembly makes a bad TBuffer3D
407     return 0;
408   }
409
410   TBuffer3D* buff  = fShape->MakeBuffer3D();
411   if (fHMTrans.GetUseTrans())
412   {
413     Reve::ZTrans& mx = RefHMTrans();
414     Int_t N = buff->NbPnts();
415     Double_t* pnts = buff->fPnts;
416     for(Int_t k=0; k<N; k++)
417     {
418       mx.MultiplyIP(&pnts[3*k]);
419     }
420   }
421   return buff;
422 }