Candidate.h
Go to the documentation of this file.
1#ifndef CANDIDATE_HEADER
2#define CANDIDATE_HEADER
3#include <algorithm>
4#include <limits>
5
6#include "Octree.h"
7#include "PrimitiveShape.h"
8#include "ScoreComputer.h"
10#include <MiscLib/Random.h>
11#include <MiscLib/RefCountPtr.h>
12#include <MiscLib/RefCounted.h>
13#include <MiscLib/Vector.h>
14
15#ifndef DLL_LINKAGE
16#define DLL_LINKAGE
17#endif
18
20{
21public:
22 Candidate();
23 Candidate(PrimitiveShape* shape, size_t level);
24
27 {
28 return m_shape;
29 }
30
31 void
33 {
34 m_shape = shape;
35 }
36
37 float
38 LowerBound() const
39 {
40 return m_lowerBound;
41 }
42
43 float
44 UpperBound() const
45 {
46 return m_upperBound;
47 }
48
51 {
52 return m_indices;
53 }
54
55 void
57 {
58 m_indices = indices;
59 }
60
61 size_t
63 {
64 return m_subset;
65 }
66
67 float
69 {
70 return (m_lowerBound + m_upperBound) / 2.f;
71 }
72
73 void
74 SetSubset(size_t subset)
75 {
76 m_subset = subset;
77 }
78
79 size_t
80 Level() const
81 {
82 return m_level;
83 }
84
85 void Reset();
86 template <class ScoreVisitorT>
87 bool ImproveBounds(const MiscLib::Vector<ImmediateOctreeType*>& octrees,
88 const PointCloud& pc,
89 ScoreVisitorT& scoreVisitor,
90 size_t currentSize,
91 float bitmapEpsilon,
92 size_t maxSubset,
93 size_t minPoints = 500);
94 template <class ScoreVisitorT>
95 void RecomputeBounds(const MiscLib::Vector<ImmediateOctreeType*>& octrees,
96 const PointCloud& pc,
97 ScoreVisitorT& scoreVisitor,
98 size_t currentSize,
99 float epsilon,
100 float normalThresh,
101 float bitmapEpsilon);
102 void Reindex(const MiscLib::Vector<int>& newIndices,
103 int minInvalidIndex,
104 size_t mergedSubsets,
105 const MiscLib::Vector<size_t>& subsetSizes,
106 const PointCloud& pc,
107 size_t currentSize,
108 float epsilon,
109 float normalThresh,
110 float bitmapEpsilon);
111 void Reindex(const MiscLib::Vector<size_t>& reindex);
112 template <class ScoreVisitorT>
113 void GlobalScore(ScoreVisitorT& scoreVisitor, const IndexedOctreeType& oct);
114 float WeightedScore(const PointCloud& pc, float epsilon, float normalThresh) const;
115 void ConnectedComponent(const PointCloud& pc, float bitmapEpsilon, float* borderRatio = 0);
116 template <class ScoreVisitorT>
117 float GlobalWeightedScore(ScoreVisitorT& scoreVisitor,
118 const IndexedOctreeType& oct,
119 const PointCloud& pc,
120 float epsilon,
121 float normalThresh,
122 float bitmapEpsilon);
123 inline bool operator<(const Candidate& c) const;
124 inline bool operator>(const Candidate& c) const;
125 inline bool operator<=(const Candidate& c) const;
126 inline bool operator>=(const Candidate& c) const;
127 inline void Clone(Candidate* c) const;
128 bool
129 IsEquivalent(const Candidate& c, const PointCloud& pc, float epsilon, float normalThresh) const;
130
131 size_t
132 Size() const
133 {
134 return m_indices->size();
135 }
136
137private:
138 inline void GetBounds(size_t sampledPoints, size_t totalPoints);
139 inline void Induct(double totalSize,
140 double sampleSize,
141 double totalCorrectSize,
142 float* lower,
143 float* upper) const;
144 inline void Deduct(double totalSize,
145 double sampleSize,
146 double totalCorrectSize,
147 float* lower,
148 float* upper) const;
149
150 void GetScore(const PointCloud& pc, float bitmapEpsilon, bool doFiltering);
151 void GetScoreMaxCCSize(const PointCloud& pc, float bitmapEpsilon, bool doFiltering);
152 void GetScoreMaxCCMinBorder(const PointCloud& pc, float bitmapEpsilon, bool doFiltering);
153
154 float GetVariance(const PointCloud& pc);
155 float GetPseudoVariance(const PointCloud& pc);
156
157private:
159 size_t m_subset;
160 float m_lowerBound;
161 float m_upperBound;
163 size_t m_level;
164 bool m_hasConnectedComponent;
165 size_t m_score;
166};
167
168bool
169Candidate::operator<(const Candidate& c) const
170{
171 return ExpectedValue() < c.ExpectedValue();
172}
173
174bool
176{
177 return ExpectedValue() > c.ExpectedValue();
178}
179
180bool
182{
183 return ExpectedValue() <= c.ExpectedValue();
184}
185
186bool
188{
189 return ExpectedValue() >= c.ExpectedValue();
190}
191
192void
194{
195 c->m_shape = m_shape->Clone();
196 c->m_shape->Release();
197 c->m_subset = m_subset;
198 c->m_lowerBound = m_lowerBound;
199 c->m_upperBound = m_upperBound;
200 c->m_indices = new MiscLib::RefCounted<MiscLib::Vector<size_t>>(*m_indices);
201 c->m_indices->Release();
202 c->m_level = m_level;
203 ;
204 c->m_hasConnectedComponent = m_hasConnectedComponent;
205 c->m_score = m_score;
206}
207
208void
209Candidate::GetBounds(size_t sampledPoints, size_t totalPoints)
210{
211 Induct(
212 (double)totalPoints, (double)sampledPoints, (double)m_score, &m_lowerBound, &m_upperBound);
213 m_lowerBound = std::max(0.f, m_lowerBound);
214}
215
216void
217Candidate::Induct(double totalSize,
218 double sampleSize,
219 double totalCorrectSize,
220 float* lower,
221 float* upper) const
222{
223 Deduct(-2.0 - sampleSize, -2.0 - totalSize, -1.0 - totalCorrectSize, lower, upper);
224 *lower = -1.f - *lower;
225 *upper = -1.f - *upper;
226}
227
228void
229Candidate::Deduct(double totalSize,
230 double sampleSize,
231 double totalCorrectSize,
232 float* lower,
233 float* upper) const
234{
235 double nI = sampleSize * totalCorrectSize;
236 double denom = nI * (totalSize - sampleSize) * (totalSize - totalCorrectSize);
237 double frac = denom / (totalSize - 1);
238 double dev = std::sqrt(frac);
239 *lower = float((nI - dev) / totalSize); // 95% quantile
240 *upper = float((nI + dev) / totalSize); // 95% quantile
241}
242
243template <class ScoreVisitorT>
244bool
246 const PointCloud& pc,
247 ScoreVisitorT& scoreVisitor,
248 size_t currentSize,
249 float bitmapEpsilon,
250 size_t maxSubset,
251 size_t minPoints)
252{
253 if (m_subset >= maxSubset)
254 {
255 return false;
256 }
257 if (m_subset >= octrees.size())
258 {
259 return false;
260 }
261
262 size_t sampledPoints = 0;
263 for (size_t i = 0; i < m_subset; ++i)
264 {
265 sampledPoints += octrees[i]->size();
266 }
267
268 size_t newlySampledPoints = 0;
269 scoreVisitor.SetIndices(m_indices);
270 do
271 {
272 scoreVisitor.SetOctree(*octrees[m_subset]);
273 m_shape->Visit(&scoreVisitor);
274 newlySampledPoints += octrees[m_subset]->size();
275 sampledPoints += octrees[m_subset]->size();
276 ++m_subset;
277 } while (m_subset < octrees.size() && newlySampledPoints < minPoints);
278
279 m_score = m_indices->size();
280 GetBounds(sampledPoints, currentSize);
281
282 // check if connected component is worthwhile
283 if (m_subset == 1)
284 {
285 return true;
286 }
287 if (m_hasConnectedComponent ||
288 (2.f * (m_upperBound - (m_lowerBound / .7f)) / (m_upperBound + (m_lowerBound / .7f))) < .3f)
289 {
290 if (!m_hasConnectedComponent && m_indices->size() < 2)
291 {
292 return true;
293 }
294 m_hasConnectedComponent = true;
295 m_score = m_shape->ConnectedComponent(
296 pc, (4 << ((octrees.size() - m_subset) / 2)) * bitmapEpsilon, m_indices, false);
297 m_indices->resize(m_score);
298 if (m_subset >= octrees.size())
299 {
300 GetScore(pc, bitmapEpsilon, true);
301 m_upperBound = m_lowerBound = m_score;
302 return true;
303 }
304 GetScore(pc, (2 << ((octrees.size() - m_subset) / 2)) * bitmapEpsilon, false);
305
306 GetBounds(sampledPoints, currentSize);
307 }
308 return true;
309}
310
311template <class ScoreVisitorT>
312void
314 const PointCloud& pc,
315 ScoreVisitorT& scoreVisitor,
316 size_t currentSize,
317 float epsilon,
318 float normalThresh,
319 float bitmapEpsilon)
320{
321 // run over indices and check if still unassigned
322 const MiscLib::Vector<int>& shapeIndex = scoreVisitor.GetShapeIndex();
323 size_t indicesSize = m_indices->size();
324 for (size_t i = 0; i < indicesSize;)
325 {
326 if (shapeIndex[(*m_indices)[i]] != -1)
327 {
328 --indicesSize;
329 std::swap((*m_indices)[i], (*m_indices)[indicesSize]);
330 }
331 else
332 {
333 ++i;
334 }
335 }
336
337 m_score = indicesSize;
338
339 if (m_hasConnectedComponent)
340 {
341 if (m_indices->size() != indicesSize) // dirty!
342 {
343 if ((float)indicesSize / m_indices->size() > 0.95)
344 {
345 m_indices->resize(indicesSize);
346
347 GetScore(pc,
348 m_subset >= octrees.size()
349 ? bitmapEpsilon
350 : (4 << ((octrees.size() - m_subset) / 2)) * bitmapEpsilon,
351 m_subset >= octrees.size());
352
353 if (m_subset >= octrees.size())
354 {
355 m_upperBound = m_lowerBound = (float)m_indices->size();
356 return;
357 }
358 // reevaluate bounds
359 }
360 else
361 {
362 m_subset = 0;
363 m_hasConnectedComponent = false;
364 m_indices->clear();
365 m_score = 0;
366 ImproveBounds(octrees, pc, scoreVisitor, currentSize, bitmapEpsilon, 1);
367 return;
368 }
369 }
370 else if (m_subset > octrees.size())
371 {
372 return;
373 }
374 // reevaluate bounds
375 }
376 else
377 {
378 m_indices->resize(indicesSize);
379 m_score = m_indices->size();
380 }
381 size_t sampledPoints = 0, endi = std::min(m_subset, octrees.size());
382 for (size_t i = 0; i < endi; ++i)
383 {
384 sampledPoints += octrees[i]->size();
385 }
386
387 GetBounds(sampledPoints, currentSize);
388}
389
390template <class ScoreVisitorT>
391void
392Candidate::GlobalScore(ScoreVisitorT& scoreVisitor, const IndexedOctreeType& oct)
393{
394 m_indices->clear();
395 scoreVisitor.SetOctree(oct);
396 scoreVisitor.SetIndices(m_indices);
397 m_shape->Visit(&scoreVisitor);
398 m_lowerBound = m_upperBound = (float)m_indices->size();
399}
400
401template <class ScoreVisitorT>
402float
403Candidate::GlobalWeightedScore(ScoreVisitorT& scoreVisitor,
404 const IndexedOctreeType& oct,
405 const PointCloud& pc,
406 float epsilon,
407 float normalThresh,
408 float bitmapEpsilon)
409{
410 GlobalScore(scoreVisitor, oct);
411 ConnectedComponent(pc, bitmapEpsilon);
412 return WeightedScore(pc, epsilon, normalThresh);
413}
414
415#endif
#define float
Definition 16_Level.h:22
GfxTL::AACubeTree< 3, ScoreAACubeTreeStrategy< 3, RebuildAACubeTreeStrategy< GfxTL::BucketSizeMaxLevelSubdivisionTreeStrategy< GfxTL::CellLevelTreeStrategy< GfxTL::CellCenterAACubeTreeStrategy< 3, GfxTL::BaseAACubeTreeStrategy< GfxTL::CellRangeDataTreeStrategy< GfxTL::NullTreeStrategy, GfxTL::IteratedIndexedIteratorTreeDataKernel< MiscLib::Vector< size_t >::iterator, PointCloud::const_iterator > > > > > > > > > IndexedOctreeType
Definition Octree.h:44
constexpr T c
#define DLL_LINKAGE
Definition basic.h:12
bool operator>=(const Candidate &c) const
Definition Candidate.h:187
PrimitiveShape * Shape()
Definition Candidate.h:26
void GlobalScore(ScoreVisitorT &scoreVisitor, const IndexedOctreeType &oct)
Definition Candidate.h:392
float UpperBound() const
Definition Candidate.h:44
MiscLib::RefCounted< MiscLib::Vector< size_t > > * Indices()
Definition Candidate.h:50
bool operator<(const Candidate &c) const
Definition Candidate.h:169
float LowerBound() const
Definition Candidate.h:38
size_t Size() const
Definition Candidate.h:132
bool operator<=(const Candidate &c) const
Definition Candidate.h:181
size_t Level() const
Definition Candidate.h:80
void ConnectedComponent(const PointCloud &pc, float bitmapEpsilon, float *borderRatio=0)
void Shape(PrimitiveShape *shape)
Definition Candidate.h:32
float ExpectedValue() const
Definition Candidate.h:68
size_t ComputedSubsets() const
Definition Candidate.h:62
void Indices(MiscLib::RefCounted< MiscLib::Vector< size_t > > *indices)
Definition Candidate.h:56
bool operator>(const Candidate &c) const
Definition Candidate.h:175
float WeightedScore(const PointCloud &pc, float epsilon, float normalThresh) const
Definition Candidate.cpp:88
void SetSubset(size_t subset)
Definition Candidate.h:74
void RecomputeBounds(const MiscLib::Vector< ImmediateOctreeType * > &octrees, const PointCloud &pc, ScoreVisitorT &scoreVisitor, size_t currentSize, float epsilon, float normalThresh, float bitmapEpsilon)
Definition Candidate.h:313
void Clone(Candidate *c) const
Definition Candidate.h:193
bool ImproveBounds(const MiscLib::Vector< ImmediateOctreeType * > &octrees, const PointCloud &pc, ScoreVisitorT &scoreVisitor, size_t currentSize, float bitmapEpsilon, size_t maxSubset, size_t minPoints=500)
Definition Candidate.h:245
float GlobalWeightedScore(ScoreVisitorT &scoreVisitor, const IndexedOctreeType &oct, const PointCloud &pc, float epsilon, float normalThresh, float bitmapEpsilon)
Definition Candidate.h:403
size_type size() const
Definition Vector.h:215
PrimtiveShape is a shape primitive in conjunction with a parametrization.