Removed template from Skeleton3D and some cleaning
This commit is contained in:
parent
9e62dc1e03
commit
34ca9dd9b8
|
@ -62,7 +62,7 @@ class AnimatedMesh
|
|||
/// a GUI to create patellas with the left clic, and choose a root for
|
||||
/// the trees. The right click must be on an extremity of the mesh.
|
||||
///////////////////////////////////////////////////////////
|
||||
AnimatedMesh(Skeleton3D<geo::Vector3<float>,float> const& skeleton);
|
||||
AnimatedMesh(Skeleton3D const& skeleton);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
/// \brief OpenGL render function
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
namespace pae
|
||||
{
|
||||
|
||||
std::pair<std::vector<geo::Segment<float,3>>, geo::Vector3<float>> click(Skeleton3D<geo::Vector3<float>,float> const& skel);
|
||||
std::pair<std::vector<geo::Segment<float,3>>, geo::Vector3<float>> click(Skeleton3D const& skel);
|
||||
|
||||
geo::Tree<geo::Vector3<float>>& listToTree(std::list<geo::Segment<float,3>>& vector, geo::Tree<geo::Vector3<float>>& tree);
|
||||
|
||||
|
|
|
@ -108,6 +108,30 @@ using Segment = std::pair<Vector<T,N>, Vector<T,N>>;
|
|||
template<typename T1, typename T2, typename T3>
|
||||
float distanceToSegment(T1 const& v, T2 const& p1, T3 const& p2);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
/// \ingroup geometry
|
||||
/// \brief compute on which side of the plane is the point (depending on the orientation of the plane
|
||||
///
|
||||
/// \param plane the caracteristic elements of the plane a, b, c, d in the plane equation : ax + by + cz + d = 0.
|
||||
/// \param point the point that need to be evaluated
|
||||
///
|
||||
/// \return a boolean which is true when : a*point.x() + b*point.y() + c*point.z() < -d.
|
||||
/////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
bool whichSide(geo::Vector<T,4> const& plane, geo::Vector3<T> const& point);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/// \ingroup meshing
|
||||
/// \relates pae::Skeleton3D
|
||||
/// \brief compute the equation of the optimal plane for a given set of points. For 3 points it only computes the equation of a plane, beyond 3 points with ACP decomposition it returns the mean plane.
|
||||
///
|
||||
/// \param points the given set of points to estimate the equation of the plane
|
||||
///
|
||||
/// \return the caracteristic elements of the plane a, b, c, d in the plane equation : ax + by + cz + d = 0.)
|
||||
/////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
geo::Vector<float,4> closestPlane(std::vector<geo::Vector3<T>> const& points);
|
||||
|
||||
} // namespace geo
|
||||
|
||||
#include "Geometry/MathFunctions.inl"
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <limits>
|
||||
|
||||
#include <opencv2/features2d/features2d.hpp>
|
||||
#include <eigen3/Eigen/Dense>
|
||||
|
||||
#include "Geometry/Vector.hpp"
|
||||
#include "Geometry/MathFunctions.hpp"
|
||||
|
@ -214,4 +215,47 @@ float distanceToSegment(T1 const& v, T2 const& p1, T3 const& p2)
|
|||
return distance_to_segment_helper<T1,T2,T3,vector_size<T1>::value>{}(v,p1,p2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
geo::Vector<float,4> closestPlane(std::vector<geo::Vector3<T>> const& points)
|
||||
{
|
||||
// for 3 points we just compute the plane that contains the 3 points
|
||||
if (points.size() == 3)
|
||||
{
|
||||
auto vec = crossProduct(points[1] - points[0], points[2] - points[0]);
|
||||
vec /= vec.norm();
|
||||
float t = - (points[0].x()*vec.x() + points[0].y()*vec.y() + points[0].z()*vec.z());
|
||||
return geo::Vector<float,4>{vec.x(), vec.y(), vec.z(), t};
|
||||
}
|
||||
// for more points we use an PCA decomposition to find the best plane
|
||||
else
|
||||
{
|
||||
Eigen::MatrixXf m{points.size(),3};
|
||||
|
||||
for ( unsigned int i = 0; i < points.size(); i++)
|
||||
{
|
||||
m(i,0) = points[i].x();
|
||||
m(i,1) = points[i].y();
|
||||
m(i,2) = points[i].z();
|
||||
}
|
||||
|
||||
Eigen::MatrixXf centered = m.rowwise() - m.colwise().mean();
|
||||
Eigen::MatrixXf cov = centered.adjoint() * centered;
|
||||
|
||||
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eig{cov};
|
||||
|
||||
Eigen::Vector3f v1 = eig.eigenvectors().col(1);
|
||||
Eigen::Vector3f v2 = eig.eigenvectors().col(2);
|
||||
|
||||
Eigen::Vector3f n = v1.cross(v2);
|
||||
|
||||
return( geo::Vector<float,4>{n(0),n(1),n(2), -n.dot(m.colwise().mean())} );
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool whichSide(geo::Vector<float,4> const& plane, geo::Vector3<float> const& point)
|
||||
{
|
||||
return plane.x()*point.x() + plane.y()*point.y() + plane.z()*point.z() < - plane.t();
|
||||
}
|
||||
|
||||
} // namespace geo
|
||||
|
|
|
@ -155,7 +155,7 @@ std::ostream& operator<<(std::ostream& out, Spline<Types...> const& spline)
|
|||
out << node << " ";
|
||||
out << "\n";
|
||||
|
||||
using namespace detail;
|
||||
using pae::detail::operator<<;
|
||||
|
||||
for (auto const& tuple : spline.controlPoints)
|
||||
{
|
||||
|
|
|
@ -51,31 +51,6 @@ using Junction = std::vector<std::pair<unsigned int,float>>;
|
|||
|
||||
namespace detail
|
||||
{
|
||||
/////////////////////////////////////////////////////////////
|
||||
/// \ingroup meshing
|
||||
/// \relates pae::Skeleton3D
|
||||
/// \brief compute on which side of the plane is the point (depending on the orientation of the plane
|
||||
///
|
||||
/// \param plane the caracteristic elements of the plane a, b, c, d in the plane equation : ax + by + cz + d = 0.
|
||||
/// \param point the point that need to be evaluated
|
||||
///
|
||||
/// \return a boolean which is true when : a*point.x() + b*point.y() + c*point.z() < -d.
|
||||
/////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
bool whichSide(geo::Vector<T,4> const& plane, geo::Vector3<T> const& point);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/// \ingroup meshing
|
||||
/// \relates pae::Skeleton3D
|
||||
/// \brief compute the equation of the optimal plane for a given set of points. For 3 points it only computes the equation of a plane, beyond 3 points with ACP decomposition it returns the mean plane.
|
||||
///
|
||||
/// \param points the given set of points to estimate the equation of the plane
|
||||
///
|
||||
/// \return the caracteristic elements of the plane a, b, c, d in the plane equation : ax + by + cz + d = 0.)
|
||||
/////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
geo::Vector<float,4> closestPlane(std::vector<geo::Vector3<T>> const& points);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/// \ingroup meshing
|
||||
/// \relates pae::Skeleton3D
|
||||
|
@ -89,22 +64,20 @@ namespace detail
|
|||
/// - a vector of lists of down points for all the circles
|
||||
/// the n th list of the up points vector correspond to the same circle than the n th list of the down points.
|
||||
/////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Point<T>>>> sortedPoints(geo::Vector<T,4> const& plane, std::vector<geo::Circle<T>> const& junction_circles);
|
||||
std::pair<std::vector<std::list<geo::Point<float>>>, std::vector<std::list<geo::Point<float>>>> sortedPoints(geo::Vector<float,4> const& plane, std::vector<geo::Circle<float>> const& junction_circles);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
/// \ingroup meshing
|
||||
/// \relates pae::Skeleton3D
|
||||
/// \brief push the face to the mesh with the correct orientation
|
||||
/// \param mesh mesh to add the face
|
||||
/// \param mesh mesh to add the face<T
|
||||
/// \param face face to be added
|
||||
/// \param sphere_center center of the sphere
|
||||
///
|
||||
/// Compute the vector between the center of the sphere and the points of the faces
|
||||
/// and add the face so that the normal is pointing outside the sphere.
|
||||
//////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
void pushFaceOriented(geo::Mesh& mesh, geo::Vector3<unsigned int> const& face, geo::Vector3<T> const& sphere_center);
|
||||
void pushFaceOriented(geo::Mesh& mesh, geo::Vector3<unsigned int> const& face, geo::Vector3<float> const& sphere_center);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
@ -119,8 +92,7 @@ namespace detail
|
|||
///
|
||||
/// \return the plane that cut the circles in two (helpful to test).
|
||||
////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_point, float junction_radius, std::vector<geo::Circle<T>> const& junction_circles);
|
||||
geo::Vector<float,4> meshJunction(geo::Mesh& mesh, geo::Vector3<float> const& junction_point, float junction_radius, std::vector<geo::Circle<float>> const& junction_circles);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// \ingroup meshing
|
||||
|
@ -130,7 +102,6 @@ geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_p
|
|||
/// a mesh from the skeleton, including junctions and extremities
|
||||
///
|
||||
////////////////////////////////////////////////////////////////
|
||||
template<typename... Types>
|
||||
class Skeleton3D
|
||||
{
|
||||
public:
|
||||
|
@ -241,17 +212,14 @@ class Skeleton3D
|
|||
///
|
||||
/// Prints the splines and the junctions points on the stream
|
||||
////////////////////////////////////////////////////////
|
||||
template<typename... T>
|
||||
friend std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s);
|
||||
friend std::ostream& operator<<(std::ostream& out, Skeleton3D const& s);
|
||||
|
||||
// private:
|
||||
std::vector<geo::Spline<Types...>> splines; ///< all the splines that the skeleton contains
|
||||
std::vector<geo::Spline<geo::Vector3<float>, float>> splines; ///< all the splines that the skeleton contains
|
||||
std::vector<Junction> junctions; ///< all the junction points of the skeleton
|
||||
};
|
||||
|
||||
|
||||
} // namespace pae
|
||||
|
||||
#include "Skeleton3D.inl"
|
||||
|
||||
#endif // SKELETON3D_HPP
|
||||
|
|
|
@ -48,8 +48,8 @@
|
|||
#include <Animation/Menu.hpp>
|
||||
|
||||
// Full hd : 1920x1080
|
||||
constexpr auto WIDTH = 1024;
|
||||
constexpr auto HEIGHT = 768;
|
||||
constexpr auto WIDTH = 1920;
|
||||
constexpr auto HEIGHT = 1080;
|
||||
|
||||
void drawScene(std::unique_ptr<sft::Camera> const& camera, pae::AnimatedMesh const& mesh);
|
||||
|
||||
|
@ -58,7 +58,7 @@ int main(int argc, char *argv[])
|
|||
std::srand(std::time(nullptr));
|
||||
|
||||
// Init mesh
|
||||
pae::Skeleton3D<geo::Vector3<float>, float> skeleton;
|
||||
pae::Skeleton3D skeleton;
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
namespace pae
|
||||
{
|
||||
|
||||
AnimatedMesh::AnimatedMesh(Skeleton3D<geo::Vector3<float>,float> const& skeleton)
|
||||
AnimatedMesh::AnimatedMesh(Skeleton3D const& skeleton)
|
||||
{
|
||||
auto segments = click(skeleton);
|
||||
this->segments = segments.first;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
add_executable(AnimatedMain AnimatedMain.cpp AnimatedMesh.cpp Click.cpp Menu.cpp)
|
||||
target_link_libraries(AnimatedMain Geometry SFMLTools ${SFML_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(AnimatedMain Geometry Skeleton3D SFMLTools ${SFML_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
namespace pae
|
||||
{
|
||||
|
||||
std::pair<std::vector<geo::Segment<float,3>>, geo::Vector3<float>> click(Skeleton3D<geo::Vector3<float>,float> const& skel)
|
||||
std::pair<std::vector<geo::Segment<float,3>>, geo::Vector3<float>> click(Skeleton3D const& skel)
|
||||
{
|
||||
// Initialization of the window where clicks have to be done
|
||||
sf::RenderWindow window{sf::VideoMode{800,600},"Click on the rotation points"};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
add_library(Skeleton3D Skeleton3D.cpp)
|
||||
|
||||
add_executable(TestJunction3 TestJunction3.cpp)
|
||||
target_link_libraries(TestJunction3 ${OPENGL_LIBRARIES} ${SFML_LIBRARIES} SFMLTools Geometry)
|
||||
target_link_libraries(TestJunction3 SFMLTools Skeleton3D Geometry ${OPENGL_LIBRARIES} ${SFML_LIBRARIES})
|
||||
add_executable(TestJunction4 TestJunction4.cpp)
|
||||
target_link_libraries(TestJunction4 ${OPENGL_LIBRARIES} ${SFML_LIBRARIES} SFMLTools Geometry)
|
||||
target_link_libraries(TestJunction4 SFMLTools Skeleton3D Geometry ${OPENGL_LIBRARIES} ${SFML_LIBRARIES})
|
||||
add_executable(MainDisplay MainDisplay.cpp)
|
||||
target_link_libraries(MainDisplay ${OPENGL_LIBRARIES} ${SFML_LIBRARIES} SFMLTools Geometry)
|
||||
target_link_libraries(MainDisplay SFMLTools Skeleton3D Geometry ${OPENGL_LIBRARIES} ${SFML_LIBRARIES})
|
||||
|
|
|
@ -52,7 +52,7 @@ void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh);
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Init mesh
|
||||
pae::Skeleton3D<geo::Vector3<float>, float> skeleton;
|
||||
pae::Skeleton3D skeleton;
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
|
|
|
@ -32,10 +32,11 @@
|
|||
#include <sstream>
|
||||
#include <cmath>
|
||||
#include <list>
|
||||
#include <eigen3/Eigen/Dense>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Meshing/Skeleton3D.hpp"
|
||||
#include "Utility/TupleFunctions.hpp"
|
||||
#include "Geometry/MathFunctions.hpp"
|
||||
#include "Geometry/Point.hpp"
|
||||
|
||||
namespace pae
|
||||
|
@ -44,50 +45,48 @@ namespace pae
|
|||
namespace detail
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Point<T>>>> const& pair)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
out << "up_points_vector_list" << std::endl;
|
||||
for (auto const& l : pair.first)
|
||||
{
|
||||
out << "circle_" << i << std::endl;
|
||||
for (auto const& p : l)
|
||||
{
|
||||
out << p.first << " ";
|
||||
}
|
||||
out << std::endl;
|
||||
i++;
|
||||
}
|
||||
|
||||
out << std::endl << "Second list" << std::endl;
|
||||
i = 0;
|
||||
for (auto const& l : pair.second)
|
||||
{
|
||||
|
||||
out << "circle_" << i << std::endl;
|
||||
for (auto const& p : l)
|
||||
{
|
||||
out << p.first << " ";
|
||||
}
|
||||
out << std::endl;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
// template<typename T>
|
||||
// std::ostream& operator<<(std::ostream& out, std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Point<T>>>> const& pair)
|
||||
// {
|
||||
// unsigned int i = 0;
|
||||
// out << "up_points_vector_list" << std::endl;
|
||||
// for (auto const& l : pair.first)
|
||||
// {
|
||||
// out << "circle_" << i << std::endl;
|
||||
// for (auto const& p : l)
|
||||
// {
|
||||
// out << p.first << " ";
|
||||
// }
|
||||
// out << std::endl;
|
||||
// i++;
|
||||
// }
|
||||
//
|
||||
// out << std::endl << "Second list" << std::endl;
|
||||
// i = 0;
|
||||
// for (auto const& l : pair.second)
|
||||
// {
|
||||
//
|
||||
// out << "circle_" << i << std::endl;
|
||||
// for (auto const& p : l)
|
||||
// {
|
||||
// out << p.first << " ";
|
||||
// }
|
||||
// out << std::endl;
|
||||
// i++;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return out;
|
||||
// }
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename... Types>
|
||||
Skeleton3D<Types...>::Skeleton3D() : splines{}
|
||||
Skeleton3D::Skeleton3D() : splines{}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<typename... Types>
|
||||
bool Skeleton3D<Types...>::loadFromFile(std::string const& path)
|
||||
bool Skeleton3D::loadFromFile(std::string const& path)
|
||||
{
|
||||
std::fstream file{path};
|
||||
|
||||
|
@ -100,7 +99,7 @@ bool Skeleton3D<Types...>::loadFromFile(std::string const& path)
|
|||
std::stringstream stream;
|
||||
std::string line;
|
||||
bool alreadyFoundL = false;
|
||||
geo::Spline<Types...> currentSpline;
|
||||
geo::Spline<geo::Vector3<float>, float> currentSpline;
|
||||
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
|
@ -121,7 +120,7 @@ bool Skeleton3D<Types...>::loadFromFile(std::string const& path)
|
|||
splines.push_back(currentSpline);
|
||||
|
||||
// Prepare the new one
|
||||
currentSpline = geo::Spline<Types...>{};
|
||||
currentSpline = geo::Spline<geo::Vector3<float>, float>{};
|
||||
|
||||
// Set the degree of the spline
|
||||
int i;
|
||||
|
@ -194,8 +193,7 @@ bool Skeleton3D<Types...>::loadFromFile(std::string const& path)
|
|||
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
void Skeleton3D<T...>::meshJunctions(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles) const
|
||||
void Skeleton3D::meshJunctions(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles) const
|
||||
{
|
||||
for(unsigned int i = 0; i < junctions.size(); i++)
|
||||
{
|
||||
|
@ -226,13 +224,12 @@ void Skeleton3D<T...>::meshJunctions(geo::Mesh& mesh, std::vector<std::vector<ge
|
|||
junction_circles.push_back(spline_circles[spline_circles.size()-1]);
|
||||
}
|
||||
}
|
||||
meshJunction<float>(mesh,junction_point,junction_radius, junction_circles);
|
||||
meshJunction(mesh,junction_point,junction_radius, junction_circles);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_point, float junction_radius, std::vector<geo::Circle<T>> const& junction_circles)
|
||||
geo::Vector<float,4> meshJunction(geo::Mesh& mesh, geo::Vector3<float> const& junction_point, float junction_radius, std::vector<geo::Circle<float>> const& junction_circles)
|
||||
{
|
||||
std::vector<geo::Vector3<float>> centerPoints;
|
||||
|
||||
|
@ -241,10 +238,10 @@ geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_p
|
|||
centerPoints.push_back(circle.center);
|
||||
}
|
||||
// Find the medium plane that cut the circles in two
|
||||
geo::Vector<float,4> plane = detail::closestPlane<float>(centerPoints);
|
||||
geo::Vector<float,4> plane = geo::closestPlane<float>(centerPoints);
|
||||
|
||||
// Compute list of points upside the plane and downside
|
||||
auto sorted_points = detail::sortedPoints<float>(plane, junction_circles);
|
||||
auto sorted_points = detail::sortedPoints(plane, junction_circles);
|
||||
|
||||
geo::Vector3<float> direction{plane.x(),plane.y(),plane.z()};
|
||||
direction /= direction.norm();
|
||||
|
@ -323,8 +320,8 @@ geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_p
|
|||
};
|
||||
|
||||
auto min_pair = std::min_element(std::begin(pairs), std::end(pairs),
|
||||
[] (std::pair<geo::Point<T>, geo::Point<T>> const& points,
|
||||
std::pair<geo::Point<T>, geo::Point<T>> const& points2) {
|
||||
[] (std::pair<geo::Point<float>, geo::Point<float>> const& points,
|
||||
std::pair<geo::Point<float>, geo::Point<float>> const& points2) {
|
||||
|
||||
return (points.first.second-points.second.second).norm2() <
|
||||
(points2.first.second-points2.second.second).norm2();
|
||||
|
@ -527,8 +524,7 @@ geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_p
|
|||
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
std::vector<std::pair<unsigned int, float>> Skeleton3D<T...>::findExtremities() const
|
||||
std::vector<std::pair<unsigned int, float>> Skeleton3D::findExtremities() const
|
||||
{
|
||||
std::vector<std::pair<unsigned int, float>> extremities;
|
||||
std::vector<unsigned int> indexJunctions;
|
||||
|
@ -578,8 +574,7 @@ std::vector<std::pair<unsigned int, float>> Skeleton3D<T...>::findExtremities()
|
|||
return extremities;
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
void Skeleton3D<T...>::meshExtremities(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur) const
|
||||
void Skeleton3D::meshExtremities(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur) const
|
||||
{
|
||||
std::vector<std::pair<unsigned int, float>> extremities = findExtremities();
|
||||
for (unsigned int i=0;i<extremities.size();i++)
|
||||
|
@ -588,8 +583,7 @@ void Skeleton3D<T...>::meshExtremities(geo::Mesh& mesh, std::vector<std::vector<
|
|||
}
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
void Skeleton3D<T...>::meshExtremity(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur, std::pair<unsigned int,float> extremity) const
|
||||
void Skeleton3D::meshExtremity(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur, std::pair<unsigned int,float> extremity) const
|
||||
{
|
||||
// Get the junction elements
|
||||
auto tuple = splines[extremity.first](extremity.second);
|
||||
|
@ -649,8 +643,7 @@ void Skeleton3D<T...>::meshExtremity(geo::Mesh& mesh, std::vector<std::vector<ge
|
|||
}
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
void Skeleton3D<T...>::subdivision(geo::Mesh& mesh, unsigned int profondeur, geo::Circle<float> extremCircle, unsigned int intersectionIndex, geo::Vector3<float> intersection, geo::Vector3<float> center, float radius, float t) const
|
||||
void Skeleton3D::subdivision(geo::Mesh& mesh, unsigned int profondeur, geo::Circle<float> extremCircle, unsigned int intersectionIndex, geo::Vector3<float> intersection, geo::Vector3<float> center, float radius, float t) const
|
||||
{
|
||||
std::vector<std::vector<geo::Vector3<float>>> arcs;
|
||||
for (unsigned int i=0;i<extremCircle.points.size();i++)
|
||||
|
@ -737,8 +730,7 @@ void Skeleton3D<T...>::subdivision(geo::Mesh& mesh, unsigned int profondeur, geo
|
|||
mesh.faces.push_back(sortedIndexes(indexVertices + nbPoints, indexVerticesInit + nbPoints, i2, t));
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
geo::Vector3<unsigned int> Skeleton3D<T... >::sortedIndexes(unsigned int a, unsigned int b, unsigned int c, float t) const
|
||||
geo::Vector3<unsigned int> Skeleton3D::sortedIndexes(unsigned int a, unsigned int b, unsigned int c, float t) const
|
||||
{
|
||||
if(t==0)
|
||||
{
|
||||
|
@ -751,8 +743,7 @@ geo::Vector3<unsigned int> Skeleton3D<T... >::sortedIndexes(unsigned int a, unsi
|
|||
}
|
||||
|
||||
//pt1 the extremity
|
||||
template<typename... T>
|
||||
void Skeleton3D<T...>::arcSubdivise(geo::Vector3<float> pt1, geo::Vector3<float> pt2, unsigned int profondeur, std::vector<geo::Vector3<float>>& arc, geo::Vector3<float> center, float radius) const
|
||||
void Skeleton3D::arcSubdivise(geo::Vector3<float> pt1, geo::Vector3<float> pt2, unsigned int profondeur, std::vector<geo::Vector3<float>>& arc, geo::Vector3<float> center, float radius) const
|
||||
{
|
||||
if (profondeur!=0)
|
||||
{
|
||||
|
@ -771,8 +762,7 @@ void Skeleton3D<T...>::arcSubdivise(geo::Vector3<float> pt1, geo::Vector3<float>
|
|||
}
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
geo::Mesh Skeleton3D<T...>::computeMesh(float pointsProportion, unsigned int nbPointsPerCircle, unsigned int depth,bool withExtremities, bool withJunctions) const
|
||||
geo::Mesh Skeleton3D::computeMesh(float pointsProportion, unsigned int nbPointsPerCircle, unsigned int depth,bool withExtremities, bool withJunctions) const
|
||||
{
|
||||
geo::Mesh mesh;
|
||||
std::vector<std::vector<geo::Circle<float>>> splines_circles;
|
||||
|
@ -797,8 +787,7 @@ geo::Mesh Skeleton3D<T...>::computeMesh(float pointsProportion, unsigned int nbP
|
|||
return mesh;
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s)
|
||||
std::ostream& operator<<(std::ostream& out, Skeleton3D const& s)
|
||||
{
|
||||
for (auto const& spline:s.splines)
|
||||
{
|
||||
|
@ -824,51 +813,7 @@ std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s)
|
|||
namespace detail
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
bool whichSide(geo::Vector<float,4> const& plane, geo::Vector3<float> const& point)
|
||||
{
|
||||
return plane.x()*point.x() + plane.y()*point.y() + plane.z()*point.z() < - plane.t();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
geo::Vector<float,4> closestPlane(std::vector<geo::Vector3<T>> const& points)
|
||||
{
|
||||
// for 3 points we just compute the plane that contains the 3 points
|
||||
if (points.size() == 3)
|
||||
{
|
||||
auto vec = crossProduct(points[1] - points[0], points[2] - points[0]);
|
||||
vec /= vec.norm();
|
||||
float t = - (points[0].x()*vec.x() + points[0].y()*vec.y() + points[0].z()*vec.z());
|
||||
return geo::Vector<float,4>{vec.x(), vec.y(), vec.z(), t};
|
||||
}
|
||||
// for more points we use an PCA decomposition to find the best plane
|
||||
else
|
||||
{
|
||||
Eigen::MatrixXf m{points.size(),3};
|
||||
|
||||
for ( unsigned int i = 0; i < points.size(); i++)
|
||||
{
|
||||
m(i,0) = points[i].x();
|
||||
m(i,1) = points[i].y();
|
||||
m(i,2) = points[i].z();
|
||||
}
|
||||
|
||||
Eigen::MatrixXf centered = m.rowwise() - m.colwise().mean();
|
||||
Eigen::MatrixXf cov = centered.adjoint() * centered;
|
||||
|
||||
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eig{cov};
|
||||
|
||||
Eigen::Vector3f v1 = eig.eigenvectors().col(1);
|
||||
Eigen::Vector3f v2 = eig.eigenvectors().col(2);
|
||||
|
||||
Eigen::Vector3f n = v1.cross(v2);
|
||||
|
||||
return( geo::Vector<float,4>{n(0),n(1),n(2), -n.dot(m.colwise().mean())} );
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Point<T>>>> sortedPoints(geo::Vector<T,4> const& plane, std::vector<geo::Circle<T>> const& junction_circles)
|
||||
std::pair<std::vector<std::list<geo::Point<float>>>, std::vector<std::list<geo::Point<float>>>> sortedPoints(geo::Vector<float,4> const& plane, std::vector<geo::Circle<float>> const& junction_circles)
|
||||
{
|
||||
std::vector<std::list<geo::Point<float>>> up_points;
|
||||
std::vector<std::list<geo::Point<float>>> down_points;
|
||||
|
@ -877,26 +822,26 @@ std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Poin
|
|||
{
|
||||
std::list<geo::Point<float>> first_points; // points located on one side of the circle, the first side reached.The two sides are separated by the median plane computed earlier.
|
||||
std::list<geo::Point<float>> second_points; // points located on the other side of the circle
|
||||
const bool up_side = whichSide<double>(plane, junction_circles[i].points[0].second); // constant boolean initialized at the beginning to know with which side we begin the way on the circle.
|
||||
const bool up_side = geo::whichSide<double>(plane, junction_circles[i].points[0].second); // constant boolean initialized at the beginning to know with which side we begin the way on the circle.
|
||||
bool side_current_points = up_side; // boolean to know on which side we must had the points.
|
||||
|
||||
for (unsigned int j = 0; j < junction_circles[i].points.size(); j++)
|
||||
{
|
||||
if (up_side == side_current_points)
|
||||
{
|
||||
if (whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
|
||||
if (geo::whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
|
||||
{
|
||||
first_points.push_back(junction_circles[i].points[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
side_current_points = whichSide<double>(plane, junction_circles[i].points[j].second);
|
||||
side_current_points = geo::whichSide<double>(plane, junction_circles[i].points[j].second);
|
||||
second_points.push_back(junction_circles[i].points[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (whichSide<double>(plane, junction_circles[i].points[j].second) == side_current_points)
|
||||
if (geo::whichSide<double>(plane, junction_circles[i].points[j].second) == side_current_points)
|
||||
{
|
||||
second_points.push_back(junction_circles[i].points[j]);
|
||||
}
|
||||
|
@ -910,7 +855,7 @@ std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Poin
|
|||
|
||||
for (int j = static_cast<int>(junction_circles[i].points.size()-1); j >= 0; j--)
|
||||
{
|
||||
if (whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
|
||||
if (geo::whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
|
||||
{
|
||||
first_points.push_front(junction_circles[i].points[j]);
|
||||
}
|
||||
|
@ -936,8 +881,7 @@ std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Poin
|
|||
return std::make_pair(up_points, down_points);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void pushFaceOriented(geo::Mesh& mesh, geo::Vector3<unsigned int> const& face, geo::Vector3<T> const& sphere_center)
|
||||
void pushFaceOriented(geo::Mesh& mesh, geo::Vector3<unsigned int> const& face, geo::Vector3<float> const& sphere_center)
|
||||
{
|
||||
geo::Vector3<float> v1 = mesh.vertices[face.x()] - sphere_center;
|
||||
geo::Vector3<float> v2 = geo::crossProduct(mesh.vertices[face.z()] - mesh.vertices[face.y()],
|
|
@ -75,7 +75,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
// skeleton.meshExtremities(mesh, splines_circles, profondeur);
|
||||
auto plane = pae::meshJunction<float>(mesh,geo::Vector3<float>{0.0f,0.0f,0.0f}, 2, circles);
|
||||
auto plane = pae::meshJunction(mesh,geo::Vector3<float>{0.0f,0.0f,0.0f}, 2, circles);
|
||||
|
||||
std::cout << plane << std::endl;
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
// skeleton.meshExtremities(mesh, splines_circles, profondeur);
|
||||
auto plane = pae::meshJunction<float>(mesh,geo::Vector3<float>{0.0f,0.0f,0.0f}, 2, circles);
|
||||
auto plane = pae::meshJunction(mesh,geo::Vector3<float>{0.0f,0.0f,0.0f}, 2, circles);
|
||||
|
||||
std::cout << plane << std::endl;
|
||||
|
||||
|
|
Loading…
Reference in New Issue