Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveTrackProjected.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
15 #include <ROOT/REveTrans.hxx>
16 #include <ROOT/REveRenderData.hxx>
17 
18 #include "json.hpp"
19 
20 
21 using namespace ROOT::Experimental;
22 namespace REX = ROOT::Experimental;
23 
24 /** \class REveTrackProjected
25 \ingroup REve
26 Projected copy of a REveTrack.
27 */
28 
29 
30 REveTrackProjected::~REveTrackProjected()
31 {
32  if (fOrigPnts) {
33  delete [] fOrigPnts;
34  fOrigPnts = nullptr;
35  }
36 }
37 
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 /// This is virtual method from base-class REveProjected.
41 
42 void REveTrackProjected::SetProjection(REveProjectionManager* mng, REveProjectable* model)
43 {
44  REveProjected::SetProjection(mng, model);
45  CopyVizParams(dynamic_cast<REveElement*>(model));
46 
47  REveTrack* otrack = dynamic_cast<REveTrack*>(fProjectable);
48  SetTrackParams(*otrack);
49  SetLockPoints(otrack->GetLockPoints());
50 }
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Set depth (z-coordinate) of the projected points.
54 
55 void REveTrackProjected::SetDepthLocal(Float_t d)
56 {
57  SetDepthCommon(d, this, fBBox);
58 
59  for (Int_t i = 0; i < fSize; ++i)
60  {
61  fPoints[i].fZ = fDepth;
62  }
63 
64  for (auto &pm: fPathMarks)
65  {
66  pm.fV.fZ = fDepth;
67  }
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Virtual method from base-class REveProjected.
72 
73 void REveTrackProjected::UpdateProjection()
74 {
75  MakeTrack(kFALSE); // REveProjectionManager makes recursive calls
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Find index of the last point that lies within the same
80 /// segment of projected space.
81 /// For example, rho-z projection separates upper and lower hemisphere
82 /// and tracks break into two lines when crossing the y=0 plane.
83 
84 Int_t REveTrackProjected::GetBreakPointIdx(Int_t start)
85 {
86  REveProjection *projection = fManager->GetProjection();
87 
88  Int_t val = fSize - 1;
89 
90  if (projection->HasSeveralSubSpaces())
91  {
92  REveVector v1, v2;
93  if (fSize > 1)
94  {
95  Int_t i = start;
96  while (i < fSize - 1)
97  {
98  v1 = RefPoint(i);
99  v2 = RefPoint(i+1);
100  if(projection->AcceptSegment(v1, v2, fPropagator->GetDelta()) == kFALSE)
101  {
102  val = i;
103  break;
104  }
105  i++;
106  }
107  }
108  }
109  return val;
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Calculate the points of the track for drawing.
114 /// Call base-class, project, find break-points and insert points
115 /// required for full representation.
116 
117 void REveTrackProjected::MakeTrack(Bool_t recurse)
118 {
119  REveTrack *otrack = dynamic_cast<REveTrack*>(fProjectable);
120  REveTrans *trans = otrack->PtrMainTrans(kFALSE);
121  REveProjection *projection = fManager->GetProjection();
122 
123  fBreakPoints.clear();
124 
125  fPathMarks.clear();
126  SetPathMarks(*otrack);
127  if (GetLockPoints() || otrack->GetSize() > 0)
128  {
129  ClonePoints(*otrack);
130  fLastPMIdx = otrack->GetLastPMIdx();
131  }
132  else
133  {
134  REveTrack::MakeTrack(recurse);
135  }
136  if (fSize == 0) return; // All points can be outside of MaxR / MaxZ limits.
137 
138  // Break segments additionally if required by the projection.
139  ReduceSegmentLengths(projection->GetMaxTrackStep());
140  // XXXX This is stoopid. Need some more flaxible way od doing this.
141  // XXXX Make it dependant on projection parameters and on individual
142  // XXXX points (a function of r and z, eg).
143  // XXXX Also, we could represnet track with a bezier curve, trying
144  // XXXX to stretch it as far out as we can so the fewest number of
145  // XXXX points/directions needs to be transferred.
146 
147  // Project points, store originals (needed for break-points).
148  Float_t *p = & fPoints[0].fX;
149  fOrigPnts = new REveVector[fSize];
150  for (Int_t i = 0; i < fSize; ++i, p+=3)
151  {
152  if (trans) trans->MultiplyIP(p);
153  fOrigPnts[i].Set(p);
154  projection->ProjectPointfv(p, fDepth);
155  }
156 
157  Int_t bL = 0, bR = GetBreakPointIdx(0);
158  std::vector<REveVector> vvec;
159  while (kTRUE)
160  {
161  for (Int_t i = bL; i <= bR; i++)
162  {
163  vvec.push_back( RefPoint(i) );
164  }
165  if (bR == fSize - 1)
166  break;
167 
168  REveVector vL = fOrigPnts[bR];
169  REveVector vR = fOrigPnts[bR + 1];
170  projection->BisectBreakPoint(vL, vR, kTRUE, fDepth);
171  vvec.push_back(vL);
172  fBreakPoints.push_back((Int_t)vvec.size());
173  vvec.push_back(vR);
174 
175  bL = bR + 1;
176  bR = GetBreakPointIdx(bL);
177  }
178  fBreakPoints.push_back((Int_t)vvec.size()); // Mark the track-end for drawing.
179 
180  // Decide if points need to be fixed.
181  // This (and the fixing itself) should really be done in REveProjection but
182  // for now we do it here as RhoZ is the only one that needs it.
183  Bool_t fix_y = kFALSE;
184  Float_t sign_y = 0;
185  if (projection->HasSeveralSubSpaces())
186  {
187  switch (fPropagator->GetProjTrackBreaking())
188  {
189  case REveTrackPropagator::kPTB_UseFirstPointPos:
190  {
191  fix_y = kTRUE;
192  sign_y = vvec.front().fY;
193  break;
194  }
195  case REveTrackPropagator::kPTB_UseLastPointPos:
196  {
197  fix_y = kTRUE;
198  sign_y = vvec.back().fY;
199  break;
200  }
201  }
202  }
203 
204  Reset((Int_t)vvec.size());
205  for (auto &i: vvec)
206  {
207  if (fix_y)
208  SetNextPoint(i.fX, TMath::Sign(i.fY, sign_y), i.fZ);
209  else
210  SetNextPoint(i.fX, i.fY, i.fZ);
211  }
212  delete [] fOrigPnts;
213  fOrigPnts = nullptr;
214 
215  // Project path-marks
216  for (auto &pm: fPathMarks)
217  {
218  projection->ProjectPointdv(trans, pm.fV.Arr(), pm.fV.Arr(), fDepth);
219  }
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Print line segments info.
224 
225 void REveTrackProjected::PrintLineSegments()
226 {
227  printf("%s LineSegments:\n", GetCName());
228 
229  Int_t start = 0;
230  Int_t segment = 0;
231 
232  for (auto &bpi: fBreakPoints)
233  {
234  Int_t size = bpi - start;
235 
236  const REveVector &sVec = RefPoint(start);
237  const REveVector &bPnt = RefPoint(bpi-1);
238  printf("seg %d size %d start %d ::(%f, %f, %f) (%f, %f, %f)\n",
239  segment, size, start, sVec.fX, sVec.fY, sVec.fZ,
240  bPnt.fX, bPnt.fY, bPnt.fZ);
241  start += size;
242  segment++;
243  }
244 }
245 
246 ////////////////////////////////////////////////////////////////////////////////
247 /// Virtual method from from base-class REveTrack.
248 
249 void REveTrackProjected::SecSelected(REveTrack* /*track*/)
250 {
251  REveTrack* t = dynamic_cast<REveTrack*>(fProjectable);
252  if (t)
253  t->SecSelected(t);
254 }
255 
256 
257 /** \class REveTrackListProjected
258 \ingroup REve
259 Specialization of REveTrackList for holding REveTrackProjected objects.
260 */
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Default constructor.
264 
265 REveTrackListProjected::REveTrackListProjected() :
266  REveTrackList (),
267  REveProjected ()
268 {
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// This is virtual method from base-class REveProjected.
273 
274 void REveTrackListProjected::SetProjection(REveProjectionManager* proj, REveProjectable* model)
275 {
276  REveProjected::SetProjection(proj, model);
277  CopyVizParams(dynamic_cast<REveElement*>(model));
278 
279  REveTrackList& tl = * dynamic_cast<REveTrackList*>(model);
280  SetPropagator(tl.GetPropagator());
281 }
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 /// This is not needed for functionality as SetDepth(Float_t d)
285 /// is overriden -- but SetDepthLocal() is abstract.
286 /// Just emits a warning if called.
287 
288 void REveTrackListProjected::SetDepthLocal(Float_t /*d*/)
289 {
290  Warning("SetDepthLocal", "This function only exists to fulfill an abstract interface.");
291 }
292 
293 ////////////////////////////////////////////////////////////////////////////////
294 /// Set depth of all children inheriting from REveTrackProjected.
295 
296 void REveTrackListProjected::SetDepth(Float_t d)
297 {
298  SetDepth(d, this);
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Set depth of all children of el inheriting from REveTrackProjected.
303 
304 void REveTrackListProjected::SetDepth(Float_t d, REveElement *el)
305 {
306  for (auto &c: el->RefChildren()) {
307  auto ptrack = dynamic_cast<REveTrackProjected *>(c);
308  if (ptrack)
309  ptrack->SetDepth(d);
310  if (fRecurse)
311  SetDepth(d, c);
312  }
313 }
314 
315 ////////////////////////////////////////////////////////////////////////////////
316 /// Creates client representation.
317 
318 Int_t REveTrackProjected::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
319 {
320  Int_t ret = REveTrack::WriteCoreJson(j, rnr_offset);
321 
322  j["render_data"]["break_point_size"] = fBreakPoints.size();
323 
324  return ret;
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Creates client rendering info.
329 
330 void REveTrackProjected::BuildRenderData()
331 {
332  REveTrack::BuildRenderData();
333 
334  if (fRenderData && !fBreakPoints.empty()) {
335  fRenderData->Reserve(0, 0, fBreakPoints.size());
336  fRenderData->PushI(fBreakPoints);
337  }
338 }