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