48 TGLScene::TSceneInfo::TSceneInfo(TGLViewerBase* view, TGLScene* scene) :
49 TGLSceneInfo (view, scene),
60 TGLScene::TSceneInfo::~TSceneInfo()
68 void TGLScene::TSceneInfo::ClearDrawElementVec(DrawElementVec_t& vec,
71 if (vec.capacity() > (size_t) maxSize) {
73 foo.reserve((
size_t) maxSize);
84 void TGLScene::TSceneInfo::ClearDrawElementPtrVec(DrawElementPtrVec_t& vec,
87 if (vec.capacity() > (size_t) maxSize) {
88 DrawElementPtrVec_t foo;
89 foo.reserve((
size_t) maxSize);
101 void TGLScene::TSceneInfo::ClearAfterRebuild()
103 Int_t maxSize = (Int_t) fShapesOfInterest.size();
105 ClearDrawElementVec(fVisibleElements, maxSize);
113 void TGLScene::TSceneInfo::ClearAfterUpdate()
115 Int_t maxSize = (Int_t) fShapesOfInterest.size();
117 ClearDrawElementPtrVec(fOpaqueElements, maxSize);
118 ClearDrawElementPtrVec(fTranspElements, maxSize);
119 ClearDrawElementPtrVec(fSelOpaqueElements, maxSize);
120 ClearDrawElementPtrVec(fSelTranspElements, maxSize);
128 void TGLScene::TSceneInfo::Lodify(TGLRnrCtx& ctx)
130 for (DrawElementVec_i i = fVisibleElements.begin(); i != fVisibleElements.end(); ++i)
131 i->fPhysical->QuantizeShapeLOD(i->fPixelLOD, ctx.CombiLOD(), i->fFinalLOD);
138 void TGLScene::TSceneInfo::PreDraw()
140 if (fMinorStamp < fScene->GetMinorStamp())
142 fOpaqueElements.clear();
143 fTranspElements.clear();
144 fSelOpaqueElements.clear();
145 fSelTranspElements.clear();
147 for (DrawElementVec_i i = fVisibleElements.begin(); i != fVisibleElements.end(); ++i)
149 if (i->fPhysical->IsSelected())
151 if (i->fPhysical->IsTransparent())
152 fSelTranspElements.push_back(&*i);
154 fSelOpaqueElements.push_back(&*i);
156 if (i->fPhysical->IsTransparent())
157 fTranspElements.push_back(&*i);
159 fOpaqueElements.push_back(&*i);
162 fMinorStamp = fScene->GetMinorStamp();
169 void TGLScene::TSceneInfo::PostDraw()
176 void TGLScene::TSceneInfo::ResetDrawStats()
187 void TGLScene::TSceneInfo::UpdateDrawStats(
const TGLPhysicalShape& shape,
191 if (shape.IsTransparent()) {
197 if (lod == TGLRnrCtx::kLODPixel) {
204 TClass* logIsA = shape.GetLogical()->IsA();
205 std::map<TClass*, UInt_t>::iterator it = fByShapeCnt.find(logIsA);
206 if (it == fByShapeCnt.end()) {
208 it = fByShapeCnt.insert(std::make_pair(logIsA, 0u)).first;
218 void TGLScene::TSceneInfo::DumpDrawStats()
224 out += Form(
"Drew scene (%s / %i LOD) - %i (Op %i Trans %i) %i pixel\n",
225 TGLRnrCtx::StyleName(LastStyle()), LastLOD(),
226 fOpaqueCnt + fTranspCnt, fOpaqueCnt, fTranspCnt, fAsPixelCnt);
227 out += Form(
"\tInner phys nums: physicals=%d, of_interest=%lu, visible=%lu, op=%lu, trans=%lu",
228 ((TGLScene*)fScene)->GetMaxPhysicalID(),
229 (ULong_t)fShapesOfInterest.size(), (ULong_t)fVisibleElements.size(),
230 (ULong_t)fOpaqueElements.size(), (ULong_t)fTranspElements.size());
235 out +=
"\n\tStatistics by shape:\n";
236 std::map<TClass*, UInt_t>::const_iterator it = fByShapeCnt.begin();
237 while (it != fByShapeCnt.end()) {
238 out += Form(
"\t%-20s %u\n", it->first->GetName(), it->second);
242 Info(
"TGLScene::DumpDrawStats()",
"%s",out.Data());
278 TGLScene::TGLScene() :
281 fInSmartRefresh(kFALSE),
282 fLastPointSizeScale (0),
283 fLastLineWidthScale (0)
286 TGLLogicalShape::SetEnvDefaults();
292 TGLScene::~TGLScene()
294 TakeLock(kModifyLock);
295 ReleaseGLCtxIdentity();
299 fGLCtxIdentity->ReleaseClient();
300 ReleaseLock(kModifyLock);
311 void TGLScene::ReleaseGLCtxIdentity()
313 if (fGLCtxIdentity == 0)
return;
315 if (fGLCtxIdentity->IsValid())
318 LogicalShapeMapIt_t lit = fLogicalShapes.begin();
319 while (lit != fLogicalShapes.end()) {
320 lit->second->DLCachePurge();
327 LogicalShapeMapIt_t lit = fLogicalShapes.begin();
328 while (lit != fLogicalShapes.end()) {
329 lit->second->DLCacheDrop();
333 fGLCtxIdentity->ReleaseClient();
347 TGLScene::TSceneInfo* TGLScene::CreateSceneInfo(TGLViewerBase* view)
349 return new TSceneInfo(view,
this);
356 inline Bool_t TGLScene::ComparePhysicalVolumes(
const TGLPhysicalShape* shape1,
357 const TGLPhysicalShape* shape2)
359 return (shape1->BoundingBox().Volume() > shape2->BoundingBox().Volume());
366 inline Bool_t TGLScene::ComparePhysicalDiagonals(
const TGLPhysicalShape* shape1,
367 const TGLPhysicalShape* shape2)
369 return (shape1->BoundingBox().Diagonal() > shape2->BoundingBox().Diagonal());
382 void TGLScene::RebuildSceneInfo(TGLRnrCtx& rnrCtx)
384 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
385 if (sinfo == 0 || sinfo->GetScene() !=
this) {
386 Error(
"TGLScene::RebuildSceneInfo",
"Scene mismatch.");
390 TGLSceneBase::RebuildSceneInfo(rnrCtx);
392 if (sinfo->fShapesOfInterest.capacity() > fPhysicalShapes.size()) {
394 foo.reserve(fPhysicalShapes.size());
395 sinfo->fShapesOfInterest.swap(foo);
397 sinfo->fShapesOfInterest.clear();
400 PhysicalShapeMapIt_t pit = fPhysicalShapes.begin();
401 while (pit != fPhysicalShapes.end())
403 TGLPhysicalShape * pshp = pit->second;
404 const TGLLogicalShape * lshp = pshp->GetLogical();
405 if (rnrCtx.GetCamera()->OfInterest(pshp->BoundingBox(),
406 lshp->IgnoreSizeForOfInterest()))
408 sinfo->fShapesOfInterest.push_back(pshp);
413 std::sort(sinfo->fShapesOfInterest.begin(), sinfo->fShapesOfInterest.end(),
414 TGLScene::ComparePhysicalDiagonals);
416 sinfo->ClearAfterRebuild();
426 void TGLScene::UpdateSceneInfo(TGLRnrCtx& rnrCtx)
428 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
429 if (sinfo == 0 || sinfo->GetScene() !=
this) {
430 Error(
"TGLScene::UpdateSceneInfo",
"Scene mismatch.");
436 TGLSceneBase::UpdateSceneInfo(rnrCtx);
438 if (!sinfo->IsVisible())
441 sinfo->fVisibleElements.clear();
445 Int_t checkCount = 0;
446 Bool_t timerp = rnrCtx.IsStopwatchRunning();
447 sinfo->ResetUpdateTimeouted();
449 for (ShapeVec_i phys=sinfo->fShapesOfInterest.begin();
450 phys!=sinfo->fShapesOfInterest.end();
451 ++phys, ++checkCount)
453 const TGLPhysicalShape * drawShape = *phys;
460 Bool_t drawNeeded = kTRUE;
465 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
468 std::vector<TGLPlane>::iterator pi = sinfo->ClipPlanes().begin();
469 while (pi != sinfo->ClipPlanes().end())
471 if (drawShape->BoundingBox().Overlap(*pi) == Rgl::kOutside)
479 else if (sinfo->ClipMode() == TGLSceneInfo::kClipInside)
482 std::vector<TGLPlane>::iterator pi = sinfo->ClipPlanes().begin();
484 while (pi != sinfo->ClipPlanes().end())
486 Rgl::EOverlap ovlp = drawShape->BoundingBox().Overlap(*pi);
487 if (ovlp == Rgl::kOutside)
489 else if (ovlp == Rgl::kInside)
493 if (cnt == sinfo->ClipPlanes().size())
501 std::vector<TGLPlane>::iterator pi = sinfo->FrustumPlanes().begin();
502 while (pi != sinfo->FrustumPlanes().end())
504 if (drawShape->BoundingBox().Overlap(*pi) == Rgl::kOutside)
516 DrawElement_t de(drawShape);
517 drawShape->CalculateShapeLOD(rnrCtx, de.fPixelSize, de.fPixelLOD);
518 sinfo->fVisibleElements.push_back(de);
523 if (timerp && (checkCount % 5000) == 0 && rnrCtx.HasStopwatchTimedOut())
525 sinfo->UpdateTimeouted();
526 if (rnrCtx.ViewerLOD() == TGLRnrCtx::kLODHigh)
527 Warning(
"TGLScene::UpdateSceneInfo",
528 "Timeout reached, not all elements processed.");
533 sinfo->ClearAfterUpdate();
544 void TGLScene::LodifySceneInfo(TGLRnrCtx& rnrCtx)
546 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
547 if (sinfo == 0 || sinfo->GetScene() !=
this) {
548 Error(
"TGLScene::LodifySceneInfo",
"Scene mismatch.");
552 TGLSceneBase::LodifySceneInfo(rnrCtx);
554 sinfo->Lodify(rnrCtx);
568 void TGLScene::PreDraw(TGLRnrCtx& rnrCtx)
570 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
571 if (sinfo == 0 || sinfo->GetScene() !=
this) {
572 TGLSceneInfo* si = rnrCtx.GetSceneInfo();
573 Error(
"TGLScene::PreDraw",
"%s", Form(
"SceneInfo mismatch (0x%lx, '%s').",
574 (ULong_t)si, si ? si->IsA()->GetName() :
"<>"));
579 TGLSceneBase::PreDraw(rnrCtx);
581 TGLContextIdentity* cid = rnrCtx.GetGLCtxIdentity();
582 if (cid != fGLCtxIdentity)
584 ReleaseGLCtxIdentity();
585 fGLCtxIdentity = cid;
586 fGLCtxIdentity->AddClientRef();
590 if (fLastPointSizeScale != TGLUtil::GetPointSizeScale() ||
591 fLastLineWidthScale != TGLUtil::GetLineWidthScale())
594 LogicalShapeMapIt_t lit = fLogicalShapes.begin();
595 while (lit != fLogicalShapes.end()) {
596 lit->second->DLCacheClear();
601 fLastPointSizeScale = TGLUtil::GetPointSizeScale();
602 fLastLineWidthScale = TGLUtil::GetLineWidthScale();
607 sinfo->ResetDrawStats();
613 void TGLScene::RenderOpaque(TGLRnrCtx& rnrCtx)
615 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
616 if (!sinfo->fOpaqueElements.empty())
617 RenderAllPasses(rnrCtx, sinfo->fOpaqueElements, kTRUE);
623 void TGLScene::RenderTransp(TGLRnrCtx& rnrCtx)
625 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
626 if (!sinfo->fTranspElements.empty())
627 RenderAllPasses(rnrCtx, sinfo->fTranspElements, kTRUE);
633 void TGLScene::RenderSelOpaque(TGLRnrCtx& rnrCtx)
635 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
636 if ( ! sinfo->fSelOpaqueElements.empty())
637 RenderAllPasses(rnrCtx, sinfo->fSelOpaqueElements, kFALSE);
643 void TGLScene::RenderSelTransp(TGLRnrCtx& rnrCtx)
645 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
646 if (!sinfo->fSelTranspElements.empty())
647 RenderAllPasses(rnrCtx, sinfo->fSelTranspElements, kFALSE);
653 void TGLScene::RenderSelOpaqueForHighlight(TGLRnrCtx& rnrCtx)
655 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
656 if ( ! sinfo->fSelOpaqueElements.empty())
657 RenderHighlight(rnrCtx, sinfo->fSelOpaqueElements);
663 void TGLScene::RenderSelTranspForHighlight(TGLRnrCtx& rnrCtx)
665 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
666 if (!sinfo->fSelTranspElements.empty())
667 RenderHighlight(rnrCtx, sinfo->fSelTranspElements);
672 void TGLScene::RenderHighlight(TGLRnrCtx& rnrCtx,
673 DrawElementPtrVec_t& elVec)
675 DrawElementPtrVec_t svec(1);
677 glEnable(GL_STENCIL_TEST);
678 for (DrawElementPtrVec_i i = elVec.begin(); i != elVec.end(); ++i)
682 glStencilFunc(GL_ALWAYS, 0x1, 0x1);
683 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
684 glClear(GL_STENCIL_BUFFER_BIT);
686 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
688 RenderAllPasses(rnrCtx, svec, kFALSE);
690 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
692 glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
693 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
695 rnrCtx.SetHighlightOutline(kTRUE);
696 RenderAllPasses(rnrCtx, svec, kFALSE);
697 rnrCtx.SetHighlightOutline(kFALSE);
699 glDisable(GL_STENCIL_TEST);
707 void TGLScene::PostDraw(TGLRnrCtx& rnrCtx)
709 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
712 sinfo->DumpDrawStats();
716 TGLSceneBase::PostDraw(rnrCtx);
725 void TGLScene::RenderAllPasses(TGLRnrCtx& rnrCtx,
726 DrawElementPtrVec_t& elVec,
727 Bool_t check_timeout)
729 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
732 Short_t sceneStyle = rnrCtx.SceneStyle();
738 rnrPass[0] = rnrPass[1] = TGLRnrCtx::kPassUndef;
742 case TGLRnrCtx::kFill:
743 case TGLRnrCtx::kOutline:
745 glEnable(GL_LIGHTING);
746 if (sinfo->ShouldClip())
749 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
750 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
751 glDisable(GL_CULL_FACE);
755 if (sceneStyle == TGLRnrCtx::kOutline && ! (rnrCtx.Selection() || rnrCtx.Highlight()))
758 rnrPass[0] = TGLRnrCtx::kPassOutlineFill;
759 rnrPass[1] = TGLRnrCtx::kPassOutlineLine;
763 rnrPass[0] = TGLRnrCtx::kPassFill;
767 case TGLRnrCtx::kWireFrame:
769 rnrPass[0] = TGLRnrCtx::kPassWireFrame;
770 glDisable(GL_LIGHTING);
771 glDisable(GL_CULL_FACE);
772 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
781 for (Int_t i = 0; i < reqPasses; ++i)
786 Short_t pass = rnrPass[i];
787 rnrCtx.SetDrawPass(pass);
789 if (pass == TGLRnrCtx::kPassOutlineFill)
792 glEnable(GL_POLYGON_OFFSET_FILL);
793 glPolygonOffset(0.5f, 0.5f);
795 else if (pass == TGLRnrCtx::kPassOutlineLine)
798 TGLUtil::LineWidth(rnrCtx.SceneOLLineW());
799 glDisable(GL_POLYGON_OFFSET_FILL);
800 glDisable(GL_LIGHTING);
808 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
810 else if (pass == TGLRnrCtx::kPassWireFrame)
812 TGLUtil::LineWidth(rnrCtx.SceneWFLineW());
816 if ( ! sinfo->ShouldClip())
818 RenderElements(rnrCtx, elVec, check_timeout);
823 TGLPlaneSet_t & planeSet = sinfo->ClipPlanes();
827 Info(
"TGLScene::RenderAllPasses()",
828 "%ld active clip planes", (Long_t)planeSet.size());
832 glGetIntegerv(GL_MAX_CLIP_PLANES, &maxGLPlanes);
833 UInt_t maxPlanes = maxGLPlanes;
835 if (planeSet.size() < maxPlanes) {
836 maxPlanes = planeSet.size();
839 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
843 for (UInt_t ii=0; ii<maxPlanes; ii++) {
844 glClipPlane(GL_CLIP_PLANE0+ii, planeSet[ii].CArr());
845 glEnable(GL_CLIP_PLANE0+ii);
850 RenderElements(rnrCtx, elVec, check_timeout);
857 std::vector<TGLPlane> activePlanes;
858 for (planeInd=0; planeInd<maxPlanes; planeInd++)
860 activePlanes.push_back(planeSet[planeInd]);
861 TGLPlane& p = activePlanes.back();
863 glClipPlane(GL_CLIP_PLANE0+planeInd, p.CArr());
864 glEnable(GL_CLIP_PLANE0+planeInd);
868 RenderElements(rnrCtx, elVec, check_timeout, &activePlanes);
871 glClipPlane(GL_CLIP_PLANE0+planeInd, p.CArr());
875 for (planeInd=0; planeInd<maxPlanes; planeInd++) {
876 glDisable(GL_CLIP_PLANE0+planeInd);
882 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
883 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
884 glEnable(GL_CULL_FACE);
885 glEnable(GL_LIGHTING);
893 void TGLScene::RenderElements(TGLRnrCtx& rnrCtx,
894 DrawElementPtrVec_t& elVec,
895 Bool_t check_timeout,
896 const TGLPlaneSet_t* clipPlanes)
898 TSceneInfo* sinfo =
dynamic_cast<TSceneInfo*
>(rnrCtx.GetSceneInfo());
903 for (DrawElementPtrVec_i i = elVec.begin(); i != elVec.end(); ++i)
905 const TGLPhysicalShape * drawShape = (*i)->fPhysical;
907 Bool_t drawNeeded = kTRUE;
910 if (clipPlanes && IsOutside(drawShape->BoundingBox(), *clipPlanes))
916 rnrCtx.SetShapeLOD((*i)->fFinalLOD);
917 rnrCtx.SetShapePixSize((*i)->fPixelSize);
918 glPushName(drawShape->ID());
919 drawShape->Draw(rnrCtx);
922 sinfo->UpdateDrawStats(*drawShape, rnrCtx.ShapeLOD());
927 if (check_timeout && (drawCount % 2000) == 0 &&
928 rnrCtx.HasStopwatchTimedOut())
930 if (rnrCtx.ViewerLOD() == TGLRnrCtx::kLODHigh)
931 Warning(
"TGLScene::RenderElements",
932 "Timeout reached, not all elements rendered.");
950 Bool_t TGLScene::ResolveSelectRecord(TGLSelectRecord& rec, Int_t curIdx)
952 if (curIdx >= rec.GetN())
955 TGLPhysicalShape* pshp = FindPhysical(rec.GetItem(curIdx));
958 rec.SetTransparent(pshp->IsTransparent());
959 rec.SetPhysShape(pshp);
960 rec.SetLogShape(const_cast<TGLLogicalShape*>(pshp->GetLogical()));
961 rec.SetObject(pshp->GetLogical()->GetExternal());
977 void TGLScene::CalcBoundingBox()
const
979 Double_t xMin, xMax, yMin, yMax, zMin, zMax;
980 xMin = xMax = yMin = yMax = zMin = zMax = 0.0;
981 PhysicalShapeMapCIt_t physicalShapeIt = fPhysicalShapes.begin();
982 const TGLPhysicalShape * physicalShape;
983 while (physicalShapeIt != fPhysicalShapes.end())
985 physicalShape = physicalShapeIt->second;
991 const TGLBoundingBox& box = physicalShape->BoundingBox();
992 if (physicalShapeIt == fPhysicalShapes.begin()) {
993 xMin = box.XMin(); xMax = box.XMax();
994 yMin = box.YMin(); yMax = box.YMax();
995 zMin = box.ZMin(); zMax = box.ZMax();
997 if (box.XMin() < xMin) { xMin = box.XMin(); }
998 if (box.XMax() > xMax) { xMax = box.XMax(); }
999 if (box.YMin() < yMin) { yMin = box.YMin(); }
1000 if (box.YMax() > yMax) { yMax = box.YMax(); }
1001 if (box.ZMin() < zMin) { zMin = box.ZMin(); }
1002 if (box.ZMax() > zMax) { zMax = box.ZMax(); }
1006 fBoundingBox.SetAligned(TGLVertex3(xMin,yMin,zMin), TGLVertex3(xMax,yMax,zMax));
1007 fBoundingBoxValid = kTRUE;
1018 void TGLScene::AdoptLogical(TGLLogicalShape& shape)
1020 if (fLock != kModifyLock) {
1021 Error(
"TGLScene::AdoptLogical",
"expected ModifyLock");
1025 shape.fScene =
this;
1026 fLogicalShapes.insert(LogicalShapeMapValueType_t(shape.ID(), &shape));
1036 Bool_t TGLScene::DestroyLogical(TObject* logid, Bool_t mustFind)
1038 if (fLock != kModifyLock) {
1039 Error(
"TGLScene::DestroyLogical",
"expected ModifyLock");
1043 LogicalShapeMapIt_t lit = fLogicalShapes.find(logid);
1045 if (lit == fLogicalShapes.end()) {
1047 Error(
"TGLScene::DestroyLogical",
"logical not found in map.");
1051 TGLLogicalShape * logical = lit->second;
1053 while ((phid = logical->UnrefFirstPhysical()) != 0)
1055 PhysicalShapeMapIt_t pit = fPhysicalShapes.find(phid);
1056 if (pit != fPhysicalShapes.end())
1057 DestroyPhysicalInternal(pit);
1059 Warning(
"TGLScene::DestroyLogical",
"an attached physical not found in map.");
1061 assert(logical->Ref() == 0);
1062 fLogicalShapes.erase(lit);
1064 InvalidateBoundingBox();
1073 Int_t TGLScene::DestroyLogicals()
1075 if (fLock != kModifyLock) {
1076 Error(
"TGLScene::DestroyLogicals",
"expected ModifyLock");
1081 LogicalShapeMapIt_t logicalShapeIt = fLogicalShapes.begin();
1082 const TGLLogicalShape * logicalShape;
1083 while (logicalShapeIt != fLogicalShapes.end()) {
1084 logicalShape = logicalShapeIt->second;
1086 if (logicalShape->Ref() == 0) {
1087 fLogicalShapes.erase(logicalShapeIt++);
1088 delete logicalShape;
1107 TGLLogicalShape * TGLScene::FindLogical(TObject* logid)
const
1109 LogicalShapeMapCIt_t lit = fLogicalShapes.find(logid);
1110 if (lit != fLogicalShapes.end()) {
1113 if (fInSmartRefresh)
1114 return FindLogicalSmartRefresh(logid);
1129 void TGLScene::AdoptPhysical(TGLPhysicalShape & shape)
1131 if (fLock != kModifyLock) {
1132 Error(
"TGLScene::AdoptPhysical",
"expected ModifyLock");
1136 assert(fPhysicalShapes.find(shape.ID()) == fPhysicalShapes.end());
1138 fPhysicalShapes.insert(PhysicalShapeMapValueType_t(shape.ID(), &shape));
1140 InvalidateBoundingBox();
1149 void TGLScene::DestroyPhysicalInternal(PhysicalShapeMapIt_t pit)
1152 fPhysicalShapes.erase(pit);
1159 Bool_t TGLScene::DestroyPhysical(UInt_t phid)
1161 if (fLock != kModifyLock) {
1162 Error(
"TGLScene::DestroyPhysical",
"expected ModifyLock.");
1166 PhysicalShapeMapIt_t pit = fPhysicalShapes.find(phid);
1168 if (pit == fPhysicalShapes.end()) {
1169 Error(
"TGLScene::DestroyPhysical::UpdatePhysical",
"physical not found.");
1173 DestroyPhysicalInternal(pit);
1175 InvalidateBoundingBox();
1183 Int_t TGLScene::DestroyPhysicals()
1185 if (fLock != kModifyLock) {
1186 Error(
"TGLScene::DestroyPhysicals",
"expected ModifyLock");
1194 LogicalShapeMapIt_t lit = fLogicalShapes.begin();
1195 while (lit != fLogicalShapes.end())
1197 TGLLogicalShape *lshp = lit->second;
1198 if (lshp && lshp->Ref() != 0)
1200 count += lshp->Ref();
1201 lshp->DestroyPhysicals();
1206 assert (count == fPhysicalShapes.size());
1207 fPhysicalShapes.clear();
1210 InvalidateBoundingBox();
1221 TGLPhysicalShape* TGLScene::FindPhysical(UInt_t phid)
const
1223 PhysicalShapeMapCIt_t pit = fPhysicalShapes.find(phid);
1224 return (pit != fPhysicalShapes.end()) ? pit->second : 0;
1231 UInt_t TGLScene::GetMaxPhysicalID()
1233 if (fPhysicalShapes.empty())
return 0;
1234 return (--fPhysicalShapes.end())->first;
1245 Bool_t TGLScene::BeginUpdate()
1247 Bool_t ok = TakeLock(kModifyLock);
1265 void TGLScene::EndUpdate(Bool_t minorChange, Bool_t sceneChanged, Bool_t updateViewers)
1273 ReleaseLock(kModifyLock);
1276 TagViewersChanged();
1283 void TGLScene::UpdateLogical(TObject* logid)
1285 if (fLock != kModifyLock) {
1286 Error(
"TGLScene::UpdateLogical",
"expected ModifyLock");
1290 TGLLogicalShape* log = FindLogical(logid);
1293 Error(
"TGLScene::UpdateLogical",
"logical not found");
1297 log->DLCacheClear();
1298 log->UpdateBoundingBox();
1304 void TGLScene::UpdatePhysical(UInt_t phid, Double_t* trans, UChar_t* col)
1306 if (fLock != kModifyLock) {
1307 Error(
"TGLScene::UpdatePhysical",
"expected ModifyLock");
1311 TGLPhysicalShape* phys = FindPhysical(phid);
1314 Error(
"TGLScene::UpdatePhysical",
"physical not found");
1318 if (trans) phys->SetTransform(trans);
1319 if (col) phys->SetDiffuseColor(col);
1325 void TGLScene::UpdatePhysical(UInt_t phid, Double_t* trans, Color_t cidx, UChar_t transp)
1327 if (fLock != kModifyLock) {
1328 Error(
"TGLScene::UpdatePhysical",
"expected ModifyLock");
1332 TGLPhysicalShape* phys = FindPhysical(phid);
1335 Error(
"TGLScene::UpdatePhysical",
"physical not found");
1340 phys->SetTransform(trans);
1343 RGBAFromColorIdx(rgba, cidx, transp);
1344 phys->SetDiffuseColor(rgba);
1352 void TGLScene::UpdatePhysioLogical(TObject* logid, Double_t* trans, UChar_t* col)
1354 if (fLock != kModifyLock) {
1355 Error(
"TGLScene::UpdatePhysioLogical",
"expected ModifyLock");
1359 TGLLogicalShape* log = FindLogical(logid);
1362 Error(
"TGLScene::UpdatePhysioLogical",
"logical not found");
1366 if (log->Ref() != 1) {
1367 Warning(
"TGLScene::UpdatePhysioLogical",
"expecting a single physical (%d).", log->Ref());
1370 TGLPhysicalShape* phys = log->fFirstPhysical;
1371 if (trans) phys->SetTransform(trans);
1372 if (col) phys->SetDiffuseColor(col);
1379 void TGLScene::UpdatePhysioLogical(TObject* logid, Double_t* trans, Color_t cidx, UChar_t transp)
1381 if (fLock != kModifyLock) {
1382 Error(
"TGLScene::UpdatePhysioLogical",
"expected ModifyLock");
1386 TGLLogicalShape* log = FindLogical(logid);
1389 Error(
"TGLScene::UpdatePhysioLogical",
"logical not found");
1393 if (log->Ref() != 1) {
1394 Warning(
"TGLScene::UpdatePhysioLogical",
"expecting a single physical (%d).", log->Ref());
1397 TGLPhysicalShape* phys = log->fFirstPhysical;
1399 phys->SetTransform(trans);
1402 RGBAFromColorIdx(rgba, cidx, transp);
1403 phys->SetDiffuseColor(rgba);
1416 UInt_t TGLScene::BeginSmartRefresh()
1418 fSmartRefreshCache.swap(fLogicalShapes);
1421 LogicalShapeMapIt_t i = fSmartRefreshCache.begin();
1422 while (i != fSmartRefreshCache.end()) {
1423 if (i->second->KeepDuringSmartRefresh() == kFALSE) {
1424 LogicalShapeMapIt_t j = i++;
1426 fSmartRefreshCache.erase(j);
1432 fInSmartRefresh = kTRUE;
1439 void TGLScene::EndSmartRefresh()
1441 fInSmartRefresh = kFALSE;
1443 LogicalShapeMapIt_t i = fSmartRefreshCache.begin();
1444 while (i != fSmartRefreshCache.end()) {
1448 fSmartRefreshCache.clear();
1455 TGLLogicalShape * TGLScene::FindLogicalSmartRefresh(TObject* ID)
const
1457 LogicalShapeMapIt_t it = fSmartRefreshCache.find(ID);
1458 if (it != fSmartRefreshCache.end())
1460 TGLLogicalShape* l_shape = it->second;
1461 fSmartRefreshCache.erase(it);
1462 if (l_shape->IsA() != TGLObject::GetGLRenderer(ID->IsA()))
1464 Warning(
"TGLScene::FindLogicalSmartRefresh",
"Wrong renderer-type found in cache.");
1471 LogicalShapeMap_t* lsm =
const_cast<LogicalShapeMap_t*
>(&fLogicalShapes);
1472 lsm->insert(LogicalShapeMapValueType_t(l_shape->ID(), l_shape));
1473 l_shape->DLCacheClear();
1474 l_shape->UpdateBoundingBox();
1491 UInt_t TGLScene::SizeOfScene()
const
1493 UInt_t size =
sizeof(*this);
1495 printf(
"Size: Scene Only %u\n", size);
1497 LogicalShapeMapCIt_t logicalShapeIt = fLogicalShapes.begin();
1498 const TGLLogicalShape * logicalShape;
1499 while (logicalShapeIt != fLogicalShapes.end()) {
1500 logicalShape = logicalShapeIt->second;
1501 size +=
sizeof(*logicalShape);
1505 printf(
"Size: Scene + Logical Shapes %u\n", size);
1507 PhysicalShapeMapCIt_t physicalShapeIt = fPhysicalShapes.begin();
1508 const TGLPhysicalShape * physicalShape;
1509 while (physicalShapeIt != fPhysicalShapes.end()) {
1510 physicalShape = physicalShapeIt->second;
1511 size +=
sizeof(*physicalShape);
1515 printf(
"Size: Scene + Logical Shapes + Physical Shapes %u\n", size);
1523 void TGLScene::DumpMapSizes()
const
1525 printf(
"Scene: %u Logicals / %u Physicals\n",
1526 (UInt_t) fLogicalShapes.size(), (UInt_t) fPhysicalShapes.size());
1532 void TGLScene::RGBAFromColorIdx(Float_t rgba[4], Color_t ci, Char_t transp)
1534 TColor* c = gROOT->GetColor(ci);
1535 if(c) c->GetRGB(rgba[0], rgba[1], rgba[2]);
1536 else rgba[0] = rgba[1] = rgba[2] = 0.5;
1537 rgba[3] = 1.0f - transp/100.0f;
1543 Bool_t TGLScene::IsOutside(
const TGLBoundingBox & box,
1544 const TGLPlaneSet_t & planes)
1546 for (TGLPlaneSet_ci p=planes.begin(); p!=planes.end(); ++p)
1547 if (box.Overlap(*p) == Rgl::kOutside)