SpherePrimitiveShape.cpp
Go to the documentation of this file.
2
3#include <fstream>
4#include <iostream>
5#include <sstream>
6
7#include "Bitmap.h"
8#include "IndexIterator.h"
11#include <GfxTL/AABox.h>
17#include <GfxTL/Covariance.h>
21#include <GfxTL/Jacobi.h>
22#include <GfxTL/KdTree.h>
23#include <GfxTL/L2Norm.h>
25#include <GfxTL/Mean.h>
27#include <GfxTL/NullClass.h>
29#include <GfxTL/VectorKernel.h>
30#include <MiscLib/Performance.h>
32
34 m_sphere(s), m_parametrization(m_sphere)
35{
36}
37
39 BitmapPrimitiveShape(sps), m_sphere(sps.m_sphere), m_parametrization(sps.m_parametrization)
40{
41 m_parametrization.Shape(m_sphere);
42}
43
44size_t
46{
47 return 1;
48}
49
50bool
51SpherePrimitiveShape::Init(bool binary, std::istream* i)
52{
53 // read the polygons but ignore them
54 GfxTL::AABox<GfxTL::Vector2Df> bboxUpper, bboxLower;
55 size_t upperuextent, uppervextent, loweruextent, lowervextent;
56 if (binary)
57 {
58 // read number of components
59 size_t size;
60 i->read((char*)&size, sizeof(size));
61 if (size)
62 {
63 // read upper bbox
64 i->read((char*)&bboxUpper, sizeof(bboxUpper));
65 // read upperuextent and uppervextent
66 i->read((char*)&upperuextent, sizeof(upperuextent));
67 i->read((char*)&uppervextent, sizeof(uppervextent));
68 for (size_t j = 0; j < size; ++j)
69 {
70 // read number of polys of component
71 size_t numPolys;
72 i->read((char*)&numPolys, sizeof(numPolys));
73 for (size_t k = 0; k < numPolys; ++k)
74 {
75 // read number of points in poly
76 size_t numPoints;
77 i->read((char*)&numPoints, sizeof(numPoints));
79 for (size_t l = 0; l < numPoints; ++l)
80 {
81 i->read((char*)&pp, sizeof(pp));
82 }
83 }
84 }
85 }
86 // do the same for lower bitmap
87 // read number of components
88 i->read((char*)&size, sizeof(size));
89 if (size)
90 {
91 // read lower bbox
92 i->read((char*)&bboxLower, sizeof(bboxLower));
93 // read loweruextent and lowervextent
94 i->read((char*)&loweruextent, sizeof(loweruextent));
95 i->read((char*)&lowervextent, sizeof(lowervextent));
96 for (size_t j = 0; j < size; ++j)
97 {
98 // read number of polys of component
99 size_t numPolys;
100 i->read((char*)&numPolys, sizeof(numPolys));
101 for (size_t k = 0; k < numPolys; ++k)
102 {
103 // read number of points in poly
104 size_t numPoints;
105 i->read((char*)&numPoints, sizeof(numPoints));
107 for (size_t l = 0; l < numPoints; ++l)
108 {
109 i->read((char*)&pp, sizeof(pp));
110 }
111 }
112 }
113 }
114 }
115 else
116 {
117 // read number of components
118 size_t size;
119 (*i) >> size;
120 if (size)
121 {
122 // read upper bbox
123 (*i) >> bboxUpper.Min()[0] >> bboxUpper.Max()[0] >> bboxUpper.Min()[1] >>
124 bboxUpper.Max()[1];
125 // read upperuextent and uppervextent
126 (*i) >> upperuextent >> uppervextent;
127 for (size_t j = 0; j < size; ++j)
128 {
129 // read number of polys of component
130 size_t numPolys;
131 (*i) >> numPolys;
132 for (size_t k = 0; k < numPolys; ++k)
133 {
134 // read number of points in poly
135 size_t numPoints;
136 (*i) >> numPoints;
138 for (size_t l = 0; l < numPoints; ++l)
139 {
140 (*i) >> pp[0] >> pp[1];
141 }
142 }
143 }
144 }
145 // read number of components
146 (*i) >> size;
147 if (size)
148 {
149 // read lower bbox
150 (*i) >> bboxLower.Min()[0] >> bboxLower.Max()[0] >> bboxLower.Min()[1] >>
151 bboxLower.Max()[1];
152 // read loweruextent and lowervextent
153 (*i) >> loweruextent >> lowervextent;
154 for (size_t j = 0; j < size; ++j)
155 {
156 // read number of polys of component
157 size_t numPolys;
158 (*i) >> numPolys;
159 for (size_t k = 0; k < numPolys; ++k)
160 {
161 // read number of points in poly
162 size_t numPoints;
163 (*i) >> numPoints;
165 for (size_t l = 0; l < numPoints; ++l)
166 {
167 (*i) >> pp[0] >> pp[1];
168 }
169 }
170 }
171 }
172 }
173 return true;
174}
175
178{
179 return new SpherePrimitiveShape(*this);
180}
181
182float
184{
185 return m_sphere.Distance(p);
186}
187
188float
190{
191 return m_sphere.SignedDistance(p);
192}
193
194float
196{
197 Vec3f normal;
198 m_sphere.Normal(p, &normal);
199 return n.dot(normal);
200}
201
202void
204 const Vec3f& n,
205 std::pair<float, float>* dn) const
206{
207 Vec3f normal;
208 dn->first = m_sphere.DistanceAndNormal(p, &normal);
209 dn->second = n.dot(normal);
210}
211
212void
214{
215 m_sphere.Project(p, pp);
216}
217
218void
220{
221 m_sphere.Normal(p, n);
222}
223
224unsigned int
226 float epsilon,
227 float normalThresh,
228 float rms,
229 const PointCloud& pc,
230 const MiscLib::Vector<size_t>& indices) const
231{
233 numTests, epsilon, normalThresh, rms, pc, indices);
234}
235
236void
238{
239 *s = "Sphere";
240}
241
242bool
244 float epsilon,
245 float normalThresh,
248{
249 // do LS-fitting
250 Sphere fit = m_sphere;
251 if (fit.LeastSquaresFit(pc, begin, end))
252 {
253 m_sphere = fit;
254 m_parametrization.Shape(m_sphere);
255 return true;
256 }
257 return false;
258}
259
262 float epsilon,
263 float normalThresh,
266 std::pair<size_t, float>* score) const
267{
268 // do LS-fitting
269 Sphere fit = m_sphere;
270 if (fit.LeastSquaresFit(pc, begin, end))
271 {
272 score->first = -1;
273 return new SpherePrimitiveShape(fit);
274 }
275 score->first = 0;
276 return NULL;
277}
278
279void
280SpherePrimitiveShape::Serialize(std::ostream* o, bool binary) const
281{
282 if (binary)
283 {
284 const char id = 1;
285 (*o) << id;
286 }
287 else
288 {
289 (*o) << "1"
290 << " ";
291 }
292 m_sphere.Serialize(binary, o);
293 m_parametrization.Serialize(o, binary);
294 if (!binary)
295 {
296 *o << std::endl;
297 }
298}
299
300void
301SpherePrimitiveShape::Deserialize(std::istream* i, bool binary)
302{
303 m_sphere.Init(binary, i);
304 m_parametrization.Shape(m_sphere);
305 m_parametrization.Deserialize(i, binary);
306}
307
308size_t
310{
311 return m_sphere.SerializedSize() + m_parametrization.SerializedSize() + 1;
312}
313
316{
317 return new SphereLevMarFunc(m_sphere);
318}
319
320void
321SpherePrimitiveShape::Transform(float scale, const Vec3f& translate)
322{
323 m_sphere.Transform(scale, translate);
324}
325
326void
328{
329 visitor->Visit(*this);
330}
331
332void
334 const PointCloud& pc,
337 float distThresh,
339{
340 // sample the bounding box in parameter space at 25 locations
341 // these points are used to estimate the other shapes
342 // if the shapes succeed the suggestion is returned
344 samples.resize(2 * 25);
345 size_t c = samples.size() / 2;
346 float uStep = (m_extBbox.Max()[0] - m_extBbox.Min()[0]) / 4;
347 float vStep = (m_extBbox.Max()[1] - m_extBbox.Min()[1]) / 4;
348 float u = m_extBbox.Min()[0];
349 for (unsigned int i = 0; i < 5; ++i, u += uStep)
350 {
351 float v = m_extBbox.Min()[1];
352 for (unsigned int j = 0; j < 5; ++j, v += vStep)
353 m_parametrization.InSpace(u, v, &samples[i * 5 + j], &samples[i * 5 + j + c]);
354 }
355
356 Plane plane;
357 if (plane.LeastSquaresFit(samples.begin(), samples.begin() + c))
358 {
359 bool failed = false;
360 for (size_t i = 0; i < c; ++i)
361 if (plane.Distance(samples[i]) > distThresh)
362 {
363 failed = true;
364 break;
365 }
366 if (!failed)
367 {
368 suggestions->push_back(new PlanePrimitiveShape(plane));
369 suggestions->back()->Release();
370 }
371 }
372
373 /*// we suggest a plane if the radius is large enough so that the error
374 // along the two directions is less than distThresh
375 float ulength = 0, vlength = 0;
376 if(m_hasBitmap.first)
377 {
378 // has points on the upper side
379 ulength = m_extBboxUpper.Max()[0] - m_extBboxUpper.Min()[0];
380 vlength = m_extBboxUpper.Max()[1] - m_extBboxUpper.Min()[1];
381 }
382 if(m_hasBitmap.second)
383 {
384 ulength += m_extBboxLower.Max()[0] - m_extBboxLower.Min()[0];
385 vlength += m_extBboxLower.Max()[1] - m_extBboxLower.Min()[1];
386 }
387 float arcLength = M_PI * std::max(ulength, vlength);
388 float radiusDiff = (m_sphere.Radius() - std::sin(arcLength / 2)
389 * m_sphere.Radius()) / 2;
390 if(radiusDiff < distThresh)
391 {
392 Vec3f pos, normal;
393 SphereAsSquaresParametrization ssp(m_sphere, m_parametrizationNormal);
394 if(m_hasBitmap.first && m_hasBitmap.second)
395 {
396 GfxTL::Vector3Df center, eigenValues;
397 GfxTL::Mean(GfxTL::IndexIterate(begin, pc.begin()),
398 GfxTL::IndexIterate(end, pc.begin()), &center);
399 GfxTL::MatrixXX< 3, 3, float > cov, eigenVectors;
400 GfxTL::CovarianceMatrix(center, GfxTL::IndexIterate(begin, pc.begin()),
401 GfxTL::IndexIterate(end, pc.begin()), &cov);
402 GfxTL::Jacobi(cov, &eigenValues, &eigenVectors);
403 GfxTL::EigSortDesc(&eigenValues, &eigenVectors);
404 GfxTL::Vector3Df n = GfxTL::Vector3Df(eigenVectors[2]);
405 Plane plane(Vec3f(center.Data()), Vec3f(n.Data()));
406 suggestions->push_back(new PlanePrimitiveShape(plane));
407 suggestions->back()->Release();
408 }
409 else if(m_hasBitmap.first)
410 {
411 GfxTL::Vector2Df center;
412 m_extBboxUpper.Center(&center);
413 ssp.InSpace(std::make_pair(center[0], center[1]), false, &pos, &normal);
414 // offset position
415 pos -= radiusDiff * normal;
416 Plane plane(pos, normal);
417 suggestions->push_back(new PlanePrimitiveShape(plane));
418 suggestions->back()->Release();
419 }
420 else if(m_hasBitmap.second)
421 {
422 GfxTL::Vector2Df center;
423 m_extBboxUpper.Center(&center);
424 ssp.InSpace(std::make_pair(center[0], center[1]), true, &pos, &normal);
425 // offset position
426 pos -= radiusDiff * normal;
427 Plane plane(pos, normal);
428 suggestions->push_back(new PlanePrimitiveShape(plane));
429 suggestions->back()->Release();
430 }
431 }*/
432}
433
434void
438 float epsilon)
439{
440 m_parametrization.Optimize(
441 GfxTL::IndexIterate(begin, pc.begin()), GfxTL::IndexIterate(end, pc.begin()), epsilon);
442}
443
444void
446 size_t begin,
447 size_t end,
448 float epsilon)
449{
450 m_parametrization.Optimize(GfxTL::IndexIterate(IndexIterator(begin), pc.begin()),
452 epsilon);
453}
454
455bool
456SpherePrimitiveShape::Similar(float tolerance, const SpherePrimitiveShape& shape) const
457{
458 return m_sphere.Radius() <= (1.f + tolerance) * shape.m_sphere.Radius() &&
459 (1.f + tolerance) * m_sphere.Radius() >= shape.m_sphere.Radius();
460}
461
462void
463SpherePrimitiveShape::Parameters(const Vec3f& p, std::pair<float, float>* param) const
464{
465 m_parametrization.Parameters(p, param);
466}
467
468void
476
477void
481 MiscLib::Vector<std::pair<float, float>>* bmpParams) const
482{
483 ParametersImpl(begin, end, bmpParams);
484}
485
486bool
487SpherePrimitiveShape::InSpace(float u, float v, Vec3f* p, Vec3f* n) const
488{
489 return m_parametrization.InSpace(u, v, p, n);
490}
491
492void
495 MiscLib::Vector<std::pair<float, float>>* params,
496 size_t* uextent,
497 size_t* vextent)
498{
499 *uextent = std::ceil((bbox->Max()[0] - bbox->Min()[0]) / epsilon);
500 *vextent = std::ceil((bbox->Max()[1] - bbox->Min()[1]) / epsilon);
501}
502
503void
504SpherePrimitiveShape::InBitmap(const std::pair<float, float>& param,
505 float epsilon,
507 size_t uextent,
508 size_t vextent,
509 std::pair<int, int>* inBmp) const
510{
511 inBmp->first = std::floor((param.first - bbox.Min()[0]) / epsilon);
512 inBmp->second = std::floor((param.second - bbox.Min()[1]) / epsilon);
513}
514
515void
517 float epsilon,
518 bool* uwrap,
519 bool* vwrap) const
520{
521 m_parametrization.WrapBitmap(bbox, epsilon, uwrap, vwrap);
522}
523
524void
526 float epsilon,
527 size_t uextent,
528 size_t vextent,
529 MiscLib::Vector<int>* componentImg,
530 MiscLib::Vector<std::pair<int, size_t>>* labels) const
531{
532 m_parametrization.WrapComponents(bbox, epsilon, uextent, vextent, componentImg, labels);
533}
534
535bool
537 size_t v,
538 float epsilon,
540 size_t uextent,
541 size_t vextent,
542 Vec3f* p,
543 Vec3f* n) const
544{
545 return m_parametrization.InSpace(
546 (u + .5f) * epsilon + bbox.Min()[0], (v + .5f) * epsilon + bbox.Min()[1], p, n);
547}
class DLL_LINKAGE PlanePrimitiveShape
MiscLib::performance_t totalTime_sphereConnected
constexpr T c
unsigned int ConfidenceTests(unsigned int numTests, float epsilon, float normalThresh, float rms, const PointCloud &pc, const MiscLib::Vector< size_t > &indices) const
GfxTL::AABox< GfxTL::Vector2Df > m_extBbox
Point & Min()
Definition AABox.hpp:68
Point & Max()
Definition AABox.hpp:82
void resize(size_type s, const value_type &v)
Definition Vector.h:227
const Point * const_iterator
Definition Vector.h:25
size_type size() const
Definition Vector.h:215
Definition Plane.h:19
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Plane.cpp:200
float Distance(const Vec3f &pos) const
Definition Plane.h:47
virtual void Visit(const PlanePrimitiveShape &plane)=0
PrimtiveShape is a shape primitive in conjunction with a parametrization.
bool Similar(float tolerance, const SpherePrimitiveShape &shape) const
void WrapComponents(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< int > *componentImg, MiscLib::Vector< std::pair< int, size_t > > *labels) const
void DistanceAndNormalDeviation(const Vec3f &p, const Vec3f &n, std::pair< float, float > *dn) const
void Deserialize(std::istream *i, bool binary)
unsigned int ConfidenceTests(unsigned int numTests, float epsilon, float normalThresh, float rms, const PointCloud &pc, const MiscLib::Vector< size_t > &indices) const
float SignedDistance(const Vec3f &p) const
float NormalDeviation(const Vec3f &p, const Vec3f &n) const
bool Init(bool binary, std::istream *i)
PrimitiveShape * Clone() const
void Normal(const Vec3f &p, Vec3f *n) const
void SuggestSimplifications(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end, float distThresh, MiscLib::Vector< MiscLib::RefCountPtr< PrimitiveShape > > *suggestions) const
void InBitmap(const std::pair< float, float > &param, float epsilon, const GfxTL::AABox< GfxTL::Vector2Df > &bbox, size_t uextent, size_t vextent, std::pair< int, int > *inBmp) const
void Transform(float scale, const Vec3f &translate)
PrimitiveShape * LSFit(const PointCloud &pc, float epsilon, float normalThresh, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end, std::pair< size_t, float > *score) const
void Visit(PrimitiveShapeVisitor *visitor) const
void Project(const Vec3f &p, Vec3f *pp) const
void OptimizeParametrization(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end, float epsilon)
LevMarFunc< float > * SignedDistanceFunc() const
bool Fit(const PointCloud &pc, float epsilon, float normalThresh, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
void WrapBitmap(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, bool *uwrap, bool *vwrap) const
float Distance(const Vec3f &p) const
void Serialize(std::ostream *o, bool binary=true) const
This is the one and only serialization function It stores all the parameters of the shape as well as ...
void BitmapExtent(float epsilon, GfxTL::AABox< GfxTL::Vector2Df > *bbox, MiscLib::Vector< std::pair< float, float > > *params, size_t *uextent, size_t *vextent)
void Description(std::string *s) const
void Parameters(const Vec3f &p, std::pair< float, float > *param) const
bool InSpace(float u, float v, Vec3f *p, Vec3f *n) const
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Sphere.cpp:399
float Radius() const
Definition Sphere.cpp:357
Definition basic.h:18
IndexedIterator< IndexIteratorT, IteratorT > IndexIterate(IndexIteratorT idxIt, IteratorT it)
clock_t performance_t
Definition Performance.h:31