14 #include "Foundation/console.h"
15 #include "Foundation/StringUtil.h"
16 #include "Geometry/RandomBoxPacker.h"
17 #include "Geometry/ParticleComparer.h"
18 #include "Geometry/SphereFitter.h"
28 template <
typename TmplParticle>
32 typedef TmplParticle Particle;
33 PlaneComparer(
const Particle &particle)
34 : m_pParticle(&particle)
38 inline bool operator()(
const Plane &plane1,
const Plane &plane2)
const
42 plane1.
sep(m_pParticle->getPos())
44 plane2.
sep(m_pParticle->getPos())
48 const Particle *m_pParticle;
51 template<
typename TmplTraits>
52 FittedParticleIterator<TmplTraits>::FittedParticleIterator(
54 int maxInsertionFailures,
55 const PlaneVector &fitPlaneVector
58 m_fitPlaneVector(fitPlaneVector),
59 m_maxInsertionFailures(maxInsertionFailures),
62 m_next(Fitter::getInvalidParticle()),
69 std::string(
"isValid method returns true for INVALID particle:")
71 StringUtil::toString(m_next)
74 initialiseFitterPtrVector();
77 template<
typename TmplTraits>
78 const typename FittedParticleIterator<TmplTraits>::PlaneVector &
79 FittedParticleIterator<TmplTraits>::getFitPlaneVector()
const
81 return m_fitPlaneVector;
84 template<
typename TmplTraits>
85 int FittedParticleIterator<TmplTraits>::getMaxInsertionFailures()
const
87 return m_maxInsertionFailures;
90 template<
typename TmplTraits>
91 const typename FittedParticleIterator<TmplTraits>::Packer &
92 FittedParticleIterator<TmplTraits>::getPacker()
const
97 template<
typename TmplTraits>
98 typename FittedParticleIterator<TmplTraits>::Packer &
99 FittedParticleIterator<TmplTraits>::getPacker()
104 template<
typename TmplTraits>
106 FittedParticleIterator<TmplTraits>::initialiseFitterPtrVector()
108 FitterPtrVector fitters;
109 fitters.push_back(FitterPtr(
new Move2SurfaceFitter(getPacker())));
110 if (getPacker().is2d())
112 fitters.push_back(FitterPtr(
new TwoDFitter(getPacker())));
113 if (getFitPlaneVector().size() > 0) {
114 fitters.push_back(FitterPtr(
new TwoDPlaneFitter(getPacker())));
119 fitters.push_back(FitterPtr(
new ThreeDFitter(getPacker())));
120 if (getFitPlaneVector().size() > 0) {
121 fitters.push_back(FitterPtr(
new ThreeDPlaneFitter(getPacker())));
125 m_fitterPtrVector = fitters;
128 template<
typename TmplTraits>
129 typename FittedParticleIterator<TmplTraits>::FitterPtrVector &
130 FittedParticleIterator<TmplTraits>::getFitterPtrVector()
132 return m_fitterPtrVector;
135 template<
typename TmplTraits>
136 const typename FittedParticleIterator<TmplTraits>::FitterPtrVector &
137 FittedParticleIterator<TmplTraits>::getFitterPtrVector()
const
139 return m_fitterPtrVector;
142 template<
typename TmplTraits>
143 typename FittedParticleIterator<TmplTraits>::Plane
144 FittedParticleIterator<TmplTraits>::getClosestFitPlane(
145 const Particle &particle
148 PlaneVector fitPlanes = getFitPlaneVector();
149 if (fitPlanes.size() > 0) {
150 std::sort(fitPlanes.begin(), fitPlanes.end(), PlaneComparer<Particle>(particle));
154 return Plane(
Vec3(-1.0, 0, 0),
Vec3(DBL_MAX/2, DBL_MAX/2, DBL_MAX/2));
157 template<
typename TmplTraits>
158 Vec3 FittedParticleIterator<TmplTraits>::getRandomPoint()
const
160 return getPacker().getRandomPoint();
163 template<
typename TmplTraits>
164 typename FittedParticleIterator<TmplTraits>::Particle
165 FittedParticleIterator<TmplTraits>::getCandidateParticle(
169 return getPacker().getCandidateParticle(point);
172 template<
typename TmplTraits>
173 typename FittedParticleIterator<TmplTraits>::ParticleVector
174 FittedParticleIterator<TmplTraits>::getClosestNeighbours(
175 const Particle& particle,
179 return getPacker().getClosestNeighbours(particle, numClosest);
182 template<
typename TmplTraits>
183 typename FittedParticleIterator<TmplTraits>::Particle &
184 FittedParticleIterator<TmplTraits>::generateNext()
186 m_next = Fitter::getInvalidParticle();
187 if (m_lastFailCount < getMaxInsertionFailures())
191 FitterPtrVector fitters = getFitterPtrVector();
192 Particle particle = Fitter::getInvalidParticle();
193 Particle fitParticle = particle;
195 ParticleVector neighbours;
196 while ((!fitParticle.isValid()) && (numFails < getMaxInsertionFailures()))
198 particle = getCandidateParticle(getRandomPoint());
199 neighbours = getClosestNeighbours(particle, 4);
200 plane = getClosestFitPlane(particle);
203 typename FitterPtrVector::iterator it = getFitterPtrVector().begin();
205 (it != getFitterPtrVector().end())
207 (!fitParticle.isValid())
212 fitParticle = (*it)->getFitParticle(particle, neighbours, plane);
216 m_lastFailCount = numFails;
218 <<
"FittedParticleIterator<T>::generateNext: numFails="
220 m_successCount += ((fitParticle.isValid()) ? 1 : 0);
221 m_next = fitParticle;
226 template<
typename TmplTraits>
227 bool FittedParticleIterator<TmplTraits>::hasNext()
229 return (m_next.isValid() || generateNext().isValid());
232 template<
typename TmplTraits>
233 typename FittedParticleIterator<TmplTraits>::Particle
234 FittedParticleIterator<TmplTraits>::next()
236 if (!(m_next.isValid()))
240 const Particle next = m_next;
241 m_next = Fitter::getInvalidParticle();
245 template<
typename TmplTraits>
246 void FittedParticleIterator<TmplTraits>::logInfo()
249 <<
"BoundingBox: minPt = " << getPacker().getBBox().getMinPt()
250 <<
", maxPt = " << getPacker().getBBox().getMaxPt() <<
"\n"
251 <<
"BoundingBox: sizes = " << getPacker().getBBox().getSizes() <<
"\n";
254 typename FitterPtrVector::iterator it = getFitterPtrVector().begin();
255 (it != getFitterPtrVector().end());
258 console.
Info() << (*(*it)).toString() <<
"\n";
260 console.
Info() <<
"Total successful fits = " << m_successCount <<
"\n";
289 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
290 RandomBoxPacker<TPartGen,TCubicPackWrap>::RandomBoxPacker(
291 ParticleGeneratorPtr particleGeneratorPtr,
292 ParticlePoolPtr particlePoolPtr,
294 const BoundingBox &bBox,
295 const BoolVector &periodicDimensions,
297 double cubicPackRadius,
298 int maxInsertionFailures,
299 const PlaneVector &fitPlaneVector
302 particleGeneratorPtr,
310 m_fitPlaneVector(fitPlaneVector),
311 m_maxInsertionFailures(maxInsertionFailures)
315 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
316 RandomBoxPacker<TPartGen,TCubicPackWrap>::RandomBoxPacker(
317 ParticleGeneratorPtr particleGeneratorPtr,
318 ParticlePoolPtr particlePoolPtr,
320 const BoundingBox &bBox,
321 const BoolVector &periodicDimensions,
323 double cubicPackRadius,
324 int maxInsertionFailures
327 particleGeneratorPtr,
336 m_maxInsertionFailures(maxInsertionFailures)
338 m_fitPlaneVector = getDefaultFitPlaneVector();
341 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
342 typename RandomBoxPacker<TPartGen,TCubicPackWrap>::PlaneVector
343 RandomBoxPacker<TPartGen,TCubicPackWrap>::getDefaultFitPlaneVector()
const
345 PlaneVector fitPlaneVector;
346 if ((!this->getPeriodicDimensions()[1])) {
347 fitPlaneVector.push_back(
348 Plane(
Vec3(0, 1, 0), this->getBBox().getMinPt())
350 fitPlaneVector.push_back(
351 Plane(
Vec3(0, -1, 0), this->getBBox().getMaxPt())
354 if ((!this->getPeriodicDimensions()[0])) {
355 fitPlaneVector.push_back(
356 Plane(
Vec3( 1, 0, 0), this->getBBox().getMinPt())
358 fitPlaneVector.push_back(
359 Plane(
Vec3(-1, 0, 0), this->getBBox().getMaxPt())
365 (!this->getPeriodicDimensions()[2])
367 fitPlaneVector.push_back(
368 Plane(
Vec3(0, 0, 1), this->getBBox().getMinPt())
370 fitPlaneVector.push_back(
371 Plane(
Vec3(0, 0, -1), this->getBBox().getMaxPt())
374 return fitPlaneVector;
377 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
378 RandomBoxPacker<TPartGen,TCubicPackWrap>::~RandomBoxPacker()
382 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
384 RandomBoxPacker<TPartGen,TCubicPackWrap>::getRandom(
389 return minVal + (maxVal-minVal)*rng::s_zeroOneUniform();
392 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
393 const typename RandomBoxPacker<TPartGen,TCubicPackWrap>::PlaneVector &
394 RandomBoxPacker<TPartGen,TCubicPackWrap>::getFitPlaneVector()
const
396 return m_fitPlaneVector;
400 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
401 Vec3 RandomBoxPacker<TPartGen,TCubicPackWrap>::getRandomPoint()
const
405 getRandom(this->getBBox().getMinPt().X(), this->getBBox().getMaxPt().X()),
406 getRandom(this->getBBox().getMinPt().Y(), this->getBBox().getMaxPt().Y()),
407 getRandom(this->getBBox().getMinPt().Z(), this->getBBox().getMaxPt().Z())
411 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
412 typename RandomBoxPacker<TPartGen,TCubicPackWrap>::ParticleVector
413 RandomBoxPacker<TPartGen,TCubicPackWrap>::getClosestNeighbours(
414 const Particle& particle,
418 ParticleVector neighbourVector =
419 this->getNTable().getUniqueNeighbourVector(
424 if (static_cast<int>(neighbourVector.size()) < numClosest)
427 this->getNTable().getUniqueNeighbourVector(
429 particle.getRad() + this->getTolerance()
431 if (static_cast<int>(neighbourVector.size()) < numClosest)
434 this->getNTable().getUniqueNeighbourVector(
436 this->getParticleGenerator().getMaxFitRadius() + this->getTolerance()
442 neighbourVector.begin(),
443 neighbourVector.end(),
447 if (static_cast<int>(neighbourVector.size()) > numClosest) {
448 neighbourVector.erase(
449 neighbourVector.begin() + numClosest,
450 neighbourVector.end()
454 return neighbourVector;
457 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
458 bool RandomBoxPacker<TPartGen,TCubicPackWrap >::particleIsValid(
459 const Particle &particle
464 this->getParticleGenerator().isValidFitRadius(particle.getRad())
466 Inherited::particleFitsInBBoxWithNeighbours(particle)
470 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
471 int RandomBoxPacker<TPartGen,TCubicPackWrap>::getMaxInsertionFailures()
const
473 return m_maxInsertionFailures;
476 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
477 void RandomBoxPacker<TPartGen,TCubicPackWrap>::generateRandomFill()
479 StuffedParticleIterator it =
480 StuffedParticleIterator(
482 getMaxInsertionFailures(),
487 const Particle p = it.next();
488 this->createAndInsertParticle(p);
493 template <
typename TPartGen,
template <
typename TTPartGen>
class TCubicPackWrap>
494 void RandomBoxPacker<TPartGen,TCubicPackWrap>::generate()
496 this->generateCubicPacking();
497 this->generateRandomFill();