00001
00002
00003
00004 #include "TGLLogicalShape.h"
00005 #include "TGLPhysicalShape.h"
00006 #include "TGLRnrCtx.h"
00007 #include "TGLScene.h"
00008 #include "TGLCamera.h"
00009 #include "TGLSelectRecord.h"
00010 #include "TGLContext.h"
00011 #include "TGLIncludes.h"
00012
00013 #include "TBuffer3D.h"
00014 #include "TClass.h"
00015 #include "TContextMenu.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 ClassImp(TGLLogicalShape);
00067
00068
00069 TGLLogicalShape::TGLLogicalShape() :
00070 fRef (0),
00071 fFirstPhysical (0),
00072 fExternalObj (0),
00073 fScene (0),
00074 fDLBase (0),
00075 fDLSize (1),
00076 fDLValid (0),
00077 fDLCache (kTRUE),
00078 fRefStrong (kFALSE),
00079 fOwnExtObj (kFALSE)
00080 {
00081
00082 }
00083
00084
00085 TGLLogicalShape::TGLLogicalShape(TObject* obj) :
00086 fRef (0),
00087 fFirstPhysical (0),
00088 fExternalObj (obj),
00089 fScene (0),
00090 fDLBase (0),
00091 fDLSize (1),
00092 fDLValid (0),
00093 fDLCache (kTRUE),
00094 fRefStrong (kFALSE),
00095 fOwnExtObj (kFALSE)
00096 {
00097
00098 }
00099
00100
00101 TGLLogicalShape::TGLLogicalShape(const TBuffer3D & buffer) :
00102 fRef (0),
00103 fFirstPhysical (0),
00104 fExternalObj (buffer.fID),
00105 fScene (0),
00106 fDLBase (0),
00107 fDLSize (1),
00108 fDLValid (0),
00109 fDLCache (kTRUE),
00110 fRefStrong (kFALSE),
00111 fOwnExtObj (kFALSE)
00112 {
00113
00114
00115
00116 if (buffer.SectionsValid(TBuffer3D::kBoundingBox)) {
00117 fBoundingBox.Set(buffer.fBBVertex);
00118 } else if (buffer.SectionsValid(TBuffer3D::kRaw)) {
00119
00120 fBoundingBox.SetAligned(buffer.NbPnts(), buffer.fPnts);
00121 }
00122
00123
00124
00125 if (fExternalObj == 0)
00126 {
00127 fExternalObj = new TNamed("Generic object", "Internal object created for bookkeeping.");
00128 fOwnExtObj = kTRUE;
00129 }
00130 }
00131
00132
00133 TGLLogicalShape::~TGLLogicalShape()
00134 {
00135
00136
00137
00138
00139 if (fRef > 0) {
00140 Warning("TGLLogicalShape::~TGLLogicalShape", "some physicals still lurking around.");
00141 DestroyPhysicals();
00142 }
00143 DLCachePurge();
00144 if (fOwnExtObj)
00145 {
00146 delete fExternalObj;
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 void TGLLogicalShape::AddRef(TGLPhysicalShape* phys) const
00157 {
00158
00159
00160 phys->fNextPhysical = fFirstPhysical;
00161 fFirstPhysical = phys;
00162 ++fRef;
00163 }
00164
00165
00166 void TGLLogicalShape::SubRef(TGLPhysicalShape* phys) const
00167 {
00168
00169
00170
00171
00172 assert(phys != 0);
00173
00174 Bool_t found = kFALSE;
00175 if (fFirstPhysical == phys) {
00176 fFirstPhysical = phys->fNextPhysical;
00177 found = kTRUE;
00178 } else {
00179 TGLPhysicalShape *shp1 = fFirstPhysical, *shp2;
00180 while ((shp2 = shp1->fNextPhysical) != 0) {
00181 if (shp2 == phys) {
00182 shp1->fNextPhysical = shp2->fNextPhysical;
00183 found = kTRUE;
00184 break;
00185 }
00186 shp1 = shp2;
00187 }
00188 }
00189 if (found == kFALSE) {
00190 Error("TGLLogicalShape::SubRef", "Attempt to un-ref an unregistered physical.");
00191 return;
00192 }
00193
00194 if (--fRef == 0 && fRefStrong)
00195 delete this;
00196 }
00197
00198
00199 void TGLLogicalShape::DestroyPhysicals()
00200 {
00201
00202
00203 TGLPhysicalShape *curr = fFirstPhysical, *next;
00204 while (curr)
00205 {
00206 next = curr->fNextPhysical;
00207 curr->fLogicalShape = 0;
00208 --fRef;
00209 delete curr;
00210 curr = next;
00211 }
00212 assert (fRef == 0);
00213 fFirstPhysical = 0;
00214 }
00215
00216
00217 UInt_t TGLLogicalShape::UnrefFirstPhysical()
00218 {
00219
00220
00221
00222
00223 if (fFirstPhysical == 0) return 0;
00224
00225 TGLPhysicalShape *phys = fFirstPhysical;
00226 UInt_t phid = phys->ID();
00227 fFirstPhysical = phys->fNextPhysical;
00228 phys->fLogicalShape = 0;
00229 --fRef;
00230 return phid;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 void TGLLogicalShape::UpdateBoundingBoxesOfPhysicals()
00240 {
00241
00242
00243 TGLPhysicalShape* pshp = fFirstPhysical;
00244 while (pshp)
00245 {
00246 pshp->UpdateBoundingBox();
00247 pshp = pshp->fNextPhysical;
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 Bool_t TGLLogicalShape::SetDLCache(Bool_t cache)
00258 {
00259
00260
00261
00262 if (cache == fDLCache)
00263 return kFALSE;
00264
00265 if (fDLCache)
00266 DLCachePurge();
00267 fDLCache = cache;
00268 return kTRUE;
00269 }
00270
00271
00272 Bool_t TGLLogicalShape::ShouldDLCache(const TGLRnrCtx& rnrCtx) const
00273 {
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 if (!fDLCache || !fScene ||
00287 (rnrCtx.SecSelection() && SupportsSecondarySelect()))
00288 {
00289 return kFALSE;
00290 }
00291 return kTRUE;
00292 }
00293
00294
00295 void TGLLogicalShape::DLCacheClear()
00296 {
00297
00298
00299
00300 fDLValid = 0;
00301 }
00302
00303
00304 void TGLLogicalShape::DLCacheDrop()
00305 {
00306
00307
00308
00309
00310
00311
00312 fDLBase = 0;
00313 fDLValid = 0;
00314 }
00315
00316
00317 void TGLLogicalShape::DLCachePurge()
00318 {
00319
00320
00321
00322
00323
00324
00325
00326 if (fDLBase != 0)
00327 {
00328 PurgeDLRange(fDLBase, fDLSize);
00329 fDLBase = 0;
00330 fDLValid = 0;
00331 }
00332 }
00333
00334
00335 void TGLLogicalShape::PurgeDLRange(UInt_t base, Int_t size) const
00336 {
00337
00338
00339
00340 if (fScene)
00341 {
00342 fScene->GetGLCtxIdentity()->RegisterDLNameRangeToWipe(base, size);
00343 }
00344 else
00345 {
00346 Warning("TGLLogicalShape::PurgeDLRange", "Scene unknown, attempting direct deletion.");
00347 glDeleteLists(base, size);
00348 }
00349 }
00350
00351
00352 Short_t TGLLogicalShape::QuantizeShapeLOD(Short_t shapeLOD,
00353 Short_t ) const
00354 {
00355
00356
00357
00358
00359
00360 return shapeLOD;
00361 }
00362
00363
00364 void TGLLogicalShape::Draw(TGLRnrCtx& rnrCtx) const
00365 {
00366
00367
00368
00369
00370
00371
00372 if (gDebug > 4) {
00373 Info("TGLLogicalShape::Draw", "this %ld (class %s) LOD %d", (Long_t)this, IsA()->GetName(), rnrCtx.ShapeLOD());
00374 }
00375
00376 entry_point:
00377
00378
00379
00380
00381
00382
00383
00384 if (!ShouldDLCache(rnrCtx) || rnrCtx.IsDLCaptureOpen())
00385 {
00386 DirectDraw(rnrCtx);
00387 return;
00388 }
00389
00390 if (fDLBase == 0)
00391 {
00392 fDLBase = glGenLists(fDLSize);
00393 if (fDLBase == 0)
00394 {
00395 Warning("TGLLogicalShape::Draw", "display-list registration failed.");
00396 fDLCache = kFALSE;
00397 goto entry_point;
00398 }
00399 }
00400
00401 Short_t lod = rnrCtx.ShapeLOD();
00402 UInt_t off = DLOffset(lod);
00403 if ((1<<off) & fDLValid)
00404 {
00405 glCallList(fDLBase + off);
00406 }
00407 else
00408 {
00409 rnrCtx.OpenDLCapture();
00410 glNewList(fDLBase + off, GL_COMPILE_AND_EXECUTE);
00411 DirectDraw(rnrCtx);
00412 glEndList();
00413 rnrCtx.CloseDLCapture();
00414 fDLValid |= (1<<off);
00415 }
00416 }
00417
00418
00419 void TGLLogicalShape::DrawHighlight(TGLRnrCtx& rnrCtx, const TGLPhysicalShape* pshp, Int_t lvl) const
00420 {
00421
00422
00423
00424
00425 const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
00426 Int_t inner[4][2] = { { 0,-1}, { 1, 0}, { 0, 1}, {-1, 0} };
00427 Int_t outer[8][2] = { {-1,-1}, { 1,-1}, { 1, 1}, {-1, 1},
00428 { 0,-2}, { 2, 0}, { 0, 2}, {-2, 0} };
00429
00430 if (lvl < 0) lvl = pshp->GetSelected();
00431
00432 rnrCtx.SetHighlightOutline(kTRUE);
00433 TGLUtil::LockColor();
00434 Int_t first_outer = (rnrCtx.CombiLOD() == TGLRnrCtx::kLODHigh) ? 0 : 4;
00435 for (int i = first_outer; i < 8; ++i)
00436 {
00437 glViewport(vp.X() + outer[i][0], vp.Y() + outer[i][1], vp.Width(), vp.Height());
00438 glColor4ubv(rnrCtx.ColorSet().Selection(lvl).CArr());
00439 Draw(rnrCtx);
00440 }
00441 TGLUtil::UnlockColor();
00442 rnrCtx.SetHighlightOutline(kFALSE);
00443
00444 pshp->SetupGLColors(rnrCtx);
00445 for (int i = 0; i < 4; ++i)
00446 {
00447 glViewport(vp.X() + inner[i][0], vp.Y() + inner[i][1], vp.Width(), vp.Height());
00448 glColor4fv(pshp->Color());
00449 Draw(rnrCtx);
00450 }
00451 glViewport(vp.X(), vp.Y(), vp.Width(), vp.Height());
00452
00453 pshp->SetupGLColors(rnrCtx);
00454 Float_t dr[2];
00455 glGetFloatv(GL_DEPTH_RANGE,dr);
00456 glDepthRange(dr[0], 0.5*dr[1]);
00457 Draw(rnrCtx);
00458 glDepthRange(dr[0], dr[1]);
00459 }
00460
00461
00462 void TGLLogicalShape::ProcessSelection(TGLRnrCtx& , TGLSelectRecord& rec)
00463 {
00464
00465
00466
00467
00468
00469
00470 printf("TGLLogicalShape::ProcessSelection %d names on the stack (z1=%g, z2=%g).\n",
00471 rec.GetN(), rec.GetMinZ(), rec.GetMaxZ());
00472 printf(" Names: ");
00473 for (Int_t j=0; j<rec.GetN(); ++j) printf ("%u ", rec.GetItem(j));
00474 printf("\n");
00475 }
00476
00477
00478 void TGLLogicalShape::InvokeContextMenu(TContextMenu& menu, UInt_t x, UInt_t y) const
00479 {
00480
00481
00482 if (fExternalObj) {
00483 menu.Popup(x, y, fExternalObj);
00484 }
00485 }