TorusPrimitiveShape.cpp
Go to the documentation of this file.
2
3#include <sstream>
4
10#include <MiscLib/Performance.h>
12
14 m_torus(torus), m_parametrization(m_torus)
15{
16}
17
19 BitmapPrimitiveShape(tps), m_torus(tps.m_torus), m_parametrization(tps.m_parametrization)
20{
21 m_parametrization.Shape(m_torus);
22}
23
24size_t
26{
27 return 4;
28}
29
32{
33 return new TorusPrimitiveShape(*this);
34}
35
36float
38{
39 return m_torus.Distance(p);
40}
41
42float
44{
45 return m_torus.SignedDistance(p);
46}
47
48float
50{
51 Vec3f normal;
52 m_torus.Normal(p, &normal);
53 return n.dot(normal);
54}
55
56void
58 const Vec3f& n,
59 std::pair<float, float>* dn) const
60{
61 Vec3f normal;
62 dn->first = m_torus.DistanceAndNormal(p, &normal);
63 dn->second = n.dot(normal);
64}
65
66void
68{
69 m_torus.Project(p, pp);
70}
71
72void
74{
75 m_torus.Normal(p, n);
76}
77
78unsigned int
80 float epsilon,
81 float normalThresh,
82 float rms,
83 const PointCloud& pc,
84 const MiscLib::Vector<size_t>& indices) const
85{
87 numTests, epsilon, normalThresh, rms, pc, indices);
88}
89
90void
92{
93 std::ostringstream ostr;
94 ostr << "Torus (minor=" << m_torus.MinorRadius() << " major=" << m_torus.MajorRadius() << ")";
95 *s = ostr.str();
96 // *s = "Torus";
97}
98
99bool
101 float epsilon,
102 float normalThresh,
105{
106 Torus fit = m_torus;
107 if (fit.LeastSquaresFit(pc, begin, end))
108 {
109 m_torus = fit;
110 m_parametrization.Shape(m_torus);
111 return true;
112 }
113 return false;
114}
115
118 float epsilon,
119 float normalThresh,
122 std::pair<size_t, float>* score) const
123{
124 Torus fit = m_torus;
125 if (fit.LeastSquaresFit(pc, begin, end))
126 {
127 score->first = -1;
128 return new TorusPrimitiveShape(fit);
129 }
130 score->first = 0;
131 return NULL;
132}
133
136{
137 return new TorusLevMarFunc(m_torus);
138}
139
140void
141TorusPrimitiveShape::Serialize(std::ostream* o, bool binary) const
142{
143 if (binary)
144 {
145 const char id = 4;
146 (*o) << id;
147 }
148 else
149 {
150 (*o) << "4"
151 << " ";
152 }
153 m_torus.Serialize(binary, o);
154 m_parametrization.Serialize(o, binary);
155 if (!binary)
156 {
157 *o << std::endl;
158 }
159}
160
161void
162TorusPrimitiveShape::Deserialize(std::istream* i, bool binary)
163{
164 m_torus.Init(binary, i);
165 m_parametrization.Shape(m_torus);
166 m_parametrization.Deserialize(i, binary);
167}
168
169size_t
171{
172 return m_torus.SerializedSize() + m_parametrization.SerializedSize() + 1;
173}
174
175void
176TorusPrimitiveShape::Transform(float scale, const Vec3f& translate)
177{
178 m_torus.Transform(scale, translate);
179}
180
181void
183{
184 visitor->Visit(*this);
185}
186
187void
189 const PointCloud& pc,
192 float distThresh,
194{
195 // sample the bounding box in parameter space at 25 locations
196 // these points are used to estimate the other shapes
197 // if the shapes succeed the suggestion is returned
198 MiscLib::Vector<Vec3f> samples(2 * 25);
199 float uStep = (m_extBbox.Max()[0] - m_extBbox.Min()[0]) / 4;
200 float vStep = (m_extBbox.Max()[1] - m_extBbox.Min()[1]) / 4;
201 float u = m_extBbox.Min()[0];
202 for (unsigned int i = 0; i < 5; ++i, u += uStep)
203 {
204 float v = m_extBbox.Min()[1];
205 for (unsigned int j = 0; j < 5; ++j, v += vStep)
206 {
207 float bmpu;
208 if (m_torus.MajorRadius() < m_torus.MinorRadius() * 2)
209 {
210 bmpu = u * (m_torus.MajorRadius() + m_torus.MinorRadius());
211 }
212 else
213 {
214 bmpu = u * m_torus.MajorRadius();
215 }
216 InSpace(bmpu, v * m_torus.MinorRadius(), &samples[i * 5 + j], &samples[i * 5 + j + 25]);
217 }
218 }
219 size_t c = samples.size() / 2;
220 // now check all the shape types
221 Cone cone;
222 if (cone.InitAverage(samples))
223 {
224 cone.LeastSquaresFit(samples.begin(), samples.begin() + c);
225 bool failed = false;
226 for (size_t i = 0; i < c; ++i)
227 if (cone.Distance(samples[i]) > distThresh)
228 {
229 failed = true;
230 break;
231 }
232 if (!failed)
233 {
234 suggestions->push_back(new ConePrimitiveShape(cone));
235 suggestions->back()->Release();
236 }
237 }
238 Cylinder cylinder;
239 if (cylinder.InitAverage(samples))
240 {
241 cylinder.LeastSquaresFit(samples.begin(), samples.begin() + c);
242 bool failed = false;
243 for (size_t i = 0; i < c; ++i)
244 if (cylinder.Distance(samples[i]) > distThresh)
245 {
246 failed = true;
247 break;
248 }
249 if (!failed)
250 {
251 suggestions->push_back(new CylinderPrimitiveShape(cylinder));
252 suggestions->back()->Release();
253 }
254 }
255 Sphere sphere;
256 if (sphere.Init(samples))
257 {
258 sphere.LeastSquaresFit(samples.begin(), samples.begin() + c);
259 bool failed = false;
260 for (size_t i = 0; i < c; ++i)
261 if (sphere.Distance(samples[i]) > distThresh)
262 {
263 failed = true;
264 break;
265 }
266 if (!failed)
267 {
268 suggestions->push_back(new SpherePrimitiveShape(sphere));
269 suggestions->back()->Release();
270 }
271 }
272 Plane plane;
273 if (plane.LeastSquaresFit(samples.begin(), samples.begin() + c))
274 {
275 bool failed = false;
276 for (size_t i = 0; i < c; ++i)
277 if (plane.Distance(samples[i]) > distThresh)
278 {
279 failed = true;
280 break;
281 }
282 if (!failed)
283 {
284 suggestions->push_back(new PlanePrimitiveShape(plane));
285 suggestions->back()->Release();
286 }
287 }
288 /*// although theoretically possible, we never suggest a cone since a misclassification
289 // of a cone as a torus is extremley seldom
290 // The parametrization is given as major arclength and minor arclength
291 float radialMajor = m_extBbox.Max()[0] - m_extBbox.Min()[0];
292 float radialMinor = m_extBbox.Max()[1] - m_extBbox.Min()[1];
293 float lengthMajor = radialMajor * m_torus.MajorRadius();
294 float lengthMinor = radialMinor * m_torus.MinorRadius();
295 float meanRadius = (m_torus.MajorRadius() + m_torus.MinorRadius()) / 2;
296 // suggest a cylinder if either of the two radii can be replaced by
297 // a non curved direction
298 // we suggest a cylinder if the major radius causes an error less than distThresh
299 // this tests if the major radius can be replaced
300 float radiusDiffMajor = (m_torus.MajorRadius() - (std::cos(radialMajor / 2)
301 * m_torus.MajorRadius())) / 2;
302 if(radiusDiffMajor < distThresh)
303 {
304 // construct the cylinder
305 // the axis of the cylinder is given
306 float majorCenter = (m_extBbox.Max()[0] - m_extBbox.Min()[0]) / 2
307 * m_torus.MajorRadius();
308 Vec3f pos, normal, cyAxisDir;
309 InSpace(majorCenter, M_PI * m_torus.MinorRadius(), &pos, &normal);
310 cyAxisDir = normal.cross(m_torus.AxisDirection());
311 cyAxisDir.normalize();
312 pos -= (m_torus.MinorRadius() - radiusDiffMajor) * normal;
313 Cylinder cylinder(cyAxisDir, pos, m_torus.MinorRadius());
314 suggestions->push_back(new CylinderPrimitiveShape(cylinder));
315 suggestions->back()->Release();
316 }
317 // now test if the minor radius can be replaced
318 float radiusDiffMinor = (m_torus.MinorRadius() - (std::cos(radialMinor / 2)
319 * m_torus.MinorRadius())) / 2;
320 if(radiusDiffMinor < distThresh)
321 {
322 // if the minor radius is replaced
323 }
324 // we suggest a sphere if the torus is apple shaped
325 if(m_torus.IsAppleShaped())
326 {
327 Sphere sphere(m_torus.Center(),
328 (m_torus.MajorRadius() + m_torus.MinorRadius()) / 2);
329 suggestions->push_back(new SpherePrimitiveShape(sphere));
330 suggestions->back()->Release();
331 }
332 // we can also suggest a sphere if the error introduced by a common radius
333 // for minor and major does not introduce an error
334 //else if()
335 //{
336 //}
337 // we suggest a plane if both major and minor radius cause ony small error
338 float radiusDiffMinor = (m_torus.MinorRadius() - (std::cos(radialMinor / 2)
339 * m_torus.MinorRadius())) / 2;
340 if(radiusDiffMajor < distThresh && radiusDiffMinor < distThresh)
341 {
342 GfxTL::Vector2Df paramCenter;
343 m_extBbox.Center(&paramCenter);
344 Vec3f pos, normal;
345 InSpace(paramCenter[0] * m_torus.MajorRadius(),
346 paramCenter[1] * m_torus.MinorRadius(), &pos, &normal);
347 Plane plane(pos, normal);
348 suggestions->push_back(new PlanePrimitiveShape(plane));
349 suggestions->back()->Release();
350 }*/
351}
352
353void
355 size_t begin,
356 size_t end,
357 float epsilon)
358{
359 m_parametrization.Optimize(GfxTL::IndexIterate(IndexIterator(begin), pc.begin()),
361 epsilon);
362}
363
364bool
365TorusPrimitiveShape::Similar(float tolerance, const TorusPrimitiveShape& shape) const
366{
367 return m_torus.MajorRadius() <= (1.f + tolerance) * shape.m_torus.MajorRadius() &&
368 (1.f + tolerance) * m_torus.MajorRadius() >= shape.m_torus.MajorRadius() &&
369 m_torus.MinorRadius() <= (1.f + tolerance) * shape.m_torus.MinorRadius() &&
370 (1.f + tolerance) * m_torus.MinorRadius() >= shape.m_torus.MinorRadius();
371}
372
373void
374TorusPrimitiveShape::Parameters(const Vec3f& p, std::pair<float, float>* param) const
375{
376 m_parametrization.Parameters(p, param);
377}
378
379void
387
388void
392 MiscLib::Vector<std::pair<float, float>>* bmpParams) const
393{
394 ParametersImpl(begin, end, bmpParams);
395}
396
397bool
398TorusPrimitiveShape::InSpace(float u, float v, Vec3f* p, Vec3f* n) const
399{
400 return m_parametrization.InSpace(u, v, p, n);
401}
402
403void
406 MiscLib::Vector<std::pair<float, float>>* params,
407 size_t* uextent,
408 size_t* vextent)
409{
410 *uextent = std::ceil((bbox->Max()[0] - bbox->Min()[0]) / epsilon);
411 *vextent = std::ceil((bbox->Max()[1] - bbox->Min()[1]) / epsilon);
412}
413
414void
415TorusPrimitiveShape::InBitmap(const std::pair<float, float>& param,
416 float epsilon,
418 size_t uextent,
419 size_t vextent,
420 std::pair<int, int>* inBmp) const
421{
422 inBmp->first = std::floor((param.first - bbox.Min()[0]) / epsilon);
423 inBmp->second = std::floor((param.second - bbox.Min()[1]) / epsilon);
424}
425
426void
428 float epsilon,
429 bool* uwrap,
430 bool* vwrap) const
431{
432 m_parametrization.WrapBitmap(bbox, epsilon, uwrap, vwrap);
433}
434
435void
437 float epsilon,
438 size_t uextent,
439 size_t vextent,
440 MiscLib::Vector<int>* componentImg,
441 MiscLib::Vector<std::pair<int, size_t>>* labels) const
442{
443 m_parametrization.WrapComponents(bbox, epsilon, uextent, vextent, componentImg, labels);
444}
445
446void
448 const MiscLib::Vector<int>& componentsImg,
449 size_t uextent,
450 size_t vextent,
451 float epsilon,
452 int label)
453{
454}
455
456bool
458 size_t v,
459 float epsilon,
461 size_t uextent,
462 size_t vextent,
463 Vec3f* p,
464 Vec3f* n) const
465{
466 return m_parametrization.InSpace(
467 (u + .5f) * epsilon + bbox.Min()[0], (v + .5f) * epsilon + bbox.Min()[1], p, n);
468}
class DLL_LINKAGE CylinderPrimitiveShape
class DLL_LINKAGE SpherePrimitiveShape
class DLL_LINKAGE ConePrimitiveShape
class DLL_LINKAGE PlanePrimitiveShape
MiscLib::performance_t totalTime_torusConnected
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
Definition Cone.h:25
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Cone.cpp:699
float Distance(const Vec3f &p) const
Definition Cone.h:252
bool InitAverage(const MiscLib::Vector< Vec3f > &samples)
Definition Cone.cpp:119
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Cylinder.cpp:439
float Distance(const Vec3f &p) const
Definition Cylinder.h:197
bool InitAverage(const MiscLib::Vector< Vec3f > &samples)
Definition Cylinder.cpp:97
Point & Min()
Definition AABox.hpp:68
Point & Max()
Definition AABox.hpp:82
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 LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Sphere.cpp:399
float Distance(const Vec3f &p) const
Definition Sphere.h:260
bool Init(const MiscLib::Vector< Vec3f > &samples)
Definition Sphere.cpp:172
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
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, size_t begin, size_t end, float epsilon)
LevMarFunc< float > * SignedDistanceFunc() const
bool Similar(float tolerance, const TorusPrimitiveShape &shape) 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 SetExtent(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, const MiscLib::Vector< int > &componentsImg, size_t uextent, size_t vextent, float epsilon, int label)
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
Definition Torus.h:21
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Torus.cpp:538
const float MajorRadius() const
Definition Torus.h:60
const float MinorRadius() const
Definition Torus.h:54
Definition basic.h:18
IndexedIterator< IndexIteratorT, IteratorT > IndexIterate(IndexIteratorT idxIt, IteratorT it)
clock_t performance_t
Definition Performance.h:31