ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvIndexedTransformationBuffer.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include "ecvBBox.h"
11 
12 // cloudViewer
13 #include <ParallelSort.h>
14 
16  : ccHObject(name),
17  m_bBoxValidSize(0),
18  m_showAsPolyline(false),
19  m_showTrihedrons(true),
20  m_trihedronsScale(1.0f) {}
21 
23  const ccIndexedTransformationBuffer& buffer)
24  : ccHObject(buffer),
25  m_bBox(buffer.m_bBox),
26  m_bBoxValidSize(buffer.m_bBoxValidSize),
27  m_showAsPolyline(buffer.m_showAsPolyline),
28  m_showTrihedrons(buffer.m_showTrihedrons),
29  m_trihedronsScale(buffer.m_trihedronsScale) {
30  try {
31  this->std::vector<ccIndexedTransformation>::operator=(buffer);
32  } catch (const std::bad_alloc&) {
34  "[ccIndexedTransformationBuffer] Failed to copy original "
35  "content (not enough memory)");
36  }
37 }
38 
40  const ccIndexedTransformation& b) {
41  return a.getIndex() < b.getIndex();
42 }
43 
44 static bool IndexCompOperator(const ccIndexedTransformation& a, double index) {
45  return a.getIndex() < index;
46 }
47 
49  ParallelSort(begin(), end(), IndexedSortOperator);
50 }
51 
53  double index,
54  const ccIndexedTransformation*& trans1,
55  const ccIndexedTransformation*& trans2,
56  size_t* trans1IndexInBuffer,
57  size_t* trans2IndexInBuffer) const {
58  // no transformation in buffer?
59  if (empty()) {
60  return false;
61  }
62 
63  trans1 = trans2 = 0;
64  if (trans1IndexInBuffer) *trans1IndexInBuffer = 0;
65  if (trans2IndexInBuffer) *trans2IndexInBuffer = 0;
66 
67 #if defined(_MSC_VER) && _MSC_VER > 1000
69  tIndex.setIndex(index);
70  ccIndexedTransformationBuffer::const_iterator it =
71  std::lower_bound(begin(), end(), tIndex, IndexedSortOperator);
72 #else
73  ccIndexedTransformationBuffer::const_iterator it =
74  std::lower_bound(begin(), end(), index, IndexCompOperator);
75 #endif
76 
77  // special case: all transformations are BEFORE the input index
78  if (it == end()) {
79  trans1 = &back();
80  if (trans1IndexInBuffer) *trans1IndexInBuffer = size() - 1;
81  return true;
82  }
83 
84  // special case: found transformation's index is equal to input index
85  if (it->getIndex() == index) {
86  trans1 = &(*it);
87  if (trans1IndexInBuffer) *trans1IndexInBuffer = it - begin();
88  ++it;
89  if (it != end()) {
90  trans2 = &(*it);
91  if (trans2IndexInBuffer) *trans2IndexInBuffer = it - begin();
92  }
93  } else {
94  trans2 = &(*it);
95  if (trans2IndexInBuffer) *trans2IndexInBuffer = it - begin();
96  if (it != begin()) {
97  --it;
98  trans1 = &(*it);
99  if (trans1IndexInBuffer) *trans1IndexInBuffer = it - begin();
100  }
101  }
102 
103  return true;
104 }
105 
107  m_bBox.setValidity(false);
108 }
109 
110 ccBBox ccIndexedTransformationBuffer::getOwnBB(bool withGLFeatures /*=false*/) {
111  if (!m_bBox.isValid() || m_bBoxValidSize != size()) {
112  for (ccIndexedTransformationBuffer::const_iterator it = begin();
113  it != end(); ++it)
114  m_bBox.add(it->getTranslationAsVec3D());
115 
116  m_bBoxValidSize = size();
117  }
118 
119  if (!withGLFeatures || !m_showTrihedrons || !m_bBox.isValid()) {
120  return m_bBox;
121  }
122 
123  ccBBox box = m_bBox;
124  box.minCorner() -=
126  box.maxCorner() +=
128 
129  return box;
130 }
131 
133  double index,
135  double maxIndexDistForInterpolation /*=DBL_MAX*/) const {
136  const ccIndexedTransformation *t1 = nullptr, *t2 = nullptr;
137 
138  if (!findNearest(index, t1, t2)) return false;
139 
140  if (t1) {
141  double i1 = t1->getIndex();
142  if (i1 == index) {
143  trans = *t1;
144  } else {
145  assert(i1 < index);
146  if (i1 + maxIndexDistForInterpolation < index) // trans1 is too far
147  return false;
148 
149  if (t2) {
150  double i2 = t2->getIndex();
151  if (i2 - maxIndexDistForInterpolation >
152  index) // trans2 is too far
153  return false;
154 
155  // interpolate
156  trans = ccIndexedTransformation::Interpolate(index, *t1, *t2);
157  } else {
158  // we don't interpolate outside of the buffer 'interval'
159  return false;
160  }
161  }
162  } else if (t2) {
163  if (t2->getIndex() != index) // trans2 is too far
164  return false;
165 
166  trans = *t2;
167  }
168 
169  return true;
170 }
171 
173  short dataVersion) const {
174  assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
175  if (dataVersion < 34) {
176  assert(false);
177  return false;
178  }
179 
180  if (!ccHObject::toFile_MeOnly(out, dataVersion)) return false;
181 
182  // vector size (dataVersion>=34)
183  uint32_t count = static_cast<uint32_t>(size());
184  if (out.write((const char*)&count, 4) < 0) return WriteError();
185 
186  // transformations (dataVersion>=34)
187  for (ccIndexedTransformationBuffer::const_iterator it = begin();
188  it != end(); ++it)
189  if (!it->toFile(out, dataVersion)) return false;
190 
191  // display options
192  {
193  // Show polyline (dataVersion>=34)
194  if (out.write((const char*)&m_showAsPolyline, sizeof(bool)) < 0)
195  return WriteError();
196  // Show trihedrons (dataVersion>=34)
197  if (out.write((const char*)&m_showTrihedrons, sizeof(bool)) < 0)
198  return WriteError();
199  // Display scale (dataVersion>=34)
200  if (out.write((const char*)&m_trihedronsScale, sizeof(float)) < 0)
201  return WriteError();
202  }
203 
204  return true;
205 }
206 
208  short minVersion = std::max(static_cast<short>(34),
210  if (!empty()) {
211  minVersion = std::max(
212  minVersion, front().minimumFileVersion()); // we assume they
213  // are all the same
214  }
215  return minVersion;
216 }
217 
219  QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) {
220  if (!ccHObject::fromFile_MeOnly(in, dataVersion, flags, oldToNewIDMap))
221  return false;
222 
223  // vector size (dataVersion>=34)
224  uint32_t count = 0;
225  if (in.read((char*)&count, 4) < 0) return ReadError();
226 
227  // try to resize the vector accordingly
228  try {
229  resize(count);
230  } catch (const std::bad_alloc&) {
231  // not enough memory
232  return MemoryError();
233  }
234 
235  // transformations (dataVersion>=34)
236  for (ccIndexedTransformationBuffer::iterator it = begin(); it != end();
237  ++it)
238  if (!it->fromFile(in, dataVersion, flags, oldToNewIDMap)) return false;
239 
240  // display options
241  {
242  // Show polyline (dataVersion>=34)
243  if (in.read((char*)&m_showAsPolyline, sizeof(bool)) < 0)
244  return ReadError();
245  // Show trihedrons (dataVersion>=34)
246  if (in.read((char*)&m_showTrihedrons, sizeof(bool)) < 0)
247  return ReadError();
248  // Display scale (dataVersion>=34)
249  if (in.read((char*)&m_trihedronsScale, sizeof(float)) < 0)
250  return ReadError();
251  }
252 
253  return true;
254 }
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
int size
std::string name
int count
#define ParallelSort
Definition: ParallelSort.h:33
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
Bounding box structure.
Definition: ecvBBox.h:25
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual short minimumFileVersion_MeOnly() const
virtual bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap)
Loads own object data.
short minimumFileVersion() const override
Returns the minimum file version required to save this instance.
virtual bool toFile_MeOnly(QFile &out, short dataVersion) const
Save own object data.
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
bool findNearest(double index, const ccIndexedTransformation *&trans1, const ccIndexedTransformation *&trans2, size_t *trans1IndexInBuffer=0, size_t *trans2IndexInBuffer=0) const
Returns the nearest indexed transformation(s) to a given index.
size_t m_bBoxValidSize
Bounding box last 'validity' size.
bool getInterpolatedTransformation(double index, ccIndexedTransformation &trans, double maxIndexDistForInterpolation=DBL_MAX) const
bool m_showTrihedrons
Whether trihedrons should be displayed or not.
ccIndexedTransformationBuffer(QString name=QString("Trans. buffer"))
Default constructor.
void sort()
Sorts transformations based on their index.
float m_trihedronsScale
Trihedrons display scale.
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
void invalidateBoundingBox()
Invalidates the bounding box.
bool m_showAsPolyline
Whether the path should be displayed as a polyline or not.
virtual ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
double getIndex() const
Returns associated index (e.g. timestamp)
static ccIndexedTransformation Interpolate(double interpIndex, const ccIndexedTransformation &trans1, const ccIndexedTransformation &trans2)
Interpolates two transformations at an absolute position (index)
void setIndex(double index)
Sets associated index (e.g. timestamp)
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
static bool MemoryError()
Sends a custom error message (not enough memory) and returns 'false'.
const Vector3Tpl< T > & maxCorner() const
Returns max corner (const)
Definition: BoundingBox.h:156
void setValidity(bool state)
Sets bonding box validity.
Definition: BoundingBox.h:200
const Vector3Tpl< T > & minCorner() const
Returns min corner (const)
Definition: BoundingBox.h:154
bool isValid() const
Returns whether bounding box is valid or not.
Definition: BoundingBox.h:203
void add(const Vector3Tpl< T > &P)
'Enlarges' the bounding box with a point
Definition: BoundingBox.h:131
static bool IndexedSortOperator(const ccIndexedTransformation &a, const ccIndexedTransformation &b)
static bool IndexCompOperator(const ccIndexedTransformation &a, double index)
a[190]