|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tstream.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticskeletondeformation.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STL includes
|
|
Toshihiro Shimizu |
890ddd |
#include <set></set>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_misc.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_pool.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_function_types.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_iterator_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticskeleton.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PERSIST_IDENTIFIER(PlasticSkeletonVertex, "PlasticSkeletonVertex")
|
|
Toshihiro Shimizu |
890ddd |
PERSIST_IDENTIFIER(PlasticSkeleton, "PlasticSkeleton")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DEFINE_CLASS_CODE(PlasticSkeleton, 122)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticSkeletonVertex implementation
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex::PlasticSkeletonVertex()
|
|
Toshihiro Shimizu |
890ddd |
: tcg::Vertex<tpointd>(), m_number(-1), m_parent(-1), m_minAngle(-(std::numeric_limits<double>::max)()), m_maxAngle((std::numeric_limits<double>::max)()), m_interpolate(true)</double></double></tpointd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex::PlasticSkeletonVertex(const TPointD &pos)
|
|
Toshihiro Shimizu |
890ddd |
: tcg::Vertex<tpointd>(pos), m_number(-1), m_parent(-1), m_minAngle(-(std::numeric_limits<double>::max)()), m_maxAngle((std::numeric_limits<double>::max)()), m_interpolate(true)</double></double></tpointd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex::operator PlasticHandle() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
PlasticHandle result(P());
|
|
Toshihiro Shimizu |
890ddd |
result.m_interpolate = m_interpolate;
|
|
Toshihiro Shimizu |
890ddd |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeletonVertex::saveData(TOStream &os)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
os.child("name") << m_name;
|
|
Toshihiro Shimizu |
890ddd |
os.child("number") << m_number;
|
|
Toshihiro Shimizu |
890ddd |
os.child("pos") << this->P().x << this->P().y;
|
|
Toshihiro Shimizu |
890ddd |
os.child("interpolate") << (int)this->m_interpolate;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_minAngle != -(std::numeric_limits<double>::max)())</double>
|
|
Toshihiro Shimizu |
890ddd |
os.child("minAngle") << m_minAngle;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_maxAngle != (std::numeric_limits<double>::max)())</double>
|
|
Toshihiro Shimizu |
890ddd |
os.child("maxAngle") << m_maxAngle;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeletonVertex::loadData(TIStream &is)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int val;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::string tagName;
|
|
Toshihiro Shimizu |
890ddd |
while (is.openChild(tagName)) {
|
|
Toshihiro Shimizu |
890ddd |
if (tagName == "name")
|
|
Toshihiro Shimizu |
890ddd |
is >> m_name, is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
else if (tagName == "number")
|
|
Toshihiro Shimizu |
890ddd |
is >> m_number, is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
else if (tagName == "pos")
|
|
Toshihiro Shimizu |
890ddd |
is >> this->P().x >> this->P().y, is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
else if (tagName == "interpolate")
|
|
Toshihiro Shimizu |
890ddd |
is >> val, m_interpolate = (bool)val, is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
else if (tagName == "minAngle")
|
|
Toshihiro Shimizu |
890ddd |
is >> m_minAngle, is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
else if (tagName == "maxAngle")
|
|
Toshihiro Shimizu |
890ddd |
is >> m_maxAngle, is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
is.skipCurrentTag();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticSkeleton::Imp definition
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class PlasticSkeleton::Imp
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
std::set<plasticskeletondeformation *=""> m_deformations; //!< Registered deformations for this skeleton (not owned)</plasticskeletondeformation>
|
|
Toshihiro Shimizu |
890ddd |
tcg::indices_pool<int> m_numbersPool; //!< Vertex numbers pool (used for naming vertices only)</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
Imp() {}
|
|
Toshihiro Shimizu |
890ddd |
Imp(const Imp &other);
|
|
Toshihiro Shimizu |
890ddd |
Imp &operator=(const Imp &other);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef BOOST_NO_RVALUE_REFERENCES
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Imp(Imp &&other);
|
|
Toshihiro Shimizu |
890ddd |
Imp &operator=(Imp &&other);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::Imp::Imp(const Imp &other)
|
|
Toshihiro Shimizu |
890ddd |
: m_numbersPool(other.m_numbersPool)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::Imp &PlasticSkeleton::Imp::operator=(const Imp &other)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_numbersPool = other.m_numbersPool;
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef BOOST_NO_RVALUE_REFERENCES
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::Imp::Imp(Imp &&other)
|
|
Toshihiro Shimizu |
890ddd |
: m_numbersPool(std::move(other.m_numbersPool))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::Imp &PlasticSkeleton::Imp::operator=(Imp &&other)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_numbersPool = std::move(other.m_numbersPool);
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticSkeleton implementation
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::PlasticSkeleton()
|
|
Toshihiro Shimizu |
890ddd |
: m_imp(new Imp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::~PlasticSkeleton()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::PlasticSkeleton(const PlasticSkeleton &other)
|
|
Toshihiro Shimizu |
890ddd |
: mesh_type(other), m_imp(new Imp(*other.m_imp))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton &PlasticSkeleton::operator=(const PlasticSkeleton &other)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(m_imp->m_deformations.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::operator=(other);
|
|
Toshihiro Shimizu |
890ddd |
*m_imp = *other.m_imp;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef BOOST_NO_RVALUE_REFERENCES
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::PlasticSkeleton(PlasticSkeleton &&other)
|
|
Toshihiro Shimizu |
890ddd |
: mesh_type(std::forward<mesh_type>(other)), m_imp(new Imp(std::move(*other.m_imp)))</mesh_type>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton &PlasticSkeleton::operator=(PlasticSkeleton &&other)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(m_imp->m_deformations.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::operator=(std::forward<mesh_type>(other));</mesh_type>
|
|
Toshihiro Shimizu |
890ddd |
*m_imp = std::move(*other.m_imp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::addListener(PlasticSkeletonDeformation *deformation)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_deformations.insert(deformation);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::removeListener(PlasticSkeletonDeformation *deformation)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_deformations.erase(deformation);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool PlasticSkeleton::setVertexName(int v, const QString &newName)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(!newName.isEmpty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_vertices[v].m_name == newName)
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Traverse the vertices list - if the same name already exists, return false
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<vertex_type>::iterator vt, vEnd(m_vertices.end());</vertex_type>
|
|
Toshihiro Shimizu |
890ddd |
for (vt = m_vertices.begin(); vt != vEnd; ++vt)
|
|
Toshihiro Shimizu |
890ddd |
if (vt.m_idx != v && vt->m_name == newName) // v should be skipped in the check
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Notify deformations before changing the name
|
|
Toshihiro Shimizu |
890ddd |
std::set<plasticskeletondeformation *="">::iterator dt, dEnd(m_imp->m_deformations.end());</plasticskeletondeformation>
|
|
Toshihiro Shimizu |
890ddd |
for (dt = m_imp->m_deformations.begin(); dt != dEnd; ++dt)
|
|
Toshihiro Shimizu |
890ddd |
(*dt)->vertexNameChange(this, v, newName);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_vertices[v].m_name = newName;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::moveVertex(int v, const TPointD &pos)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::vertex(v).P() = pos; // Apply new position
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int PlasticSkeleton::addVertex(const PlasticSkeletonVertex &vx, int parent)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Add the vertex
|
|
Toshihiro Shimizu |
890ddd |
int v = mesh_type::addVertex(vx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Retrieve a vertex index
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex &vx_ = vertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vx_.m_number = m_imp->m_numbersPool.acquire();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Assign a name to the vertex in case none was given
|
|
Toshihiro Shimizu |
890ddd |
QString name(vx.name());
|
|
Toshihiro Shimizu |
890ddd |
if (name.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
name = (v == 0) ? QString("Root") : "Vertex " + QString::number(vx_.m_number).rightJustified(3, '_');
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Ensure the name is unique
|
|
Toshihiro Shimizu |
890ddd |
while (!setVertexName(v, name))
|
|
Toshihiro Shimizu |
890ddd |
name += "_";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (parent >= 0) {
|
|
Toshihiro Shimizu |
890ddd |
// Link it to the parent
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::addEdge(edge_type(parent, v)); // Observe that parent is always v0
|
|
Toshihiro Shimizu |
890ddd |
vx_.m_parent = parent;
|
|
Toshihiro Shimizu |
890ddd |
assert(parent != v);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Notify deformations
|
|
Toshihiro Shimizu |
890ddd |
std::set<plasticskeletondeformation *="">::iterator dt, dEnd(m_imp->m_deformations.end());</plasticskeletondeformation>
|
|
Toshihiro Shimizu |
890ddd |
for (dt = m_imp->m_deformations.begin(); dt != dEnd; ++dt)
|
|
Toshihiro Shimizu |
890ddd |
(*dt)->addVertex(this, v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return v;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int PlasticSkeleton::insertVertex(const PlasticSkeletonVertex &vx,
|
|
Toshihiro Shimizu |
890ddd |
int parent, const std::vector<int> &children)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(parent >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (children.empty())
|
|
Toshihiro Shimizu |
890ddd |
return addVertex(vx, parent);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Add the vertex
|
|
Toshihiro Shimizu |
890ddd |
int v = mesh_type::addVertex(vx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Retrieve a vertex index
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex &vx_ = vertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vx_.m_number = m_imp->m_numbersPool.acquire();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Assign a name to the vertex in case none was given
|
|
Toshihiro Shimizu |
890ddd |
QString name(vx.name());
|
|
Toshihiro Shimizu |
890ddd |
if (name.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
name = "Vertex " + QString::number(vx_.m_number).rightJustified(3, '_');
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Ensure the name is unique
|
|
Toshihiro Shimizu |
890ddd |
while (!setVertexName(v, name))
|
|
Toshihiro Shimizu |
890ddd |
name += "_";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Link it to the parent
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex &vx_ = vertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::addEdge(edge_type(parent, v)); // Observe that parent is always v0
|
|
Toshihiro Shimizu |
890ddd |
vx_.m_parent = parent;
|
|
Toshihiro Shimizu |
890ddd |
assert(parent != v);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Link it to children
|
|
Toshihiro Shimizu |
890ddd |
int c, cCount = int(children.size());
|
|
Toshihiro Shimizu |
890ddd |
for (c = 0; c != cCount; ++c) {
|
|
Toshihiro Shimizu |
890ddd |
int vChild = children[c];
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex &vxChild = vertex(vChild);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(vxChild.parent() == parent);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Remove the edge and substitute it with a new one
|
|
Toshihiro Shimizu |
890ddd |
int e = edgeInciding(parent, vChild);
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::removeEdge(e);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::addEdge(edge_type(v, vChild));
|
|
Toshihiro Shimizu |
890ddd |
vxChild.m_parent = v;
|
|
Toshihiro Shimizu |
890ddd |
assert(v != vChild);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Notify deformations
|
|
Toshihiro Shimizu |
890ddd |
std::set<plasticskeletondeformation *="">::iterator dt, dEnd(m_imp->m_deformations.end());</plasticskeletondeformation>
|
|
Toshihiro Shimizu |
890ddd |
for (dt = m_imp->m_deformations.begin(); dt != dEnd; ++dt)
|
|
Toshihiro Shimizu |
890ddd |
(*dt)->insertVertex(this, v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return v;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int PlasticSkeleton::insertVertex(const PlasticSkeletonVertex &vx, int e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const edge_type &ed = edge(e);
|
|
Toshihiro Shimizu |
890ddd |
return insertVertex(vx, ed.vertex(0), std::vector<int>(1, ed.vertex(1)));</int>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::removeVertex(int v)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int vNumber;
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Reparent all of v's children to its parent's children, first. This is needed
|
|
Toshihiro Shimizu |
890ddd |
// to ensure that deformations update vertex deformations correctly.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeletonVertex vx(vertex(v)); // Note the COPY - not referencing. It's best since
|
|
Toshihiro Shimizu |
890ddd |
// we'll be iterating and erasing vx's edges at the same time
|
|
Toshihiro Shimizu |
890ddd |
int parent = vx.m_parent;
|
|
Toshihiro Shimizu |
890ddd |
if (parent < 0) {
|
|
Toshihiro Shimizu |
890ddd |
// Root case - clear the whole skeleton
|
|
Toshihiro Shimizu |
890ddd |
clear(); // Should ensure that the next inserted vertex has index 0
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Add edges from parent to vx's children
|
|
Toshihiro Shimizu |
890ddd |
vertex_type::edges_iterator et, eEnd = vx.edgesEnd();
|
|
Toshihiro Shimizu |
890ddd |
for (et = vx.edgesBegin(); et != eEnd; ++et) {
|
|
Toshihiro Shimizu |
890ddd |
int vChild = edge(*et).vertex(1);
|
|
Toshihiro Shimizu |
890ddd |
if (vChild == v)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::removeEdge(*et);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::addEdge(edge_type(parent, vChild));
|
|
Toshihiro Shimizu |
890ddd |
vertex(vChild).m_parent = parent;
|
|
Toshihiro Shimizu |
890ddd |
assert(vChild != parent);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vNumber = vx.m_number;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Notify deformations BEFORE removing the vertex, so the vertex deformations are still accessible.
|
|
Toshihiro Shimizu |
890ddd |
std::set<plasticskeletondeformation *="">::iterator dt, dEnd(m_imp->m_deformations.end());</plasticskeletondeformation>
|
|
Toshihiro Shimizu |
890ddd |
for (dt = m_imp->m_deformations.begin(); dt != dEnd; ++dt)
|
|
Toshihiro Shimizu |
890ddd |
(*dt)->deleteVertex(this, v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Then, erase v. This already ensures that edges connected with v are destroyed.
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::removeVertex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_numbersPool.release(vNumber);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::clear()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
mesh_type::clear();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_numbersPool.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Notify deformations
|
|
Toshihiro Shimizu |
890ddd |
std::set<plasticskeletondeformation *="">::iterator dt, dEnd(m_imp->m_deformations.end());</plasticskeletondeformation>
|
|
Toshihiro Shimizu |
890ddd |
for (dt = m_imp->m_deformations.begin(); dt != dEnd; ++dt)
|
|
Toshihiro Shimizu |
890ddd |
(*dt)->clear(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::squeeze()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Squeeze associated deformations first
|
|
Toshihiro Shimizu |
890ddd |
int v, e;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Update indices
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<vertex_type>::iterator vt, vEnd(m_vertices.end());</vertex_type>
|
|
Toshihiro Shimizu |
890ddd |
for (v = 0, vt = m_vertices.begin(); vt != vEnd; ++vt, ++v)
|
|
Toshihiro Shimizu |
890ddd |
vt->setIndex(v);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<edge_type>::iterator et, eEnd(m_edges.end());</edge_type>
|
|
Toshihiro Shimizu |
890ddd |
for (e = 0, et = m_edges.begin(); et != eEnd; ++et, ++e)
|
|
Toshihiro Shimizu |
890ddd |
et->setIndex(e);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Update stored indices
|
|
Toshihiro Shimizu |
890ddd |
for (et = m_edges.begin(); et != eEnd; ++et) {
|
|
Toshihiro Shimizu |
890ddd |
edge_type &ed = *et;
|
|
Toshihiro Shimizu |
890ddd |
ed.setVertex(0, vertex(ed.vertex(0)).getIndex());
|
|
Toshihiro Shimizu |
890ddd |
ed.setVertex(1, vertex(ed.vertex(1)).getIndex());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (vt = m_vertices.begin(); vt != vEnd; ++vt) {
|
|
Toshihiro Shimizu |
890ddd |
vertex_type &vx = *vt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (vt->m_parent >= 0)
|
|
Toshihiro Shimizu |
890ddd |
vt->m_parent = vertex(vt->m_parent).getIndex();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vertex_type::edges_iterator vet, veEnd(vx.edgesEnd());
|
|
Toshihiro Shimizu |
890ddd |
for (vet = vx.edgesBegin(); vet != veEnd; ++vet)
|
|
Toshihiro Shimizu |
890ddd |
*vet = edge(*vet).getIndex();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Finally, rebuild the actual containers
|
|
Toshihiro Shimizu |
890ddd |
if (!m_edges.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<edge_type> temp(m_edges.begin(), m_edges.end());</edge_type>
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_edges, temp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_vertices.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<vertex_type> temp(m_vertices.begin(), m_vertices.end());</vertex_type>
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_vertices, temp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::saveData(TOStream &os)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// NOTE: Primitives saved by INDEX iteration is NOT COINCIDENTAL - since
|
|
Toshihiro Shimizu |
890ddd |
// the lists' internal linking could have been altered to mismatch the
|
|
Toshihiro Shimizu |
890ddd |
// natural indexing referred to by primitives' data.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_vertices.size() != m_vertices.nodesCount() ||
|
|
Toshihiro Shimizu |
890ddd |
m_edges.size() != m_edges.nodesCount()) {
|
|
Toshihiro Shimizu |
890ddd |
// Ensure that there are no holes in the representation
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton skel(*this);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
skel.squeeze();
|
|
Toshihiro Shimizu |
890ddd |
skel.saveData(os);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Save vertices
|
|
Toshihiro Shimizu |
890ddd |
os.openChild("V");
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int vCount = int(m_vertices.size());
|
|
Toshihiro Shimizu |
890ddd |
os << vCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int v = 0; v != vCount; ++v)
|
|
Toshihiro Shimizu |
890ddd |
os.child("Vertex") << m_vertices[v];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
os.closeChild();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Save edges
|
|
Toshihiro Shimizu |
890ddd |
os.openChild("E");
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int eCount = int(m_edges.size());
|
|
Toshihiro Shimizu |
890ddd |
os << eCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int e = 0; e != eCount; ++e) {
|
|
Toshihiro Shimizu |
890ddd |
PlasticSkeleton::edge_type &ed = m_edges[e];
|
|
Toshihiro Shimizu |
890ddd |
os << ed.vertex(0) << ed.vertex(1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
os.closeChild();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PlasticSkeleton::loadData(TIStream &is)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Ensure the skeleton is clean
|
|
Toshihiro Shimizu |
890ddd |
clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Load vertices
|
|
Toshihiro Shimizu |
890ddd |
std::string str;
|
|
Toshihiro Shimizu |
890ddd |
int i, size;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (is.openChild(str)) {
|
|
Toshihiro Shimizu |
890ddd |
if (str == "V") {
|
|
Toshihiro Shimizu |
890ddd |
is >> size;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::vector<int> acquiredVertexNumbers;</int>
|
|
Toshihiro Shimizu |
890ddd |
acquiredVertexNumbers.reserve(size);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_vertices.reserve(size);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
if (is.openChild(str) && (str == "Vertex")) {
|
|
Toshihiro Shimizu |
890ddd |
vertex_type vx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
is >> vx;
|
|
Toshihiro Shimizu |
890ddd |
int idx = mesh_type::addVertex(vx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (vx.m_number < 0)
|
|
Toshihiro Shimizu |
890ddd |
vertex(idx).m_number = vx.m_number = idx + 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
acquiredVertexNumbers.push_back(vx.m_number);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
assert(false), is.skipCurrentTag();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_numbersPool = tcg::indices_pool<int>(</int>
|
|
Toshihiro Shimizu |
890ddd |
acquiredVertexNumbers.begin(), acquiredVertexNumbers.end());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
} else if (str == "E") {
|
|
Toshihiro Shimizu |
890ddd |
is >> size;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_edges.reserve(size);
|
|
Toshihiro Shimizu |
890ddd |
int v0, v1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
is >> v0 >> v1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
addEdge(edge_type(v0, v1));
|
|
Toshihiro Shimizu |
890ddd |
vertex(v1).m_parent = v0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
is.matchEndTag();
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
assert(false), is.skipCurrentTag();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticSkeleton utility functions
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int PlasticSkeleton::closestVertex(const TPointD &pos, double *dist) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Traverse vertices
|
|
Toshihiro Shimizu |
890ddd |
double d2, minDist2 = (std::numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
int v = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<vertex_type>::const_iterator vt, vEnd(m_vertices.end());</vertex_type>
|
|
Toshihiro Shimizu |
890ddd |
for (vt = m_vertices.begin(); vt != vEnd; ++vt) {
|
|
Toshihiro Shimizu |
890ddd |
d2 = tcg::point_ops::dist2(pos, vt->P());
|
|
Toshihiro Shimizu |
890ddd |
if (d2 < minDist2)
|
|
Toshihiro Shimizu |
890ddd |
minDist2 = d2, v = int(vt.m_idx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dist && v >= 0)
|
|
Toshihiro Shimizu |
890ddd |
*dist = sqrt(minDist2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return v;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int PlasticSkeleton::closestEdge(const TPointD &pos, double *dist) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Traverse edges
|
|
Toshihiro Shimizu |
890ddd |
double d, minDist = (std::numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
int e = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tcg::list<edge_type>::const_iterator et, eEnd(m_edges.end());</edge_type>
|
|
Toshihiro Shimizu |
890ddd |
for (et = m_edges.begin(); et != eEnd; ++et) {
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &vp0 = vertex(et->vertex(0)).P(), &vp1 = vertex(et->vertex(1)).P();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
d = tcg::point_ops::segDist(vp0, vp1, pos);
|
|
Toshihiro Shimizu |
890ddd |
if (d < minDist)
|
|
Toshihiro Shimizu |
890ddd |
minDist = d, e = int(et.m_idx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dist && e >= 0)
|
|
Toshihiro Shimizu |
890ddd |
*dist = minDist;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return e;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::vector<plastichandle> PlasticSkeleton::verticesToHandles() const</plastichandle>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Someway, PlasticHandle's EXPLICIT unary constructors are not enough
|
|
Toshihiro Shimizu |
890ddd |
// to disambiguate the direct construction of a vector of PlasticHandles
|
|
Toshihiro Shimizu |
890ddd |
// from m_vertices, at least with *gcc*. I guess it could be a compiler bug.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// So, we'll convert them using an explicit casting iterator...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef tcg::function < PlasticHandle (PlasticSkeletonVertex::*)() const,
|
|
Toshihiro Shimizu |
890ddd |
&PlasticSkeletonVertex::operator PlasticHandle> Func;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return std::vector<plastichandle>(</plastichandle>
|
|
Toshihiro Shimizu |
890ddd |
tcg::make_cast_it(m_vertices.begin(), Func()),
|
|
Toshihiro Shimizu |
890ddd |
tcg::make_cast_it(m_vertices.end(), Func()));
|
|
Toshihiro Shimizu |
890ddd |
}
|