Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveStraightLineSet.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 
13 #include <ROOT/REveRenderData.hxx>
15 
16 #include "TRandom.h"
17 #include "TClass.h"
18 #include "json.hpp"
19 
20 using namespace ROOT::Experimental;
21 
22 ////////////////////////////////////////////////////////////////////////////////
23 /// Constructor.
24 
25 REveStraightLineSet::REveStraightLineSet(const std::string& n, const std::string& t):
26  REveElement (n, t),
27 
28  fLinePlex (sizeof(Line_t), 4),
29  fMarkerPlex (sizeof(Marker_t), 8),
30  fOwnLinesIds (kFALSE),
31  fOwnMarkersIds (kFALSE),
32  fRnrMarkers (kTRUE),
33  fRnrLines (kTRUE),
34  fDepthTest (kTRUE),
35  fLastLine (0)
36 {
37  InitMainTrans();
38  fPickable = kTRUE;
39 
40  fMainColorPtr = &fLineColor;
41  fLineColor = 4;
42  fMarkerColor = 2;
43  fMarkerStyle = 20;
44 }
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 /// Add a line.
48 
49 REveStraightLineSet::Line_t*
50 REveStraightLineSet::AddLine(Float_t x1, Float_t y1, Float_t z1,
51  Float_t x2, Float_t y2, Float_t z2)
52 {
53  fLastLine = new (fLinePlex.NewAtom()) Line_t(x1, y1, z1, x2, y2, z2);
54  fLastLine->fId = fLinePlex.Size() - 1;
55  return fLastLine;
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Add a line.
60 
61 REveStraightLineSet::Line_t*
62 REveStraightLineSet::AddLine(const REveVector& p1, const REveVector& p2)
63 {
64  return AddLine(p1.fX, p1.fY, p1.fZ, p2.fX, p2.fY, p2.fZ);
65 }
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 /// Set line vertices with given index.
69 
70 void
71 REveStraightLineSet::SetLine(int idx,
72  Float_t x1, Float_t y1, Float_t z1,
73  Float_t x2, Float_t y2, Float_t z2)
74 {
75  Line_t* l = (Line_t*) fLinePlex.Atom(idx);
76 
77  l->fV1[0] = x1; l->fV1[1] = y1; l->fV1[2] = z1;
78  l->fV2[0] = x2; l->fV2[1] = y2; l->fV2[2] = z2;
79 }
80 
81 ////////////////////////////////////////////////////////////////////////////////
82 /// Set line vertices with given index.
83 
84 void
85 REveStraightLineSet::SetLine(int idx, const REveVector& p1, const REveVector& p2)
86 {
87  SetLine(idx, p1.fX, p1.fY, p1.fZ, p2.fX, p2.fY, p2.fZ);
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Add a marker with given position.
92 
93 REveStraightLineSet::Marker_t*
94 REveStraightLineSet::AddMarker(Float_t x, Float_t y, Float_t z, Int_t line_id)
95 {
96  Marker_t* marker = new (fMarkerPlex.NewAtom()) Marker_t(x, y, z, line_id);
97  return marker;
98 }
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Add a marker with given position.
102 
103 REveStraightLineSet::Marker_t*
104 REveStraightLineSet::AddMarker(const REveVector& p, Int_t line_id)
105 {
106  return AddMarker(p.fX, p.fY, p.fZ, line_id);
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 /// Add a marker for line with given index on relative position pos.
111 
112 REveStraightLineSet::Marker_t*
113 REveStraightLineSet::AddMarker(Int_t line_id, Float_t pos)
114 {
115  Line_t& l = * (Line_t*) fLinePlex.Atom(line_id);
116  return AddMarker(l.fV1[0] + (l.fV2[0] - l.fV1[0])*pos,
117  l.fV1[1] + (l.fV2[1] - l.fV1[1])*pos,
118  l.fV1[2] + (l.fV2[2] - l.fV1[2])*pos,
119  line_id);
120 }
121 
122 ////////////////////////////////////////////////////////////////////////////////
123 /// Copy visualization parameters from element el.
124 
125 void REveStraightLineSet::CopyVizParams(const REveElement* el)
126 {
127  const REveStraightLineSet* m = dynamic_cast<const REveStraightLineSet*>(el);
128  if (m)
129  {
130  TAttLine::operator=(*m);
131  TAttMarker::operator=(*m);
132  fRnrMarkers = m->fRnrMarkers;
133  fRnrLines = m->fRnrLines;
134  fDepthTest = m->fDepthTest;
135  }
136 
137  REveElement::CopyVizParams(el);
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Write visualization parameters.
142 
143 void REveStraightLineSet::WriteVizParams(std::ostream& out, const TString& var)
144 {
145  REveElement::WriteVizParams(out, var);
146 
147  TString t = " " + var + "->";
148  TAttMarker::SaveMarkerAttributes(out, var);
149  TAttLine ::SaveLineAttributes (out, var);
150  out << t << "SetRnrMarkers(" << ToString(fRnrMarkers) << ");\n";
151  out << t << "SetRnrLines(" << ToString(fRnrLines) << ");\n";
152  out << t << "SetDepthTest(" << ToString(fDepthTest) << ");\n";
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 /// Fill core part of JSON representation.
157 
158 Int_t REveStraightLineSet::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
159 {
160  Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
161 
162  j["fLinePlexSize"] = fLinePlex.Size();
163  j["fMarkerPlexSize"] = fMarkerPlex.Size();
164  j["fLineWidth"] = fLineWidth;
165  j["fLineStyle"] = fLineStyle;
166  j["fMarkerSize"] = fMarkerSize;
167  j["fMarkerStyle"] = fMarkerStyle;
168  j["fSecondarySelect"] = false;
169  // printf("REveStraightLineSet::WriteCoreJson %d \n", ret);
170  return ret;
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Crates 3D point array for rendering.
175 
176 void REveStraightLineSet::BuildRenderData()
177 {
178  int nVertices = fLinePlex.Size() * 2 + fMarkerPlex.Size();
179  fRenderData = std::make_unique<REveRenderData>("makeStraightLineSet", 3 * nVertices, 0, nVertices);
180 
181  // printf("REveStraightLineSet::BuildRenderData id = %d \n", GetElementId());
182  REveChunkManager::iterator li(fLinePlex);
183  while (li.next())
184  {
185  Line_t *l = (Line_t*) li();
186 
187  fRenderData->PushV(l->fV1[0], l->fV1[1],l->fV1[2]);
188  fRenderData->PushV(l->fV2[0], l->fV2[1],l->fV2[2]);
189  fRenderData->PushI(l->fId);
190  }
191 
192 
193  REveChunkManager::iterator mi(fMarkerPlex);
194  while (mi.next())
195  {
196  Marker_t *m = (Marker_t*) mi();
197  fRenderData->PushV(m->fV[0], m->fV[1], m->fV[2]);
198  fRenderData->PushI(m->fLineId);
199  }
200 
201  REveElement::BuildRenderData();
202 
203  // printf("REveStraightLineSet::BuildRenderData size= %d\n", fRenderData->GetBinarySize());
204 }
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 /// Return class of projected object.
208 /// Virtual from REveProjectable.
209 
210 TClass* REveStraightLineSet::ProjectedClass(const REveProjection*) const
211 {
212  return TClass::GetClass<REveStraightLineSetProjected>();
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Compute bounding-box.
217 /// Virtual from TAttBBox.
218 
219 void REveStraightLineSet::ComputeBBox()
220 {
221  if (fLinePlex.Size() == 0 && fMarkerPlex.Size() == 0) {
222  BBoxZero();
223  return;
224  }
225 
226  BBoxInit();
227 
228  REveChunkManager::iterator li(fLinePlex);
229  while (li.next()) {
230  BBoxCheckPoint(((Line_t*)li())->fV1);
231  BBoxCheckPoint(((Line_t*)li())->fV2);
232  }
233 
234  REveChunkManager::iterator mi(fMarkerPlex);
235  while (mi.next())
236  {
237  BBoxCheckPoint(((Marker_t*)mi())->fV);
238  }
239 }
240 
241 
242 /** \class REveStraightLineSetProjected
243 \ingroup REve
244 Projected replica of a REveStraightLineSet.
245 */
246 
247 ClassImp(REveStraightLineSetProjected);
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 /// Constructor.
251 
252 REveStraightLineSetProjected::REveStraightLineSetProjected() :
253  REveStraightLineSet(), REveProjected ()
254 {
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Set projection manager and model object.
259 
260 void REveStraightLineSetProjected::SetProjection(REveProjectionManager* mng,
261  REveProjectable* model)
262 {
263  REveProjected::SetProjection(mng, model);
264 
265  CopyVizParams(dynamic_cast<REveElement*>(model));
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Set depth (z-coordinate) of the projected points.
270 
271 void REveStraightLineSetProjected::SetDepthLocal(Float_t d)
272 {
273  SetDepthCommon(d, this, fBBox);
274 
275  REveChunkManager::iterator li(fLinePlex);
276  while (li.next())
277  {
278  REveStraightLineSet::Line_t& l = * (REveStraightLineSet::Line_t*) li();
279  l.fV1[2] = fDepth;
280  l.fV2[2] = fDepth;
281  }
282 
283  REveChunkManager::iterator mi(fMarkerPlex);
284  while (mi.next())
285  {
286  Marker_t& m = * (Marker_t*) mi();
287  m.fV[2] = fDepth;
288  }
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Callback that actually performs the projection.
293 /// Called when projection parameters have been updated.
294 
295 void REveStraightLineSetProjected::UpdateProjection()
296 {
297  REveProjection& proj = * fManager->GetProjection();
298  REveStraightLineSet& orig = * dynamic_cast<REveStraightLineSet*>(fProjectable);
299 
300  REveTrans *trans = orig.PtrMainTrans(kFALSE);
301 
302  BBoxClear();
303 
304  // Lines
305  Int_t num_lines = orig.GetLinePlex().Size();
306  if (proj.HasSeveralSubSpaces())
307  num_lines += TMath::Max(1, num_lines/10);
308  fLinePlex.Reset(sizeof(Line_t), num_lines);
309  REveVector p1, p2;
310  REveChunkManager::iterator li(orig.GetLinePlex());
311  while (li.next())
312  {
313  Line_t *l = (Line_t*) li();
314 
315  proj.ProjectPointfv(trans, l->fV1, p1, fDepth);
316  proj.ProjectPointfv(trans, l->fV2, p2, fDepth);
317 
318  if (proj.AcceptSegment(p1, p2, 0.1f))
319  {
320  AddLine(p1, p2)->fId = l->fId;
321  }
322  else
323  {
324  REveVector bp1(l->fV1), bp2(l->fV2);
325  if (trans) {
326  trans->MultiplyIP(bp1);
327  trans->MultiplyIP(bp2);
328  }
329  proj.BisectBreakPoint(bp1, bp2, kTRUE, fDepth);
330 
331  AddLine(p1, bp1)->fId = l->fId;
332  AddLine(bp2, p2)->fId = l->fId;
333  }
334  }
335  if (proj.HasSeveralSubSpaces())
336  fLinePlex.Refit();
337 
338  // Markers
339  fMarkerPlex.Reset(sizeof(Marker_t), orig.GetMarkerPlex().Size());
340  REveChunkManager::iterator mi(orig.GetMarkerPlex());
341  REveVector pp;
342  while (mi.next())
343  {
344  Marker_t &m = * (Marker_t*) mi();
345 
346  proj.ProjectPointfv(trans, m.fV, pp, fDepth);
347  AddMarker(pp, m.fLineId);
348  }
349 }