14 #include "Foundation/console.h"
15 #include "Foundation/StringUtil.h"
16 #include "Geometry/RandomSpherePacker.h"
17 #include "Geometry/SphereFitter.h"
18 #include "Geometry/ParticleComparer.h"
28 template<
typename TmplTraits>
29 SphereFittedPIterator<TmplTraits>::SphereFittedPIterator(
31 int maxInsertionFailures,
32 const BoundingSphere &bSphere
36 m_maxInsertionFailures(maxInsertionFailures),
39 m_next(Fitter::getInvalidParticle()),
46 std::string(
"isValid method returns true for INVALID particle:")
48 StringUtil::toString(m_next)
51 initialiseFitterPtrVector();
54 template<
typename TmplTraits>
55 int SphereFittedPIterator<TmplTraits>::getMaxInsertionFailures()
const
57 return m_maxInsertionFailures;
60 template<
typename TmplTraits>
61 const typename SphereFittedPIterator<TmplTraits>::Packer &
62 SphereFittedPIterator<TmplTraits>::getPacker()
const
67 template<
typename TmplTraits>
68 typename SphereFittedPIterator<TmplTraits>::Packer &
69 SphereFittedPIterator<TmplTraits>::getPacker()
74 template<
typename TmplTraits>
75 const BoundingSphere &
76 SphereFittedPIterator<TmplTraits>::getBSphere()
const
81 template<
typename TmplTraits>
83 SphereFittedPIterator<TmplTraits>::initialiseFitterPtrVector()
85 FitterPtrVector fitters;
86 fitters.push_back(FitterPtr(
new Move2SurfaceFitter(getPacker())));
87 if (getPacker().is2d())
89 fitters.push_back(FitterPtr(
new TwoDSFitter(getPacker())));
90 fitters.push_back(FitterPtr(
new TwoDSSphereFitter(getPacker(), getBSphere())));
94 fitters.push_back(FitterPtr(
new ThreeDFitter(getPacker())));
95 fitters.push_back(FitterPtr(
new ThreeDSSphereFitter(getPacker(), getBSphere())));
97 m_fitterPtrVector = fitters;
100 template<
typename TmplTraits>
101 typename SphereFittedPIterator<TmplTraits>::FitterPtrVector &
102 SphereFittedPIterator<TmplTraits>::getFitterPtrVector()
104 return m_fitterPtrVector;
107 template<
typename TmplTraits>
108 const typename SphereFittedPIterator<TmplTraits>::FitterPtrVector &
109 SphereFittedPIterator<TmplTraits>::getFitterPtrVector()
const
111 return m_fitterPtrVector;
114 template<
typename TmplTraits>
115 Vec3 SphereFittedPIterator<TmplTraits>::getRandomPoint()
const
117 return getPacker().getRandomPoint();
120 template<
typename TmplTraits>
121 typename SphereFittedPIterator<TmplTraits>::Particle
122 SphereFittedPIterator<TmplTraits>::getCandidateParticle(
126 return getPacker().getCandidateParticle(point);
129 template<
typename TmplTraits>
130 typename SphereFittedPIterator<TmplTraits>::ParticleVector
131 SphereFittedPIterator<TmplTraits>::getClosestNeighbours(
132 const Particle& particle,
136 return getPacker().getClosestNeighbours(particle, numClosest);
139 template<
typename TmplTraits>
140 typename SphereFittedPIterator<TmplTraits>::Particle &
141 SphereFittedPIterator<TmplTraits>::generateNext()
143 m_next = Fitter::getInvalidParticle();
144 if (m_lastFailCount < getMaxInsertionFailures())
148 FitterPtrVector fitters = getFitterPtrVector();
149 Particle particle = Fitter::getInvalidParticle();
150 Particle fitParticle = particle;
152 ParticleVector neighbours;
153 while ((!fitParticle.isValid()) && (numFails < getMaxInsertionFailures()))
155 particle = getCandidateParticle(getRandomPoint());
156 neighbours = getClosestNeighbours(particle, 4);
159 typename FitterPtrVector::iterator it = getFitterPtrVector().begin();
161 (it != getFitterPtrVector().end())
163 (!fitParticle.isValid())
168 fitParticle = (*it)->getFitParticle(particle, neighbours, plane);
172 m_lastFailCount = numFails;
173 m_successCount += ((fitParticle.isValid()) ? 1 : 0);
174 m_next = fitParticle;
179 template<
typename TmplTraits>
180 bool SphereFittedPIterator<TmplTraits>::hasNext()
182 return (m_next.isValid() || generateNext().isValid());
185 template<
typename TmplTraits>
186 typename SphereFittedPIterator<TmplTraits>::Particle
187 SphereFittedPIterator<TmplTraits>::next()
189 if (!(m_next.isValid()))
193 const Particle next = m_next;
194 m_next = Fitter::getInvalidParticle();
198 template<
typename TmplTraits>
199 void SphereFittedPIterator<TmplTraits>::logInfo()
202 <<
"BoundingSphere: minPt = " << getPacker().getBBox().getMinPt()
203 <<
", maxPt = " << getPacker().getBBox().getMaxPt() <<
"\n"
204 <<
"BoundingSphere: sizes = " << getPacker().getBBox().getSizes() <<
"\n";
207 typename FitterPtrVector::iterator it = getFitterPtrVector().begin();
208 (it != getFitterPtrVector().end());
211 console.
Info() << (*(*it)).toString() <<
"\n";
213 console.
Info() <<
"Total successful fits = " << m_successCount <<
"\n";
242 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
243 RandomSpherePacker<TPartGen,TCubicPackWrap>::RandomSpherePacker(
244 ParticleGeneratorPtr particleGeneratorPtr,
245 ParticlePoolPtr particlePoolPtr,
247 const BoundingSphere &bSphere,
249 double cubicPackRadius,
250 int maxInsertionFailures,
254 particleGeneratorPtr,
257 do2d ? bSphere.get2dBBox() : bSphere.getBBox(),
263 m_maxInsertionFailures(maxInsertionFailures)
267 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
268 RandomSpherePacker<TPartGen,TCubicPackWrap>::~RandomSpherePacker()
272 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
273 const BoundingSphere &
274 RandomSpherePacker<TPartGen,TCubicPackWrap>::getBSphere(
280 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
282 RandomSpherePacker<TPartGen,TCubicPackWrap>::getRandom(
287 return minVal + (maxVal-minVal)*rng::s_zeroOneUniform();
290 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
291 Vec3 RandomSpherePacker<TPartGen,TCubicPackWrap>::getRandomPoint()
const
295 getRandom(this->getBBox().getMinPt().X(), this->getBBox().getMaxPt().X()),
296 getRandom(this->getBBox().getMinPt().Y(), this->getBBox().getMaxPt().Y()),
297 getRandom(this->getBBox().getMinPt().Z(), this->getBBox().getMaxPt().Z())
301 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
302 typename RandomSpherePacker<TPartGen,TCubicPackWrap>::ParticleVector
303 RandomSpherePacker<TPartGen,TCubicPackWrap>::getClosestNeighbours(
304 const Particle& particle,
308 ParticleVector neighbourVector =
309 this->getNTable().getUniqueNeighbourVector(
311 this->getParticleGenerator().getMaxFitRadius() + this->getTolerance()
314 neighbourVector.begin(),
315 neighbourVector.end(),
319 if (static_cast<int>(neighbourVector.size()) > numClosest) {
320 neighbourVector.erase(
321 neighbourVector.begin() + numClosest,
322 neighbourVector.end()
326 return neighbourVector;
329 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
330 bool RandomSpherePacker<TPartGen,TCubicPackWrap >::particleIsValid(
331 const Particle &particle
336 this->getParticleGenerator().isValidFitRadius(particle.getRad())
338 particleFitsInBSphereWithNeighbours(particle)
342 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
343 int RandomSpherePacker<TPartGen,TCubicPackWrap>::getMaxInsertionFailures()
const
345 return m_maxInsertionFailures;
348 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
349 void RandomSpherePacker<TPartGen,TCubicPackWrap>::generateRandomFill()
351 StuffedParticleIterator it =
352 StuffedParticleIterator(
354 getMaxInsertionFailures(),
359 const Particle p = it.next();
360 this->createAndInsertParticle(p);
365 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
367 RandomSpherePacker<TPartGen,TCubicPackWrap>::particleFitsInBSphere(
368 const Particle &particle
372 getBSphere().contains(
373 BoundingSphere(particle.getPos(), particle.getRadius()),
378 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
380 RandomSpherePacker<TPartGen,TCubicPackWrap>::particleFitsInBSphereWithNeighbours(
381 const Particle &particle
386 particleFitsInBSphere(particle)
388 this->particleFitsWithNeighbours(particle)
392 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
393 void RandomSpherePacker<TPartGen,TCubicPackWrap>::generateCubicPackingInSphere()
395 GridIterator pointIt = GridIterator(this->getBBox(), this->getCubicPackingRadius());
396 while (pointIt.hasNext()) {
397 const Particle candidate =
398 this->getCandidateParticle(pointIt.next(), this->getCubicPackingRadius());
399 if (particleFitsInBSphereWithNeighbours(candidate)) {
400 this->createAndInsertParticle(candidate);
405 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
406 void RandomSpherePacker<TPartGen,TCubicPackWrap>::generate()
408 generateCubicPackingInSphere();
409 generateRandomFill();