Program Listing for File collection.cc¶
↰ Return to documentation for file (src/collection.cc
)
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* The ACME project *
* *
* Copyright (c) 2020, Davide Stocco and Enrico Bertolazzi. *
* *
* The ACME project and its components are supplied under the terms of *
* the open source BSD 2-Clause License. The contents of the ACME *
* project and its components may not be copied or disclosed except in *
* accordance with the terms of the BSD 2-Clause License. *
* *
* URL: https://opensource.org/licenses/BSD-2-Clause *
* *
* Davide Stocco *
* Department of Industrial Engineering *
* University of Trento *
* e-mail: davide.stocco@unitn.it *
* *
* Enrico Bertolazzi *
* Department of Industrial Engineering *
* University of Trento *
* e-mail: enrico.bertolazzi@unitn.it *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "acme.hh"
namespace acme
{
/*\
| _ _ _ _
| ___ ___ | | | ___ ___| |_(_) ___ _ __
| / __/ _ \| | |/ _ \/ __| __| |/ _ \| '_ \
| | (_| (_) | | | __/ (__| |_| | (_) | | | |
| \___\___/|_|_|\___|\___|\__|_|\___/|_| |_|
|
\*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
collection::collection(void)
: m_AABBtree(std::make_shared<AABBtree>())
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
collection::collection(
entity::vecptr & entities
)
: collection()
{
this->m_entities = entities;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::clear(void)
{
this->m_entities.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::resize(
integer size
)
{
this->m_entities.resize(size);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::push_back(
entity::ptr entity_in
)
{
this->m_entities.push_back(entity_in);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
entity::ptr &
collection::operator[](
integer i
)
{
return this->m_entities[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
entity::ptr const &
collection::operator[](
integer i
)
const
{
return this->m_entities[i];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::translate(
vec3 const & input
)
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
this->m_entities[i]->translate(input);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::rotate(
real angle,
vec3 const & axis
)
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
this->m_entities[i]->rotate(angle, axis);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::transform(
affine const & matrix
)
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
this->m_entities[i]->transform(matrix);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containNone(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isNone())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areNone(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isNone())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isNone(
integer i
)
const
{
return this->m_entities[i]->isNone();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeNone(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isNone();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countNone(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isNone())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containPoint(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isPoint())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::arePoint(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isPoint())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isPoint(
integer i
)
const
{
return this->m_entities[i]->isPoint();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removePoint(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isPoint();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countPoint(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isPoint())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containLine(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isLine())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areLine(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isLine())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isLine(
integer i
)
const
{
return this->m_entities[i]->isLine();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeLine(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isLine();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countLine(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isLine())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containRay(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isRay())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areRay(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isRay())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isRay(
integer i
)
const
{
return this->m_entities[i]->isRay();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeRay(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isRay();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countRay(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isRay())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containPlane(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isPlane())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::arePlane(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isPlane())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isPlane(
integer i)
const
{
return this->m_entities[i]->isPlane();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removePlane(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isPlane();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countPlane(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isPlane())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containSegment(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isSegment())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areSegment(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isBall())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isSegment(
integer i
)
const
{
return this->m_entities[i]->isSegment();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeSegment(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isSegment();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countSegment(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isSegment())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containTriangle(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isTriangle())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areTriangle(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isTriangle())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isTriangle(
integer i
)
const
{
return this->m_entities[i]->isTriangle();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeTriangle(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isTriangle();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countTriangle(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isTriangle())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containDisk(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isDisk())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areDisk(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isDisk())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isDisk(
integer i
)
const
{
return this->m_entities[i]->isDisk();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeDisk(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isDisk();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countDisk(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isDisk())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containBall(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isBall())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areBall(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isBall())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isBall(
integer i
)
const
{
return this->m_entities[i]->isBall();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeBall(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isBall();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countBall(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isBall())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containDegenerated(
real tolerance
)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isDegenerated(tolerance))
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areDegenerated(
real tolerance
)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isDegenerated(tolerance))
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isDegenerated(
integer i,
real tolerance
)
const
{
return this->m_entities[i]->isDegenerated(tolerance);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeDegenerated(
real tolerance
)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[tolerance](entity::ptr & entity){return entity->isDegenerated(tolerance);}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countDegenerated(
real tolerance
)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isDegenerated(tolerance))
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containClampable(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isClampable())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areClampable(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isClampable())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isClampable(
integer i
)
const
{
return this->m_entities[i]->isClampable();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeClampable(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isClampable();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countClampable(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isClampable())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::containNonClampable(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->isNonClampable())
{return true;}
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::areNonClampable(void)
const
{
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isNonClampable())
{return false;}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::isNonClampable(
integer i
)
const
{
return this->m_entities[i]->isNonClampable();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::removeNonClampable(void)
{
std::remove_if(
this->m_entities.begin(),
this->m_entities.end(),
[] (entity::ptr & entity) {return entity->isNonClampable();}
);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::countNonClampable(void)
const
{
integer count = 0;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (!this->m_entities[i]->isNonClampable())
{++count;}
}
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
integer
collection::size(void)
const
{
return integer(this->m_entities.size());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::map<std::string, integer>
collection::count(
real tolerance
)
const
{
return {{"none", this->countNone()},
{"point", this->countPoint()},
{"line", this->countLine()},
{"ray", this->countRay()},
{"plane", this->countPlane()},
{"segment", this->countSegment()},
{"triangle", this->countTriangle()},
{"disk", this->countDisk()},
{"ball", this->countBall()},
{"degenerated", this->countDegenerated(tolerance)},
{"clampable", this->countClampable()},
{"non-clampable", this->countNonClampable()}};
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::clamp(
aabb::vecptr & boxes
)
const
{
#define CMD "acme::collection::clamp(): "
boxes.clear();
vec3 min, max;
for (size_t i = 0; i < this->m_entities.size(); ++i)
{
if (this->m_entities[i]->clamp(min, max))
{
boxes.push_back(std::make_shared<aabb>(min, max, i, integer(0)));
}
else
{
ACME_ERROR(CMD "non-clampable object detected.")
}
}
#undef CMD
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::buildAABBtree(void)
{
aabb::vecptr ptrVecbox;
this->clamp(ptrVecbox);
this->m_AABBtree->build(ptrVecbox);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AABBtree::ptr const &
collection::ptrAABBtree(void)
{
return this->m_AABBtree;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::intersection(
collection & entities,
collection & candidates
)
const
{
candidates.clear();
aabb::vecpairptr intersection_list;
this->m_AABBtree->intersection(*entities.ptrAABBtree(), intersection_list);
for (size_t i = 0; i < intersection_list.size(); ++i)
{
candidates.push_back(this->m_entities[(intersection_list[i].first)->id()]);
candidates.push_back(entities[(intersection_list[i].second)->id()]);
}
return candidates.size() > 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::intersection(
AABBtree::ptr const & ptrAABBtree,
collection & candidates
)
const
{
candidates.clear();
aabb::vecpairptr intersection_list;
this->m_AABBtree->intersection(*ptrAABBtree, intersection_list);
for (size_t i = 0; i < intersection_list.size(); ++i)
{
candidates.push_back(this->m_entities[(intersection_list[i].first)->id()]);
}
return candidates.size() > 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::intersection(
aabb::vecptr const & ptrVecbox,
collection & candidates
)
const
{
AABBtree::ptr ptrAABBtree(std::make_shared<AABBtree>());
ptrAABBtree->build(ptrVecbox);
return this->intersection(ptrAABBtree, candidates);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool
collection::intersection(
aabb::ptr const ptrbox,
collection & candidates
)
const
{
aabb::vecptr ptrVecbox;
ptrVecbox.push_back(ptrbox);
return this->intersection(ptrVecbox, candidates);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void
collection::intersection(
collection & entities,
real tolerance
)
const
{
integer size = this->m_entities.size();
entities.clear();
for (integer i = 0; i < size; ++i)
{
for (integer j = i; j < size; ++j)
{
entities.push_back(entity::ptr(Intersection(this->m_entities[i].get(), this->m_entities[j].get(), tolerance)));
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
} // namespace acme
#endif