File indexing completed on 2023-03-17 11:01:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "TEveTrans.h"
0018 #include "TEveViewer.h"
0019 #include "TEveManager.h"
0020 #include "TEveUtil.h"
0021
0022 #include "TROOT.h"
0023 #include "TBuffer3D.h"
0024 #include "TBuffer3DTypes.h"
0025 #include "TVirtualViewer3D.h"
0026 #include "TColor.h"
0027 #include "TGLScenePad.h"
0028 #include "TGLPhysicalShape.h"
0029 #include "TGLSelectRecord.h"
0030 #include "TGLViewer.h"
0031 #include "TGLWidget.h"
0032
0033 #include "TGeoShape.h"
0034 #include "TGeoVolume.h"
0035 #include "TGeoNode.h"
0036 #include "TGeoShapeAssembly.h"
0037 #include "TGeoCompositeShape.h"
0038 #include "TGeoBoolNode.h"
0039 #include "TGeoManager.h"
0040 #include "TGeoMatrix.h"
0041 #include "TVirtualGeoPainter.h"
0042 #include "TVirtualX.h"
0043
0044 #include "Fireworks/Core/interface/FWGeoTopNode.h"
0045 #include "Fireworks/Core/src/FWGeoTopNodeScene.h"
0046 #include "Fireworks/Core/src/FWPopupMenu.cc"
0047 #include "Fireworks/Core/interface/FWViewType.h"
0048 #include "Fireworks/Core/interface/fwLog.h"
0049
0050 TGLViewer* FWGeoTopNode::s_pickedViewer = nullptr;
0051 TGLVector3 FWGeoTopNode::s_pickedCamera3DCenter;
0052
0053 UInt_t FWGeoTopNode::phyID(int tableIdx) { return UInt_t(tableIdx + 2); }
0054
0055 int FWGeoTopNode::tableIdx(TGLPhysicalShape* ps) { return ps->ID() - 2; }
0056
0057 void FWGeoTopNode::EraseFromSet(std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id) {
0058 sset.erase(id);
0059 SetStateOf(id);
0060 }
0061
0062
0063 void FWGeoTopNode::ClearSet(std::set<TGLPhysicalShape*>& sset) {
0064 while (!sset.empty()) {
0065 TGLPhysicalShape* id = *sset.begin();
0066 sset.erase(id);
0067 SetStateOf(id);
0068 }
0069 }
0070
0071 void FWGeoTopNode::SetStateOf(TGLPhysicalShape* id) {
0072 FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIdx(id));
0073
0074 if (fSted.find(id) != fSted.end()) {
0075 id->Select(1);
0076 data.setBit(FWGeometryTableManagerBase::kSelected);
0077 } else if (fHted.find(id) != fHted.end()) {
0078 id->Select(3);
0079 data.setBit(FWGeometryTableManagerBase::kHighlighted);
0080 } else {
0081 id->Select(0);
0082 data.resetBit(FWGeometryTableManagerBase::kHighlighted);
0083 data.resetBit(FWGeometryTableManagerBase::kSelected);
0084 }
0085 }
0086
0087
0088 void FWGeoTopNode::ProcessSelection(TGLSelectRecord& rec, std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id) {
0089
0090
0091 m_scene->BeginUpdate();
0092
0093 if (sset.empty()) {
0094 if (id) {
0095 sset.insert(id);
0096 rec.SetSecSelResult(TGLSelectRecord::kEnteringSelection);
0097 }
0098 } else {
0099 if (id) {
0100 if (rec.GetMultiple()) {
0101 if (sset.find(id) == sset.end()) {
0102 sset.insert(id);
0103 rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
0104 } else {
0105 EraseFromSet(sset, id);
0106 if (sset.empty())
0107 rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
0108 else
0109 rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
0110 }
0111 } else {
0112 if (sset.size() != 1 || sset.find(id) == sset.end()) {
0113 ClearSet(sset);
0114 sset.insert(id);
0115 rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
0116 }
0117 }
0118 } else {
0119 if (!rec.GetMultiple()) {
0120 ClearSet(sset);
0121 rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
0122 }
0123 }
0124 }
0125
0126 if (id) {
0127 SetStateOf(id);
0128 }
0129
0130 if (rec.GetSecSelResult() != TGLSelectRecord::kNone) {
0131 m_scene->EndUpdate(kTRUE, kFALSE, kTRUE);
0132 gEve->Redraw3D();
0133
0134 tableManager()->dataChanged();
0135 } else {
0136 m_scene->EndUpdate(kFALSE, kFALSE, kFALSE);
0137 }
0138 }
0139
0140
0141 bool FWGeoTopNode::selectPhysicalFromTable(int tableIndex) {
0142
0143
0144 TGLPhysicalShape* ps = m_scene->FindPhysical(phyID(tableIndex));
0145 if (ps) {
0146 fSted.insert(ps);
0147 ps->Select(1);
0148
0149 return true;
0150 } else if (tableManager()->refEntries().at(tableIndex).testBit(FWGeometryTableManagerBase::kVisNodeSelf))
0151 fwLog(fwlog::kInfo) << "Selected entry not drawn in GL viewer. \n";
0152 return false;
0153 }
0154
0155
0156 void FWGeoTopNode::printSelected() {
0157 for (std::set<TGLPhysicalShape*>::iterator it = fSted.begin(); it != fSted.end(); ++it) {
0158 printf("FWGeoTopNode::printSelected %s \n", tableManager()->refEntries().at(tableIdx(*it)).name());
0159 }
0160 }
0161
0162
0163
0164 int FWGeoTopNode::getFirstSelectedTableIndex() {
0165
0166
0167 if (fSted.size() <= 1) {
0168 int cnt = 0;
0169 for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
0170 i != tableManager()->refEntries().end();
0171 ++i, ++cnt) {
0172 if (i->testBit(FWGeometryTableManagerBase::kSelected))
0173 return cnt;
0174 }
0175 }
0176 return -1;
0177 }
0178
0179
0180 void FWGeoTopNode::ComputeBBox() {
0181
0182
0183 BBoxZero(1.0f);
0184 }
0185
0186
0187 void FWGeoTopNode::setupBuffMtx(TBuffer3D& buff, const TGeoHMatrix& mat) {
0188 const Double_t* r = mat.GetRotationMatrix();
0189 const Double_t* t = mat.GetTranslation();
0190 const Double_t* s = mat.GetScale();
0191 Double_t* m = buff.fLocalMaster;
0192 m[0] = r[0] * s[0];
0193 m[1] = r[1] * s[1];
0194 m[2] = r[2] * s[2];
0195 m[3] = 0;
0196 m[4] = r[3] * s[0];
0197 m[5] = r[4] * s[1];
0198 m[6] = r[5] * s[2];
0199 m[7] = 0;
0200 m[8] = r[6] * s[0];
0201 m[9] = r[7] * s[1];
0202 m[10] = r[8] * s[2];
0203 m[11] = 0;
0204 m[12] = t[0];
0205 m[13] = t[1];
0206 m[15] = t[2];
0207 m[15] = 1;
0208
0209 buff.fLocalFrame = kTRUE;
0210 }
0211
0212
0213 void FWGeoTopNode::paintShape(Int_t tableIndex, const TGeoHMatrix& nm, bool volumeColor, bool isParentNode) {
0214 static const TEveException eh("FWGeoTopNode::paintShape ");
0215
0216
0217
0218 FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIndex);
0219 UChar_t transparency = wrapTransparency(data, isParentNode);
0220
0221 if (transparency >= 100)
0222 return;
0223
0224 if (data.m_node->GetVolume()->IsAssembly())
0225 return;
0226 TGeoShape* shape = data.m_node->GetVolume()->GetShape();
0227
0228 TGeoCompositeShape* compositeShape = dynamic_cast<TGeoCompositeShape*>(shape);
0229 if (compositeShape) {
0230
0231
0232 Double_t halfLengths[3] = {compositeShape->GetDX(), compositeShape->GetDY(), compositeShape->GetDZ()};
0233
0234 TBuffer3D buff(TBuffer3DTypes::kComposite);
0235 buff.fID = data.m_node->GetVolume();
0236 buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color;
0237 buff.fTransparency = transparency;
0238
0239 nm.GetHomogenousMatrix(buff.fLocalMaster);
0240 buff.fLocalFrame = kTRUE;
0241 buff.SetAABoundingBox(compositeShape->GetOrigin(), halfLengths);
0242 buff.SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kBoundingBox);
0243
0244 Bool_t paintComponents = kTRUE;
0245
0246 if (TBuffer3D::GetCSLevel() == 0) {
0247 paintComponents = m_scene->OpenCompositeWithPhyID(phyID(tableIndex), buff);
0248 }
0249
0250 TBuffer3D::IncCSLevel();
0251
0252
0253 TGeoHMatrix xxx;
0254 TGeoMatrix* gst = TGeoShape::GetTransform();
0255 TGeoShape::SetTransform(&xxx);
0256
0257 if (paintComponents)
0258 compositeShape->GetBoolNode()->Paint("");
0259 TGeoShape::SetTransform(gst);
0260
0261 if (TBuffer3D::DecCSLevel() == 0)
0262 gPad->GetViewer3D()->CloseComposite();
0263
0264
0265 } else {
0266 TBuffer3D& buff = (TBuffer3D&)shape->GetBuffer3D(TBuffer3D::kCore, kFALSE);
0267 setupBuffMtx(buff, nm);
0268 buff.fID = data.m_node->GetVolume();
0269 buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color;
0270 buff.fTransparency = transparency;
0271
0272 nm.GetHomogenousMatrix(buff.fLocalMaster);
0273 buff.fLocalFrame = kTRUE;
0274
0275 Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
0276 shape->GetBuffer3D(sections, kTRUE);
0277
0278 Int_t reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
0279
0280 if (reqSec != TBuffer3D::kNone) {
0281
0282 if (reqSec & TBuffer3D::kCore)
0283 Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
0284 shape->GetBuffer3D(reqSec, kTRUE);
0285 reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
0286 }
0287
0288 if (reqSec != TBuffer3D::kNone)
0289 Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
0290 }
0291 }
0292
0293
0294 void FWGeoTopNode::Paint(Option_t* opt) {
0295 static const TEveException eh("FWGeoTopNode::Paint ");
0296
0297 TBuffer3D buff(TBuffer3DTypes::kGeneric);
0298
0299
0300 buff.fID = this;
0301 buff.fColor = GetMainColor();
0302 buff.fTransparency = GetMainTransparency();
0303 if (HasMainTrans())
0304 RefMainTrans().SetBuffer3D(buff);
0305
0306 buff.SetSectionsValid(TBuffer3D::kCore);
0307
0308 Int_t reqSections = gPad->GetViewer3D()->AddObject(1, buff);
0309 if (reqSections != TBuffer3D::kNone) {
0310 Warning(eh,
0311 "IsA='%s'. Viewer3D requires more sections (%d). Only direct-rendering supported.",
0312 ClassName(),
0313 reqSections);
0314 }
0315 }
0316
0317
0318 void FWGeoTopNode::UnSelected() {
0319 ClearSet(fSted);
0320 for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
0321 i != tableManager()->refEntries().end();
0322 ++i)
0323 i->resetBit(FWGeometryTableManagerBase::kSelected);
0324 }
0325
0326
0327 void FWGeoTopNode::UnHighlighted() {
0328 ClearSet(fHted);
0329 for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
0330 i != tableManager()->refEntries().end();
0331 ++i)
0332 i->resetBit(FWGeometryTableManagerBase::kHighlighted);
0333 }
0334
0335
0336 FWPopupMenu* FWGeoTopNode::setPopupMenu(int iX, int iY, TGLViewer* v, bool overlap) {
0337 if (getFirstSelectedTableIndex() < 0) {
0338 if (fSted.empty())
0339 fwLog(fwlog::kInfo) << "No menu -- no node/entry selected \n";
0340 return nullptr;
0341 }
0342
0343 FWPopupMenu* nodePopup = new FWPopupMenu();
0344
0345 nodePopup->AddEntry("Set As Top Node", kSetTopNode);
0346 nodePopup->AddEntry("Set As Top Node and Reset Camera", kSetTopNodeCam);
0347 nodePopup->AddSeparator();
0348 if (v) {
0349 nodePopup->AddEntry("Rnr Off", kVisSelfOff);
0350 }
0351 nodePopup->AddEntry("Turn Render On For Children", kVisChldOn);
0352 nodePopup->AddEntry("Turn Render Off For Children", kVisChldOff);
0353 nodePopup->AddEntry("Apply Color To Children", kApplyChldCol);
0354 nodePopup->AddEntry("Apply Color Recursively", kApplyChldColRec);
0355 nodePopup->AddSeparator();
0356
0357 if (overlap)
0358 nodePopup->AddEntry("Print Overlap", kPrintOverlap);
0359 nodePopup->AddEntry("Print Path", kPrintPath);
0360 nodePopup->AddEntry("Print Shape", kPrintShape);
0361 nodePopup->AddEntry("Print Material", kPrintMaterial);
0362
0363 nodePopup->AddSeparator();
0364 if (v) {
0365 Window_t wdummy;
0366 Int_t x, y;
0367 gVirtualX->TranslateCoordinates(
0368 gClient->GetDefaultRoot()->GetId(), v->GetGLWidget()->GetId(), iX, iY, x, y, wdummy);
0369 TGLVector3 pnt(x, y, 0.5 * v->GetSelRec().GetMinZ());
0370 v->CurrentCamera().WindowToViewport(pnt);
0371 s_pickedCamera3DCenter = v->CurrentCamera().ViewportToWorld(pnt);
0372
0373 s_pickedViewer = v;
0374
0375 nodePopup->AddEntry("Set Camera Center", kCamera);
0376 }
0377
0378 nodePopup->PlaceMenu(iX, iY, true, true);
0379 return nodePopup;
0380 }
0381
0382 UChar_t FWGeoTopNode::wrapTransparency(FWGeometryTableManagerBase::NodeInfo& data, bool isParentNode) {
0383 if (isParentNode) {
0384 return TMath::Max((Char_t)browser()->getMinParentTransparency(), data.m_transparency) *
0385 browser()->getParentTransparencyFactor();
0386 } else {
0387 return TMath::Max((Char_t)browser()->getMinLeafTransparency(), data.m_transparency) *
0388 browser()->getLeafTransparencyFactor();
0389 }
0390 }