00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "TEveTrans.h"
00019 #include "TEveViewer.h"
00020 #include "TEveManager.h"
00021 #include "TEveUtil.h"
00022
00023
00024 #include "TROOT.h"
00025 #include "TBuffer3D.h"
00026 #include "TBuffer3DTypes.h"
00027 #include "TVirtualViewer3D.h"
00028 #include "TColor.h"
00029 #include "TGLScenePad.h"
00030 #include "TGLPhysicalShape.h"
00031 #include "TGLSelectRecord.h"
00032 #include "TGLViewer.h"
00033 #include "TGLWidget.h"
00034
00035 #include "TGeoShape.h"
00036 #include "TGeoVolume.h"
00037 #include "TGeoNode.h"
00038 #include "TGeoShapeAssembly.h"
00039 #include "TGeoCompositeShape.h"
00040 #include "TGeoBoolNode.h"
00041 #include "TGeoManager.h"
00042 #include "TGeoMatrix.h"
00043 #include "TVirtualGeoPainter.h"
00044
00045 #include "Fireworks/Core/interface/FWGeoTopNode.h"
00046 #include "Fireworks/Core/src/FWGeoTopNodeScene.h"
00047 #include "Fireworks/Core/src/FWPopupMenu.cc"
00048 #include "Fireworks/Core/interface/FWViewType.h"
00049 #include "Fireworks/Core/interface/fwLog.h"
00050
00051 TGLViewer* FWGeoTopNode::s_pickedViewer = 0;
00052 TGLVector3 FWGeoTopNode::s_pickedCamera3DCenter;
00053
00054 UInt_t FWGeoTopNode::phyID(int tableIdx)
00055 {
00056 return UInt_t(tableIdx + 2);
00057
00058 }
00059
00060 int FWGeoTopNode::tableIdx(TGLPhysicalShape* ps)
00061 {
00062 return ps->ID() - 2;
00063 }
00064
00065 void FWGeoTopNode::EraseFromSet(std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id)
00066 {
00067 sset.erase(id);
00068 SetStateOf(id);
00069 }
00070
00071
00072 void FWGeoTopNode::ClearSet(std::set<TGLPhysicalShape*>& sset)
00073 {
00074 while (!sset.empty())
00075 {
00076 TGLPhysicalShape *id = *sset.begin();
00077 sset.erase(id);
00078 SetStateOf(id);
00079 }
00080 }
00081
00082 void FWGeoTopNode::SetStateOf(TGLPhysicalShape* id)
00083 {
00084 FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIdx(id));
00085
00086 if (fSted.find(id) != fSted.end())
00087 {
00088 id->Select(1);
00089 data.setBit(FWGeometryTableManagerBase::kSelected);
00090 }
00091 else if (fHted.find(id) != fHted.end())
00092 {
00093 id->Select(3);
00094 data.setBit(FWGeometryTableManagerBase::kHighlighted);
00095 }
00096 else
00097 {
00098 id->Select(0);
00099 data.resetBit(FWGeometryTableManagerBase::kHighlighted);
00100 data.resetBit(FWGeometryTableManagerBase::kSelected);
00101 }
00102
00103 }
00104
00105
00106 void FWGeoTopNode::ProcessSelection(TGLSelectRecord& rec, std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id)
00107 {
00108
00109
00110 m_scene->BeginUpdate();
00111
00112 if (sset.empty())
00113 {
00114 if (id)
00115 {
00116 sset.insert(id);
00117 rec.SetSecSelResult(TGLSelectRecord::kEnteringSelection);
00118 }
00119 }
00120 else
00121 {
00122 if (id)
00123 {
00124 if (rec.GetMultiple())
00125 {
00126 if (sset.find(id) == sset.end())
00127 {
00128 sset.insert(id);
00129 rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00130 }
00131 else
00132 {
00133 EraseFromSet(sset, id);
00134 if (sset.empty())
00135 rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
00136 else
00137 rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00138 }
00139 }
00140 else
00141 {
00142 if (sset.size() != 1 || sset.find(id) == sset.end())
00143 {
00144 ClearSet(sset);
00145 sset.insert(id);
00146 rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00147 }
00148 }
00149 }
00150 else
00151 {
00152 if (!rec.GetMultiple())
00153 {
00154 ClearSet(sset);
00155 rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
00156 }
00157 }
00158 }
00159
00160 if (id)
00161 {
00162 SetStateOf(id);
00163 }
00164
00165 if (rec.GetSecSelResult() != TGLSelectRecord::kNone)
00166 {
00167 m_scene->EndUpdate(kTRUE, kFALSE, kTRUE);
00168 gEve->Redraw3D();
00169
00170 tableManager()->dataChanged();
00171 }
00172 else
00173 {
00174 m_scene->EndUpdate(kFALSE, kFALSE, kFALSE);
00175 }
00176 }
00177
00178
00179 bool FWGeoTopNode::selectPhysicalFromTable( int tableIndex)
00180 {
00181
00182
00183 TGLPhysicalShape* ps = m_scene->FindPhysical(phyID(tableIndex));
00184 if (ps) {
00185 fSted.insert(ps);
00186 ps->Select(1);
00187
00188 return true;
00189 }
00190 else if ( tableManager()->refEntries().at(tableIndex).testBit(FWGeometryTableManagerBase::kVisNodeSelf));
00191 {
00192 fwLog(fwlog::kInfo) << "Selected entry not drawn in GL viewer. \n" ;
00193 return false;
00194 }
00195 }
00196
00197
00198 void FWGeoTopNode::printSelected()
00199 {
00200 for (std::set<TGLPhysicalShape*>::iterator it = fSted.begin(); it != fSted.end(); ++it)
00201 {
00202 printf("FWGeoTopNode::printSelected %s \n", tableManager()->refEntries().at(tableIdx(*it)).name() );
00203 }
00204 }
00205
00206
00207
00208 int FWGeoTopNode::getFirstSelectedTableIndex()
00209 {
00210
00211
00212 if (fSted.size() <= 1)
00213 {
00214 int cnt = 0;
00215 for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin(); i != tableManager()->refEntries().end(); ++i, ++cnt)
00216 {
00217 if (i->testBit(FWGeometryTableManagerBase::kSelected)) return cnt;
00218 }
00219 }
00220 return -1;
00221 }
00222
00223
00224 void FWGeoTopNode::ComputeBBox()
00225 {
00226
00227
00228 BBoxZero(1.0f);
00229 }
00230
00231
00232 void FWGeoTopNode::setupBuffMtx(TBuffer3D& buff, const TGeoHMatrix& mat)
00233 {
00234 const Double_t *r = mat.GetRotationMatrix();
00235 const Double_t *t = mat.GetTranslation();
00236 const Double_t *s = mat.GetScale();
00237 Double_t *m = buff.fLocalMaster;
00238 m[0] = r[0]*s[0]; m[1] = r[1]*s[1]; m[2] = r[2]*s[2]; m[3] = 0;
00239 m[4] = r[3]*s[0]; m[5] = r[4]*s[1]; m[6] = r[5]*s[2]; m[7] = 0;
00240 m[8] = r[6]*s[0]; m[9] = r[7]*s[1]; m[10] = r[8]*s[2]; m[11] = 0;
00241 m[12] = t[0]; m[13] = t[1]; m[15] = t[2]; m[15] = 1;
00242
00243 buff.fLocalFrame = kTRUE;
00244 }
00245
00246
00247 void FWGeoTopNode::paintShape( Int_t tableIndex, const TGeoHMatrix& nm, bool volumeColor, bool isParentNode)
00248 {
00249 static const TEveException eh("FWGeoTopNode::paintShape ");
00250
00251
00252
00253 FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIndex);
00254 UChar_t transparency = wrapTransparency(data, isParentNode);
00255
00256 if (transparency >= 100) return;
00257
00258 TGeoShape* shape = data.m_node->GetVolume()->GetShape();
00259
00260 TGeoCompositeShape* compositeShape = dynamic_cast<TGeoCompositeShape*>(shape);
00261 if (compositeShape)
00262 {
00263
00264
00265 Double_t halfLengths[3] = { compositeShape->GetDX(), compositeShape->GetDY(), compositeShape->GetDZ() };
00266
00267 TBuffer3D buff(TBuffer3DTypes::kComposite);
00268 buff.fID = data.m_node->GetVolume();
00269 buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color ;
00270 buff.fTransparency = transparency;
00271
00272 nm.GetHomogenousMatrix(buff.fLocalMaster);
00273 buff.fLocalFrame = kTRUE;
00274 buff.SetAABoundingBox(compositeShape->GetOrigin(), halfLengths);
00275 buff.SetSectionsValid(TBuffer3D::kCore|TBuffer3D::kBoundingBox);
00276
00277 Bool_t paintComponents = kTRUE;
00278
00279 if (TBuffer3D::GetCSLevel() == 0) {
00280 paintComponents = m_scene->OpenCompositeWithPhyID(phyID(tableIndex), buff);
00281 }
00282
00283 TBuffer3D::IncCSLevel();
00284
00285
00286 TGeoHMatrix xxx;
00287 TGeoMatrix *gst = TGeoShape::GetTransform();
00288 TGeoShape::SetTransform(&xxx);
00289
00290 if (paintComponents) compositeShape->GetBoolNode()->Paint("");
00291 TGeoShape::SetTransform(gst);
00292
00293 if (TBuffer3D::DecCSLevel() == 0)
00294 gPad->GetViewer3D()->CloseComposite();
00295
00296
00297
00298 }
00299 else
00300 {
00301 TBuffer3D& buff = (TBuffer3D&) shape->GetBuffer3D (TBuffer3D::kCore, kFALSE);
00302 setupBuffMtx(buff, nm);
00303 buff.fID = data.m_node->GetVolume();
00304 buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color ;
00305 buff.fTransparency = transparency;
00306
00307
00308 nm.GetHomogenousMatrix(buff.fLocalMaster);
00309 buff.fLocalFrame = kTRUE;
00310
00311 Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
00312 shape->GetBuffer3D(sections, kTRUE);
00313
00314 Int_t reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
00315
00316 if (reqSec != TBuffer3D::kNone) {
00317
00318 if (reqSec & TBuffer3D::kCore)
00319 Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
00320 shape->GetBuffer3D(reqSec, kTRUE);
00321 reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
00322 }
00323
00324 if (reqSec != TBuffer3D::kNone)
00325 Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
00326 }
00327 }
00328
00329
00330 void FWGeoTopNode::Paint(Option_t* opt)
00331 {
00332 static const TEveException eh("FWGeoTopNode::Paint ");
00333
00334 TBuffer3D buff(TBuffer3DTypes::kGeneric);
00335
00336
00337 buff.fID = this;
00338 buff.fColor = GetMainColor();
00339 buff.fTransparency = GetMainTransparency();
00340 if (HasMainTrans()) RefMainTrans().SetBuffer3D(buff);
00341
00342 buff.SetSectionsValid(TBuffer3D::kCore);
00343
00344 Int_t reqSections = gPad->GetViewer3D()->AddObject(1, buff);
00345 if (reqSections != TBuffer3D::kNone)
00346 {
00347 Warning(eh, "IsA='%s'. Viewer3D requires more sections (%d). Only direct-rendering supported.",
00348 ClassName(), reqSections);
00349 }
00350 }
00351
00352
00353 void FWGeoTopNode::UnSelected()
00354 {
00355 ClearSet(fSted);
00356 for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin(); i != tableManager()->refEntries().end(); ++i)
00357 i->resetBit(FWGeometryTableManagerBase::kSelected);
00358 }
00359
00360
00361 void FWGeoTopNode::UnHighlighted()
00362 {
00363 ClearSet(fHted);
00364 for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin(); i != tableManager()->refEntries().end(); ++i)
00365 i->resetBit(FWGeometryTableManagerBase::kHighlighted);
00366 }
00367
00368
00369
00370 FWPopupMenu* FWGeoTopNode::setPopupMenu(int iX, int iY, TGLViewer* v, bool overlap)
00371 {
00372 if (getFirstSelectedTableIndex() < 0)
00373 {
00374 if (fSted.empty()) fwLog(fwlog::kInfo) << "No menu -- no node/entry selected \n";
00375 return 0;
00376 }
00377
00378 FWPopupMenu* nodePopup = new FWPopupMenu();
00379
00380 nodePopup->AddEntry("Set As Top Node", kSetTopNode);
00381 nodePopup->AddEntry("Set As Top Node And Reset Camera", kSetTopNodeCam);
00382 nodePopup->AddSeparator();
00383 if (v) {
00384 nodePopup->AddEntry("Rnr Off", kVisSelfOff);
00385 }
00386 nodePopup->AddEntry("Rnr Off For All Children", kVisChldOff);
00387 nodePopup->AddEntry("Rnr On For All Children", kVisChldOn);
00388 nodePopup->AddSeparator();
00389
00390 if (overlap)
00391 nodePopup->AddEntry("Print Overlap", kPrintOverlap);
00392 nodePopup->AddEntry("Print Path", kPrintPath);
00393 nodePopup->AddEntry("Print Shape", kPrintShape);
00394 nodePopup->AddEntry("Print Material", kPrintMaterial);
00395
00396 nodePopup->AddSeparator();
00397 if (v) {
00398 Window_t wdummy;
00399 Int_t x,y;
00400 gVirtualX->TranslateCoordinates(gClient->GetDefaultRoot()->GetId(), v->GetGLWidget()->GetId(), iX, iY, x, y, wdummy);
00401 TGLVector3 pnt(x, y, 0.5*v->GetSelRec().GetMinZ());
00402 v->CurrentCamera().WindowToViewport(pnt);
00403 s_pickedCamera3DCenter = v->CurrentCamera().ViewportToWorld(pnt);
00404
00405 s_pickedViewer = v;
00406
00407 nodePopup->AddEntry("Set Camera Center", kCamera);
00408 }
00409
00410 nodePopup->PlaceMenu(iX, iY,true,true);
00411 return nodePopup;
00412 }
00413
00414
00415 UChar_t FWGeoTopNode::wrapTransparency(FWGeometryTableManagerBase::NodeInfo& data, bool isParentNode)
00416 {
00417 if (isParentNode)
00418 {
00419 return TMath::Max((Char_t)browser()->getMinParentTransparency(), data.m_transparency) * browser()->getParentTransparencyFactor();
00420 }
00421 else
00422 {
00423 return TMath::Max((Char_t)browser()->getMinLeafTransparency(), data.m_transparency) * browser()->getLeafTransparencyFactor();
00424 }
00425 }