00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TGLClip.h"
00013 #include "TGLIncludes.h"
00014 #include "TGLRnrCtx.h"
00015 #include "TGLManipSet.h"
00016
00017 #include "TGLFaceSet.h"
00018 #include "TBuffer3D.h"
00019 #include "TBuffer3DTypes.h"
00020
00021 namespace
00022 {
00023
00024 class TGLClipPlaneLogical : public TGLLogicalShape
00025 {
00026 protected:
00027 virtual void DirectDraw(TGLRnrCtx & rnrCtx) const
00028 {
00029 glBegin(rnrCtx.IsDrawPassFilled() ? GL_QUADS : GL_LINE_LOOP);
00030 glNormal3d (0.0, 0.0, 1.0);
00031 glVertex3dv(fBoundingBox[4].CArr());
00032 glVertex3dv(fBoundingBox[7].CArr());
00033 glVertex3dv(fBoundingBox[6].CArr());
00034 glVertex3dv(fBoundingBox[5].CArr());
00035 glEnd();
00036 }
00037
00038 public:
00039 TGLClipPlaneLogical() : TGLLogicalShape() { fDLCache = kFALSE; }
00040 virtual ~TGLClipPlaneLogical() {}
00041
00042 void Resize(Double_t ext)
00043 {
00044 fBoundingBox.SetAligned(TGLVertex3(-ext, -ext, 0),
00045 TGLVertex3( ext, ext, 0));
00046 UpdateBoundingBoxesOfPhysicals();
00047 }
00048
00049 };
00050
00051
00052 class TGLClipBoxLogical : public TGLLogicalShape
00053 {
00054 protected:
00055 virtual void DirectDraw(TGLRnrCtx & rnrCtx) const
00056 {
00057 glEnable(GL_NORMALIZE);
00058 fBoundingBox.Draw(rnrCtx.IsDrawPassFilled());
00059 glDisable(GL_NORMALIZE);
00060 }
00061
00062 public:
00063 TGLClipBoxLogical() : TGLLogicalShape() { fDLCache = kFALSE; }
00064 virtual ~TGLClipBoxLogical() {}
00065
00066 void Resize(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex)
00067 {
00068 fBoundingBox.SetAligned(lowVertex, highVertex);
00069 UpdateBoundingBoxesOfPhysicals();
00070 }
00071 };
00072
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 ClassImp(TGLClip);
00087
00088
00089 TGLClip::TGLClip(const TGLLogicalShape & logical, const TGLMatrix & transform, const float color[4]) :
00090 TGLPhysicalShape(0, logical, transform, kTRUE, color),
00091 fMode (kInside),
00092 fTimeStamp (1),
00093 fValid (kFALSE)
00094 {
00095
00096
00097 logical.StrongRef(kTRUE);
00098 }
00099
00100
00101 TGLClip::~TGLClip()
00102 {
00103
00104 }
00105
00106
00107 void TGLClip::Setup(const TGLVector3&, const TGLVector3&)
00108 {
00109
00110
00111
00112
00113 Warning("TGLClip::Setup", "Called on base-class -- should be re-implemented in derived class.");
00114
00115 }
00116
00117
00118 void TGLClip::Draw(TGLRnrCtx & rnrCtx) const
00119 {
00120
00121
00122
00123 glDepthMask(GL_FALSE);
00124 glEnable(GL_BLEND);
00125 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00126 glDisable(GL_CULL_FACE);
00127 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00128
00129 TGLPhysicalShape::Draw(rnrCtx);
00130
00131 glPolygonMode(GL_FRONT, GL_FILL);
00132 glEnable(GL_CULL_FACE);
00133 glDisable(GL_BLEND);
00134 glDepthMask(GL_TRUE);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 ClassImp(TGLClipPlane);
00148
00149 const float TGLClipPlane::fgColor[4] = { 1.0, 0.6, 0.2, 0.5 };
00150
00151
00152 TGLClipPlane::TGLClipPlane() :
00153 TGLClip(* new TGLClipPlaneLogical, TGLMatrix(), fgColor)
00154 {
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 SetManip(EManip(kTranslateAll | kRotateX | kRotateY));
00169
00170 TGLPlane plane(0.0, -1.0, 0.0, 0.0);
00171 Set(plane);
00172 fValid = kFALSE;
00173 }
00174
00175
00176 TGLClipPlane::~TGLClipPlane()
00177 {
00178
00179 }
00180
00181
00182 void TGLClipPlane::Setup(const TGLBoundingBox & bbox)
00183 {
00184
00185
00186 Double_t extents = bbox.Extents().Mag();
00187 TGLClipPlaneLogical* cpl = (TGLClipPlaneLogical*) GetLogical();
00188 cpl->Resize(extents);
00189 if (!fValid) {
00190 SetTransform(TGLMatrix(bbox.Center(), BoundingBox().GetNearPlane().Norm()));
00191 }
00192 IncTimeStamp();
00193 fValid = kTRUE;
00194 }
00195
00196
00197 void TGLClipPlane::Setup(const TGLVector3& point, const TGLVector3& normal)
00198 {
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 TGLVector3 n(normal);
00210 Double_t extents = n.Mag();
00211 if (extents > 0)
00212 {
00213 n /= extents;
00214 TGLClipPlaneLogical* cpl = (TGLClipPlaneLogical*) GetLogical();
00215 cpl->Resize(extents);
00216 SetTransform(TGLMatrix(point, n));
00217
00218 IncTimeStamp();
00219 fValid = kTRUE;
00220 }
00221 else
00222 {
00223 Warning("TGLClipPlane::Setup", "Normal with zero length passed.");
00224 }
00225 }
00226
00227
00228 void TGLClipPlane::Set(const TGLPlane& plane)
00229 {
00230
00231
00232
00233 TGLVertex3 oldCenter = BoundingBox().Center();
00234 TGLVertex3 newCenter = plane.NearestOn(oldCenter);
00235 SetTransform(TGLMatrix(newCenter, plane.Norm()));
00236 IncTimeStamp();
00237 fValid = kTRUE;
00238 }
00239
00240
00241 void TGLClipPlane::PlaneSet(TGLPlaneSet_t& set) const
00242 {
00243
00244
00245 set.resize(1);
00246 set[0] = BoundingBox().GetNearPlane();
00247 set[0].Negate();
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 ClassImp(TGLClipBox);
00260
00261 const float TGLClipBox::fgColor[4] = { 1.0, 0.6, 0.2, 0.3 };
00262
00263
00264 TGLClipBox::TGLClipBox() :
00265 TGLClip(* new TGLClipBoxLogical, TGLMatrix(), fgColor)
00266 {
00267
00268
00269
00270 }
00271
00272
00273 TGLClipBox::~TGLClipBox()
00274 {
00275
00276 }
00277
00278
00279 void TGLClipBox::Setup(const TGLBoundingBox& bbox)
00280 {
00281
00282
00283 TGLVector3 halfLengths = bbox.Extents() * 0.2501;
00284 TGLVertex3 center = bbox.Center() + halfLengths;
00285
00286 TGLClipBoxLogical* cbl = (TGLClipBoxLogical*) GetLogical();
00287 cbl->Resize(center - halfLengths, center + halfLengths);
00288
00289 IncTimeStamp();
00290 fValid = kTRUE;
00291 }
00292
00293
00294 void TGLClipBox::Setup(const TGLVector3& min_point, const TGLVector3& max_point)
00295 {
00296
00297
00298
00299
00300
00301
00302
00303
00304 TGLClipBoxLogical* cbl = (TGLClipBoxLogical*) GetLogical();
00305 cbl->Resize(min_point, max_point);
00306
00307 IncTimeStamp();
00308 fValid = kTRUE;
00309 }
00310
00311
00312 void TGLClipBox::PlaneSet(TGLPlaneSet_t& set) const
00313 {
00314
00315
00316
00317 BoundingBox().PlaneSet(set);
00318 TGLPlaneSet_i i = set.begin();
00319 while (i != set.end()) {
00320 i->Negate();
00321 ++i;
00322 }
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 ClassImp(TGLClipSet);
00336
00337
00338 TGLClipSet::TGLClipSet() :
00339 TGLOverlayElement(kViewer),
00340 fClipPlane (new TGLClipPlane),
00341 fClipBox (new TGLClipBox),
00342 fCurrentClip (0),
00343 fAutoUpdate (kTRUE),
00344 fShowClip (kFALSE),
00345 fShowManip (kFALSE),
00346 fManip (new TGLManipSet)
00347 {
00348
00349 }
00350
00351
00352 TGLClipSet::~TGLClipSet()
00353 {
00354
00355
00356 delete fClipPlane;
00357 delete fClipBox;
00358 delete fManip;
00359 }
00360
00361
00362 Bool_t TGLClipSet::MouseEnter(TGLOvlSelectRecord& selRec)
00363 {
00364
00365
00366
00367 return fManip->MouseEnter(selRec);
00368 }
00369
00370 Bool_t TGLClipSet::MouseStillInside(TGLOvlSelectRecord& selRec)
00371 {
00372
00373
00374
00375 return fManip->MouseStillInside(selRec);
00376 }
00377
00378
00379 Bool_t TGLClipSet::Handle(TGLRnrCtx& rnrCtx, TGLOvlSelectRecord& selRec,
00380 Event_t* event)
00381 {
00382
00383
00384
00385 return fManip->Handle(rnrCtx, selRec, event);
00386 }
00387
00388
00389 void TGLClipSet::MouseLeave()
00390 {
00391
00392
00393
00394 return fManip->MouseLeave();
00395 }
00396
00397
00398 void TGLClipSet::Render(TGLRnrCtx& rnrCtx)
00399 {
00400
00401
00402 if (!fCurrentClip) return;
00403
00404 rnrCtx.SetShapeLOD(TGLRnrCtx::kLODHigh);
00405 rnrCtx.SetDrawPass(TGLRnrCtx::kPassFill);
00406 if (fShowClip && ! rnrCtx.Selection())
00407 {
00408 fCurrentClip->Draw(rnrCtx);
00409 }
00410 if (fShowManip)
00411 {
00412 fManip->Render(rnrCtx);
00413 }
00414 }
00415
00416
00417 void TGLClipSet::FillPlaneSet(TGLPlaneSet_t& set) const
00418 {
00419
00420
00421 if (fCurrentClip)
00422 fCurrentClip->PlaneSet(set);
00423 }
00424
00425
00426 void TGLClipSet::SetupClips(const TGLBoundingBox& sceneBBox)
00427 {
00428
00429
00430 fLastBBox = sceneBBox;
00431 fClipPlane->Setup(sceneBBox);
00432 fClipBox ->Setup(sceneBBox);
00433 }
00434
00435
00436 void TGLClipSet::SetupCurrentClip(const TGLBoundingBox& sceneBBox)
00437 {
00438
00439
00440 fLastBBox = sceneBBox;
00441 if (fCurrentClip)
00442 fCurrentClip->Setup(sceneBBox);
00443 }
00444
00445
00446 void TGLClipSet::SetupCurrentClipIfInvalid(const TGLBoundingBox& sceneBBox)
00447 {
00448
00449
00450 fLastBBox = sceneBBox;
00451 if (fCurrentClip && ! fCurrentClip->IsValid())
00452 fCurrentClip->Setup(sceneBBox);
00453 }
00454
00455
00456 void TGLClipSet::InvalidateClips()
00457 {
00458
00459
00460 fClipPlane->Invalidate();
00461 fClipBox ->Invalidate();
00462 }
00463
00464
00465 void TGLClipSet::InvalidateCurrentClip()
00466 {
00467
00468
00469 if (fCurrentClip)
00470 fCurrentClip->Invalidate();
00471 }
00472
00473
00474 void TGLClipSet::GetClipState(EClipType type, Double_t data[6]) const
00475 {
00476
00477
00478
00479
00480
00481
00482 switch (type)
00483 {
00484 case kClipNone:
00485 break;
00486
00487 case kClipPlane:
00488 {
00489 if (!fClipPlane->IsValid())
00490 fClipPlane->Setup(fLastBBox);
00491 TGLPlaneSet_t planes;
00492 fClipPlane->PlaneSet(planes);
00493 data[0] = planes[0].A();
00494 data[1] = planes[0].B();
00495 data[2] = planes[0].C();
00496 data[3] = planes[0].D();
00497 break;
00498 }
00499 case kClipBox:
00500 {
00501 if (!fClipBox->IsValid())
00502 fClipBox->Setup(fLastBBox);
00503 const TGLBoundingBox & box = fClipBox->BoundingBox();
00504 TGLVector3 ext = box.Extents();
00505 data[0] = box.Center().X();
00506 data[1] = box.Center().Y();
00507 data[2] = box.Center().Z();
00508 data[3] = box.Extents().X();
00509 data[4] = box.Extents().Y();
00510 data[5] = box.Extents().Z();
00511 break;
00512 }
00513 default:
00514 Error("TGLClipSet::GetClipState", "invalid clip type '%d'.", type);
00515 break;
00516 }
00517 }
00518
00519
00520 void TGLClipSet::SetClipState(EClipType type, const Double_t data[6])
00521 {
00522
00523
00524
00525
00526
00527
00528
00529 switch (type) {
00530 case kClipNone: {
00531 break;
00532 }
00533 case kClipPlane: {
00534 TGLPlane newPlane(-data[0], -data[1], -data[2], -data[3]);
00535 fClipPlane->Set(newPlane);
00536 break;
00537 }
00538 case kClipBox: {
00539
00540
00541 const TGLBoundingBox & currentBox = fClipBox->BoundingBox();
00542 TGLVector3 shift(data[0] - currentBox.Center().X(),
00543 data[1] - currentBox.Center().Y(),
00544 data[2] - currentBox.Center().Z());
00545 fClipBox->Translate(shift);
00546
00547
00548 TGLVector3 currentScale = fClipBox->GetScale();
00549 TGLVector3 newScale(data[3] / currentBox.Extents().X() * currentScale.X(),
00550 data[4] / currentBox.Extents().Y() * currentScale.Y(),
00551 data[5] / currentBox.Extents().Z() * currentScale.Z());
00552
00553 fClipBox->Scale(newScale);
00554 break;
00555 }
00556 }
00557 }
00558
00559
00560 EClipType TGLClipSet::GetClipType() const
00561 {
00562
00563
00564
00565 EClipType type;
00566 if (fCurrentClip == 0) {
00567 type = kClipNone;
00568 } else if (fCurrentClip == fClipPlane) {
00569 type = kClipPlane;
00570 } else if (fCurrentClip == fClipBox) {
00571 type = kClipBox;
00572 } else {
00573 Error("TGLClipSet::GetClipType" , "Unknown clip type");
00574 type = kClipNone;
00575 }
00576 return type;
00577 }
00578
00579
00580 void TGLClipSet::SetClipType(EClipType type)
00581 {
00582
00583
00584
00585 switch (type) {
00586 case kClipNone: {
00587 fCurrentClip = 0;
00588 break;
00589 }
00590 case kClipPlane: {
00591 fCurrentClip = fClipPlane;
00592 break;
00593 }
00594 case kClipBox: {
00595 fCurrentClip = fClipBox;
00596 break;
00597 }
00598 default: {
00599 Error("TGLClipSet::SetClipType" , "Unknown clip type");
00600 break;
00601 }
00602 }
00603 fManip->SetPShape(fCurrentClip);
00604 }