32 constexpr double tol = 1
e-9;
35 const Double_t *ta =
a->GetTranslation(), *tb =
b->GetTranslation();
36 for (
int i = 0; i < 3; ++i)
37 if (std::fabs(ta[i] - tb[i]) > tol)
39 const Double_t *ra =
a->GetRotationMatrix(), *rb =
b->GetRotationMatrix();
40 for (
int i = 0; i < 9; ++i)
41 if (std::fabs(ra[i] - rb[i]) > tol)
48 if (!mom || !vol || !matr)
60 return std::isfinite(
p[0]) && std::isfinite(
p[1]) && std::isfinite(
p[2]);
63bool InsideWorld(
const Float_t *
p,
double limit)
67 return std::fabs(
p[0]) <= limit && std::fabs(
p[1]) <= limit && std::fabs(
p[2]) <= limit;
82 return std::min({bbox->GetDX(), bbox->GetDY(), bbox->GetDZ()});
129 std::map<TGeoVolume *, std::vector<TGeoVolume *>> mothers;
130 bool mothersBuilt =
false;
131 auto buildMothers = [&mothers, mgr]() {
133 while (
auto *vol =
static_cast<TGeoVolume *
>(next()))
146 std::set<TGeoVolume *> reachable;
147 bool reachableBuilt =
false;
148 auto buildReachable = [&reachable, mgr]() {
150 reachable.insert(top);
153 while ((node = iter.
Next()))
163 double worldLimit = 0.;
165 worldLimit = 2. * std::max(wbox->GetDX(), std::max(wbox->GetDY(), wbox->GetDZ())) + 100.;
167 std::vector<std::vector<float>> rawMarkers;
175 ent.
fName = ovl->GetName() ? ovl->GetName() :
"";
176 ent.
fTitle = ovl->GetTitle() ? ovl->GetTitle() :
"";
178 ent.
fValue = ovl->GetOverlap();
179 ent.
fV1 = ovl->GetFirstVolume();
180 ent.
fV2 = ovl->GetSecondVolume();
183 if (ovl->GetFirstMatrix())
184 ent.
fM1 = *ovl->GetFirstMatrix();
185 if (ovl->GetSecondMatrix())
186 ent.
fM2 = *ovl->GetSecondMatrix();
195 if (!reachableBuilt) {
197 reachableBuilt =
true;
199 auto it = mothers.find(ent.
fV1);
200 if (it != mothers.end())
201 for (
auto *cand : it->second)
202 if (reachable.count(cand) && IsDaughter(cand, ent.
fV1, ovl->GetFirstMatrix()) &&
203 IsDaughter(cand, ent.
fV2, ovl->GetSecondMatrix())) {
214 std::vector<float> pts;
218 pts.reserve(3 * pm->GetN());
219 for (
int k = 0; k < pm->GetN(); ++k)
220 if (IsFinitePoint(
p + 3 * k) && InsideWorld(
p + 3 * k, worldLimit)) {
221 pts.push_back(
p[3 * k]);
222 pts.push_back(
p[3 * k + 1]);
223 pts.push_back(
p[3 * k + 2]);
227 fEntries.emplace_back(std::move(ent));
228 rawMarkers.emplace_back(std::move(pts));
233 for (
size_t i = 0; i <
fEntries.size(); ++i)
249 std::set<TGeoVolume *> wanted;
251 wanted.insert(ent.fMother);
253 std::map<TGeoVolume *, std::vector<TGeoHMatrix>> found;
256 if (wanted.count(top))
261 while ((node = iter.
Next())) {
263 if (!wanted.count(vol))
270 auto it = found.find(ent.fMother);
271 if (it != found.end())
272 ent.fGlobals = it->second;
299 if (localPts.empty())
302 const size_t npt = localPts.size() / 3;
305 const double margin = 1.0;
306 const double farAway = 1.e6;
312 local.MasterToLocal(lp, dl);
326 auto distance = [&](
const Double_t *lp) {
327 if (!testV1 && !testV2)
329 double d1 = testV1 ? daughterDistance(ent.
fV1, ent.
fM1, lp) : farAway;
330 double d2 = testV2 ? daughterDistance(ent.
fV2, ent.
fM2, lp) : farAway;
331 return std::min(d1 < 0. ? farAway : d1, d2 < 0. ? farAway : d2);
335 for (
size_t k = 0; k < npt; ++k) {
336 Double_t lp[3] = {localPts[3 * k], localPts[3 * k + 1], localPts[3 * k + 2]};
337 if (distance(lp) > margin)
362 t +=
TString::Format(
"%sA %s%s<br>", which == 0 ?
"<b>" :
"", ent.
fVol1.c_str(), which == 0 ?
"</b>" :
"");
363 t +=
TString::Format(
"%sB %s%s<br>", which == 1 ?
"<b>" :
"", ent.
fVol2.c_str(), which == 1 ?
"</b>" :
"");
378 t +=
TString::Format(
"%d points (%d dropped as out of range)", kept, dropped);
383 return std::string(t.
Data());
390 std::set<std::string> *seen,
int inst,
int ninst)
402 const Double_t *t =
m.GetTranslation(), *
r =
m.GetRotationMatrix();
404 int n = snprintf(key,
sizeof(key),
"%p|%.4f,%.4f,%.4f", (
void *)vol, t[0], t[1], t[2]);
405 for (
int i = 0; i < 9 &&
n < (
int)
sizeof(key); ++i)
406 n += snprintf(key +
n,
sizeof(key) -
n,
",%.6f",
r[i]);
407 if (!seen->insert(key).second)
421 MakeTip(ent, which, placement, inst, ninst).c_str());
422 shape->SetShape(geoShape);
423 shape->SetTransMatrix(
m);
424 shape->SetMainColor(col);
425 shape->SetMainTransparency(50);
428 shape->SetPickable(
kTRUE);
440 MakeTip(ent, 2, placement, inst, ninst).c_str(), npt);
441 ps->SetMarkerColor(
kCyan);
443 ps->SetPickable(
kTRUE);
444 ps->SetMarkerStyle(4);
450 MakeTip(ent, 2, placement, inst, ninst).c_str());
451 cross->SetMainColor(
kCyan);
452 cross->SetLineWidth(2);
453 cross->SetPickable(
kTRUE);
462 constexpr double kCrossFraction = 0.3;
463 double s1 = ShapeSize(ent.
fV1), s2 = ShapeSize(ent.
fV2);
464 double smallest = (
s1 > 0. && s2 > 0.) ? std::min(
s1, s2) : std::max(
s1, s2);
465 double proportional = smallest > 0. ? kCrossFraction * smallest : (
double)
fCrossSize;
466 const float h = (float)std::min(proportional, (
double)
fCrossSize);
468 for (
size_t k = 0; k < npt; ++k) {
471 ps->SetNextPoint((
float)gp[0], (float)gp[1], (
float)gp[2]);
473 float x = (float)gp[0],
y = (
float)gp[1], z = (float)gp[2];
474 cross->AddLine(
x -
h,
y, z,
x +
h,
y, z);
475 cross->AddLine(
x,
y -
h, z,
x,
y +
h, z);
476 cross->AddLine(
x,
y, z -
h,
x,
y, z +
h);
513 std::map<std::string, int>
index;
515 for (
size_t i = 0; i <
fEntries.size(); ++i) {
517 std::string key =
e.fVol1 +
"|" +
e.fVol2 +
"|" + (
e.fExtrusion ?
"e" :
"o");
518 auto it =
index.find(key);
519 if (it ==
index.end()) {
524 g.fExtrusion =
e.fExtrusion;
526 g.fMembers.emplace_back((
int)i);
530 g.fMembers.emplace_back((
int)i);
531 if (
e.fValue >
g.fValue)
551 std::set<std::string> seen;
553 for (
size_t k = 0; k < mem.size(); ++k) {
609 if (precision <= 0. || !
fMgr)
627 if ((idx < 0) || (idx >= (
int)
fEntries.size())) {
628 printf(
"REveGeoOverlapTable::PrintOverlap: index %d out of range (%d entries)\n", idx, (
int)
fEntries.size());
634 printf(
"=== %s : %s : %.6f cm ===\n",
e.fName.c_str(),
e.fExtrusion ?
"extrusion" :
"overlap",
e.fValue);
635 printf(
" A: %s\n",
e.fVol1.c_str());
636 printf(
" B: %s\n",
e.fVol2.c_str());
637 printf(
" mother: %s\n",
e.fMother ?
e.fMother->GetName() :
"(none)");
638 if (!
e.fTitle.empty())
639 printf(
" title: %s\n",
e.fTitle.c_str());
640 printf(
" placements: %d\n", (
int)
e.fGlobals.size());
641 for (
size_t p = 0;
p <
e.fGlobals.size(); ++
p) {
642 const Double_t *t =
e.fGlobals[
p].GetTranslation();
643 printf(
" [%d] translation = (%.4f, %.4f, %.4f)\n", (
int)
p, t[0], t[1], t[2]);
645 int kept = (
int)(
e.fLocalMarkers.size() / 3);
646 printf(
" points: %d raw, %d kept (%d dropped)\n",
e.fNumRawMarkers, kept,
e.fNumRawMarkers - kept);
659 if ((gidx < 0) || (gidx >= (
int)
fGroups.size())) {
660 printf(
"REveGeoOverlapTable::PrintUniqueOverlap: index %d out of range (%d groups)\n", gidx, (
int)
fGroups.size());
666 printf(
"=== group: %s | %s | %s (%d members) ===\n",
g.fVol1.c_str(),
g.fVol2.c_str(),
667 g.fExtrusion ?
"extrusion" :
"overlap", (
int)
g.fMembers.size());
668 for (
int ei :
g.fMembers)
682 nlohmann::json arr = nlohmann::json::array();
683 for (
size_t i = 0; i <
fEntries.size(); ++i) {
685 nlohmann::json o = nlohmann::json::object();
688 o[
"kind"] =
e.fExtrusion ?
"extrusion" :
"overlap";
689 o[
"value"] =
e.fValue;
692 o[
"mother"] =
e.fMother ?
e.fMother->GetName() :
"";
693 o[
"nplaced"] = (
int)
e.fGlobals.size();
694 o[
"npoints"] = (
int)(
e.fLocalMarkers.size() / 3);
695 o[
"ndropped"] =
e.fNumRawMarkers - (
int)(
e.fLocalMarkers.size() / 3);
696 o[
"title"] =
e.fTitle;
697 arr.emplace_back(std::move(o));
699 j[
"fOverlaps"] = std::move(arr);
701 nlohmann::json garr = nlohmann::json::array();
702 for (
size_t i = 0; i <
fGroups.size(); ++i) {
705 for (
int ei :
g.fMembers)
706 npts += (
int)(
fEntries[ei].fLocalMarkers.size() / 3);
707 nlohmann::json o = nlohmann::json::object();
709 o[
"kind"] =
g.fExtrusion ?
"extrusion" :
"overlap";
710 o[
"value"] =
g.fValue;
713 o[
"ninst"] = (
int)
g.fMembers.size();
715 o[
"name"] =
g.fMembers.empty() ?
"" :
fEntries[
g.fMembers.front()].fName;
716 garr.emplace_back(std::move(o));
718 j[
"fGroups"] = std::move(garr);
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
short Color_t
Color number (short)
char Text_t
General string (char)
float Float_t
Float 4 bytes (float)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
virtual Int_t WriteCoreJson(nlohmann::json &cj, Int_t rnr_offset)
Write core json.
virtual void AddElement(REveElement *el)
Add el to the list of children.
virtual void DestroyElements()
Destroy all children of this element.
REveElement(const std::string &name="", const std::string &title="")
Default constructor.
void ScanOverlaps(TGeoManager *mgr, double precision=0.001)
Find every overlap and extrusion in the geometry and work out where each one is.
void SelectOverlap(int idx)
Show one overlap and nothing else.
std::string MakeTip(const Entry &ent, int which, int placement, int inst, int ninst) const
Text shown when the mouse is over one of the drawn pieces.
float fCrossSize
cap, in cm, on the half-length of each marker's 3D-cross arm; AddPlacement() scales the actual arm to...
void AddPlacement(const Entry &ent, const TGeoHMatrix &global, int placement, std::set< std::string > *seen=nullptr, int inst=-1, int ninst=0)
Draw one placement of the selected overlap: the two shapes and the points.
void SetMarkerSize(float size)
Marker size for the overlap points.
REveElement * fHolder
! where the selected overlap is drawn; put this in a 3D scene
TGeoManager * fMgr
! kept from ScanOverlaps() so SetPrecision() can re-run it
void SetPrecision(double precision)
Re-run the overlap check at a new precision and rebuild the table from scratch.
REveGeoOverlapTable(const REveGeoOverlapTable &)=delete
void PrintOverlap(int idx)
Print one overlap's details to the server console: name, volumes, mother, TGeoOverlap's own title (us...
void Redraw()
Re-run whichever selection is current, so a change of appearance takes effect without the client havi...
void SelectUniqueOverlap(int gidx)
Show every instance of one kind of flaw at once.
void LocalizeMarkers(Entry &ent, const std::vector< float > &localPts)
Filter the marker points down to the ones that plausibly belong to this flaw.
int fScanGen
bumped by ScanOverlaps(); lets the client tell a rescan from an ordinary selection stamp
void PrintUniqueOverlap(int gidx)
Print a whole group – every entry sharing this (vol1, vol2, extrusion) – to the server console,...
void SetCrossSize(float size)
Cap, in cm, on the half-length of each marker's 3D-cross arm.
void CollectPlacements(TGeoManager *mgr)
Global matrix of every physical placement of each mother volume.
Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override
Write core json.
std::vector< Group > fGroups
void BuildGroups()
Collapse entries that are the same flaw repeated.
std::vector< Entry > fEntries
REveStraightLineSet Set of straight lines with optional markers along the lines.
Matrix class used for computing global transformations Should NOT be used for node definition.
const TGeoMatrix * GetCurrentMatrix() const
Returns global matrix for current node.
TGeoNode * Next()
Returns next node.
The manager class for any TGeo geometry.
TGeoNavigator * AddNavigator()
Add a navigator in the list of navigators.
TObjArray * GetListOfOverlaps()
TObjArray * GetListOfVolumes() const
void ClearOverlaps()
Clear the list of overlaps.
TGeoNavigator * GetCurrentNavigator() const
Returns current navigator for the calling thread.
TGeoVolume * GetTopVolume() const
Geometrical transformation package.
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
TGeoVolume * GetVolume() const
virtual TGeoMatrix * GetMatrix() const =0
Base class describing geometry overlaps.
Base abstract class for all shapes.
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const =0
virtual Bool_t Contains(const Double_t *point) const =0
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Int_t GetNdaughters() const
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
TGeoShape * GetShape() const
void CheckOverlaps(Double_t ovlp=0.1, Option_t *option="")
Overlap checking tool. Check for illegal overlaps within a limit OVLP.
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
const char * GetName() const override
Returns name of object.
Int_t GetEntriesFast() const
TObject * At(Int_t idx) const override
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
const char * Data() const
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Namespace for ROOT features in testing.
TGeoVolume * fV1
! first volume; the mother, for an extrusion
TGeoHMatrix fM2
! placements, in the mother's local frame
std::string fName
TGeoOverlap name, e.g. ov00035.
std::string fTitle
human-readable description
std::string fVol2
names of the two volumes
TGeoVolume * fV2
! second volume
std::vector< TGeoHMatrix > fGlobals
! global matrix of every placement of the mother
bool fExtrusion
extrusion, as opposed to a real overlap
int fNumRawMarkers
points the overlap carried, before filtering
TGeoVolume * fMother
! volume both matrices are expressed in
double fValue
overlap/extrusion size, in cm
std::vector< float > fLocalMarkers
! marker points, in the mother's frame, finite only
One kind of flaw, with every placement of it that the geometry contains.