Commit 7044f2cf authored by Sylvain Thery's avatar Sylvain Thery

enhancement of ExplodeVolumeRender

parent 090ec7e8
......@@ -54,6 +54,21 @@ namespace Geometry
template <typename PFP, typename EMBV, typename EMB>
EMB volumeCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs, unsigned int thread = 0);
/**
* Compute volume centroid weighted by edge length (generic version)
* Pre: closed volume & embedded vertices
* Template param:
* PFP: as usual
* EMBV: attributes vector type or cell type (VertexCell, FaceCell, ...)
* EMB: type of attribute (Geom::Vec3f) or cell type (VertexCell, FaceCell, ...)
* @param map the map
* @param d a dart of the face
* @param attributs the vector of attribute or cell
*/
template <typename PFP, typename EMBV, typename EMB>
EMB volumeCentroidELWGen(typename PFP::MAP& map, Dart d, const EMBV& attributs, unsigned int thread = 0);
/**
* Compute volume centroid
* Pre: closed volume & embedded vertices
......@@ -62,11 +77,25 @@ EMB volumeCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs, uns
* @param position the vector of attribute
*/
template <typename PFP>
typename PFP::VEC3 volumeCentroid(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position, unsigned int thread = 0)
inline typename PFP::VEC3 volumeCentroid(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position, unsigned int thread = 0)
{
return volumeCentroidGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, d, position, thread);
}
/**
* Compute volume centroid weighted by edge length
* Pre: closed volume & embedded vertices
* @param map the map
* @param d a dart of the face
* @param position the vector of attribute
*/
template <typename PFP>
inline typename PFP::VEC3 volumeCentroidELW(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position, unsigned int thread = 0)
{
return volumeCentroidELWGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, d, position, thread);
}
/**
* Compute face centroid (generic version)
* Template param:
......@@ -80,6 +109,19 @@ typename PFP::VEC3 volumeCentroid(typename PFP::MAP& map, Dart d, const VertexAt
template <typename PFP, typename EMBV, typename EMB>
EMB faceCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs);
/**
* Compute face centroid weighted by edge length (generic version)
* Template param:
* PFP: as usual
* EMBV: attributes vector type or cell type (VertexCell, FaceCell, ...)
* EMB: type of attribute (Geom::Vec3f) or cell type (VertexCell, FaceCell, ...)
* @param map the map
* @param d a dart of the face
* @param attributs the vector of attribute or cell
*/
template <typename PFP, typename EMBV, typename EMB>
EMB faceCentroidELWGen(typename PFP::MAP& map, Dart d, const EMBV& attributs);
/**
* Compute face centroid
* Pre: closed face & embedded vertices
......@@ -93,6 +135,20 @@ typename PFP::VEC3 faceCentroid(typename PFP::MAP& map, Dart d, const VertexAttr
return faceCentroidGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, d, position);
}
/**
* Compute face centroid weighted by edge length
* Pre: closed face & embedded vertices
* @param map the map
* @param d a dart of the face
* @param position the vector of attribute
*/
template <typename PFP>
typename PFP::VEC3 faceCentroidELW(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
{
return faceCentroidELWGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, d, position);
}
/**
* Compute vertex neighbours centroid (generic version)
* Template param:
......@@ -118,11 +174,41 @@ typename PFP::VEC3 vertexNeighborhoodCentroid(typename PFP::MAP& map, Dart d, co
return vertexNeighborhoodCentroidGen<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, d, position);
}
/**
* Compute centroid of all faces
* @param map the map
* @param position position vertex attribute
* @param face_centroid centroid face attribute
* @param select the selector
* @param thread the thread id (default 0)
*/
template <typename PFP>
void computeCentroidFaces(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& face_centroid,
const FunctorSelect& select = allDarts, unsigned int thread = 0) ;
/**
* Compute centroid of all faces (Edge Length Weighted)
* @param map the map
* @param position position vertex attribute
* @param face_centroid centroid face attribute
* @param select the selector
* @param thread the thread id (default 0)
*/
template <typename PFP>
void computeCentroidELWFaces(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& face_centroid,
const FunctorSelect& select = allDarts, unsigned int thread = 0) ;
/**
* Compute neighborhood centroid of all vertices
* @param map the map
* @param position position vertex attribute
* @param vertex_centroid centroid vertex attribute
* @param select the selector
* @param thread the thread id (default 0)
*/
template <typename PFP>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VertexAttribute<typename PFP::VEC3>& vertex_centroid,
......@@ -131,11 +217,40 @@ void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
namespace Parallel
{
/**
* Compute centroid of all faces
* @param map the map
* @param position position vertex attribute
* @param face_centroid centroid face attribute
* @param select the selector
* @param nbth the number of threads
*/
template <typename PFP>
void computeCentroidFaces(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& face_centroid,
const FunctorSelect& select = allDarts, unsigned int nbth = 0) ;
/**
* Compute centroid of all faces (Edge Length Weighted)
* @param map the map
* @param position position vertex attribute
* @param face_centroid centroid face attribute
* @param select the selector
* @param nbth the number of threads
*/
template <typename PFP>
void computeCentroidELWFaces(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& face_centroid,
const FunctorSelect& select = allDarts, unsigned int nbth = 0) ;
/**
* Compute neighborhood centroid of all vertices (in parallel)
* @param map the map
* @param position position vertex attribute
* @param vertex_centroid centroid vertex attribute
* @param select the selector
* @param nbth the number of threads
*/
template <typename PFP>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VertexAttribute<typename PFP::VEC3>& vertex_centroid,
......@@ -185,6 +300,11 @@ void computeCentroidVolumes(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid,
const FunctorSelect& select = allDarts, unsigned int thread = 0) ;
template <typename PFP>
void computeCentroidELWVolumes(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid,
const FunctorSelect& select = allDarts, unsigned int thread = 0) ;
/**
* compute centroid of all vertices
* @param map the map
......@@ -206,6 +326,12 @@ void computeCentroidVolumes(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid,
const FunctorSelect& select = allDarts, unsigned int nbth = 0) ;
template <typename PFP>
void computeCentroidELWVolumes(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid,
const FunctorSelect& select = allDarts, unsigned int nbth = 0) ;
template <typename PFP>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VertexAttribute<typename PFP::VEC3>& vertex_centroid,
......
......@@ -59,6 +59,25 @@ EMB volumeCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs, uns
return center ;
}
template <typename PFP, typename EMBV, typename EMB>
EMB volumeCentroidELWGen(typename PFP::MAP& map, Dart d, const EMBV& attributs, unsigned int thread)
{
EMB center = AttribOps::zero<EMB,PFP>();
double count=0.0;
Traversor3WE<typename PFP::MAP> t(map, d,false,thread) ;
for(Dart it = t.begin(); it != t.end();it = t.next())
{
EMB e1 = attributs[it];
EMB e2 = attributs[map.phi1(it)];
double l = (e2-e1).norm();
center += (e1+e2)*l;
count += 2.0*l ;
}
center /= double(count);
return center ;
}
template <typename PFP, typename EMBV, typename EMB>
EMB faceCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs)
{
......@@ -74,6 +93,26 @@ EMB faceCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs)
return center ;
}
template <typename PFP, typename EMBV, typename EMB>
EMB faceCentroidELWGen(typename PFP::MAP& map, Dart d, const EMBV& attributs)
{
EMB center = AttribOps::zero<EMB,PFP>();
double count=0.0;
Traversor2FE<typename PFP::MAP> t(map, d) ;
for(Dart it = t.begin(); it != t.end(); it = t.next())
{
EMB e1 = attributs[it];
EMB e2 = attributs[map.phi1(it)];
double l = (e2-e1).norm();
center += (e1+e2)*l;
count += 2.0*l ;
}
center /= double(count);
return center ;
}
template <typename PFP, typename EMBV, typename EMB>
EMB vertexNeighborhoodCentroidGen(typename PFP::MAP& map, Dart d, const EMBV& attributs)
{
......@@ -98,6 +137,14 @@ void computeCentroidFaces(typename PFP::MAP& map, const VertexAttribute<typename
face_centroid[d] = faceCentroid<PFP>(map, d, position) ;
}
template <typename PFP>
void computeCentroidELWFaces(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& face_centroid, const FunctorSelect& select, unsigned int thread)
{
TraversorF<typename PFP::MAP> t(map, select,thread) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
face_centroid[d] = faceCentroidELW<PFP>(map, d, position) ;
}
template <typename PFP>
void computeNeighborhoodCentroidVertices(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, VertexAttribute<typename PFP::VEC3>& vertex_centroid, const FunctorSelect& select, unsigned int thread)
{
......@@ -127,6 +174,23 @@ public:
}
};
template <typename PFP>
class FunctorComputeCentroidELWFaces: public FunctorMapThreaded<typename PFP::MAP >
{
const VertexAttribute<typename PFP::VEC3>& m_position;
FaceAttribute<typename PFP::VEC3>& m_fcentroid;
public:
FunctorComputeCentroidELWFaces<PFP>( typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& fcentroid):
FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_fcentroid(fcentroid)
{ }
void run(Dart d, unsigned int threadID)
{
m_fcentroid[d] = faceCentroidELW<PFP>(this->m_map, d, m_position) ;
}
};
template <typename PFP>
void computeCentroidFaces(typename PFP::MAP& map,
......@@ -137,6 +201,15 @@ void computeCentroidFaces(typename PFP::MAP& map,
Algo::Parallel::foreach_cell<typename PFP::MAP,FACE>(map, funct, nbth, false, select, current_thread);
}
template <typename PFP>
void computeCentroidELWFaces(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, FaceAttribute<typename PFP::VEC3>& face_centroid,
const FunctorSelect& select, unsigned int nbth, unsigned int current_thread)
{
FunctorComputeCentroidELWFaces<PFP> funct(map,position,face_centroid);
Algo::Parallel::foreach_cell<typename PFP::MAP,FACE>(map, funct, nbth, false, select, current_thread);
}
template <typename PFP>
class FunctorComputeNeighborhoodCentroidVertices: public FunctorMapThreaded<typename PFP::MAP >
......@@ -195,6 +268,15 @@ void computeCentroidVolumes(typename PFP::MAP& map, const VertexAttribute<typena
vol_centroid[d] = Surface::Geometry::volumeCentroid<PFP>(map, d, position,thread) ;
}
template <typename PFP>
void computeCentroidELWVolumes(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid, const FunctorSelect& select, unsigned int thread)
{
TraversorW<typename PFP::MAP> t(map, select,thread) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
vol_centroid[d] = Surface::Geometry::volumeCentroidELW<PFP>(map, d, position,thread) ;
}
namespace Parallel
{
template <typename PFP>
......@@ -212,6 +294,22 @@ public:
m_vol_centroid[d] = Surface::Geometry::volumeCentroid<PFP>(this->m_map, d, m_position,threadID) ;
}
};
template <typename PFP>
class FunctorComputeCentroidELWVolumes: public FunctorMapThreaded<typename PFP::MAP >
{
const VertexAttribute<typename PFP::VEC3>& m_position;
VolumeAttribute<typename PFP::VEC3>& m_vol_centroid;
public:
FunctorComputeCentroidELWVolumes<PFP>( typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid):
FunctorMapThreaded<typename PFP::MAP>(map), m_position(position), m_vol_centroid(vol_centroid)
{ }
void run(Dart d, unsigned int threadID)
{
m_vol_centroid[d] = Surface::Geometry::volumeCentroidELW<PFP>(this->m_map, d, m_position,threadID) ;
}
};
template <typename PFP>
void computeCentroidVolumes(typename PFP::MAP& map,
......@@ -223,6 +321,16 @@ void computeCentroidVolumes(typename PFP::MAP& map,
}
template <typename PFP>
void computeCentroidELWVolumes(typename PFP::MAP& map,
const VertexAttribute<typename PFP::VEC3>& position, VolumeAttribute<typename PFP::VEC3>& vol_centroid,
const FunctorSelect& select, unsigned int nbth)
{
FunctorComputeCentroidELWVolumes<PFP> funct(map,position,vol_centroid);
Algo::Parallel::foreach_cell<typename PFP::MAP,VOLUME>(map, funct, nbth, true, select);
}
template <typename PFP>
class FunctorComputeNeighborhoodCentroidVertices: public FunctorMapThreaded<typename PFP::MAP >
{
......@@ -256,8 +364,6 @@ void computeNeighborhoodCentroidVertices(typename PFP::MAP& map,
} // namespace Algo
} // namespace CGoGN
......@@ -28,7 +28,7 @@
#include "Topology/generic/cellmarker.h"
#include "Algo/Geometry/centroid.h"
#include "Topology/generic/autoAttributeHandler.h"
#include "Algo/Geometry/normal.h"
#include "Algo/Geometry/basic.h"
namespace CGoGN
......@@ -99,7 +99,7 @@ void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttri
typedef typename PFP::REAL REAL;
VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
Algo::Volume::Geometry::Parallel::computeCentroidVolumes<PFP>(map, positions, centerVolumes, good);
Algo::Volume::Geometry::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes, good);
std::vector<VEC3> buffer;
buffer.reserve(16384);
......@@ -108,120 +108,145 @@ void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttri
bufferColors.reserve(16384);
std::vector<VEC3> bufferNormals;
bufferNormals.reserve(16384);
std::vector<VEC3> normals;
bufferNormals.reserve(20);
std::vector<VEC3> vertices;
bufferNormals.reserve(20);
TraversorCell<typename PFP::MAP, PFP::MAP::FACE_OF_PARENT> traFace(map, good);
for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next())
{
// compute normals
normals.clear();
VEC3 centerFace(0);
unsigned int nbs=0;
vertices.clear();
VEC3 centerFace = Algo::Surface::Geometry::faceCentroid<PFP>(map, d, positions);
VEC3 centerNormalFace = Algo::Surface::Geometry::newellNormal<PFP>(map,d,positions);
Dart a = d;
do
{
VEC3 v1 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,a,positions);
VEC3 v1 = positions[a] - centerFace;
v1.normalize();
Dart e = map.phi1(a);
VEC3 v2 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,e,positions);
VEC3 v2 = positions[map.phi1(e)] - centerFace;
v2.normalize();
VEC3 N = v1^v2;
double l = N.norm();
if (l>0.000001)
{
N /= l;
normals.push_back(N);
}
if (l<0.01)
N = centerNormalFace;
else
{
normals.push_back(VEC3(9,9,9));
N /= l;
if (N*centerNormalFace < 0.707)
N = centerNormalFace;
}
centerFace += positions[a];
normals.push_back(N);
vertices.push_back(positions[e]);
// VEC3 v1 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,a,positions);
// Dart e = map.phi1(a);
// VEC3 v2 = Algo::Surface::Geometry::vectorOutOfDart<PFP>(map,e,positions);
// v1.normalize();
// v2.normalize();
// VEC3 N = v1^v2;
// double l = N.norm();
// double ll = fabs(N*centerNormalFace());
// if ((l<0.2) && l<0
// if (l<0.3)
// {
// N = centerNormalFace;
// }
// else
// {
// if (N*centerNormalFace < 0.0)
// N /= -l;
// else
// N /= l;
// }
// if ((l < 0.5) || (N*centerNormalFace < 0.0))
// {
// N = centerNormalFace;
// }
// if (N*centerNormalFace < 0.0)
// {
// std::cout << "INVERTED" <<std::endl;
// N =-N;
// }
// N.normalize();
// normals.push_back(N);
// }
// normals.push_back(N);
// vertices.push_back(positions[e]);
//centerFace += positions[e];
a = e;
nbs++;
} while (a != d);
centerFace /= float(nbs);
// centerFace /= float(vertices.size());
// centerNormalFace.normalize();
VEC3 volCol = colorPerXXX[d];
unsigned int nbs = vertices.size();
// just to have more easy algo further
vertices.push_back(vertices.front());
normals.push_back(normals.front());
typename std::vector<VEC3>::iterator iv = vertices.begin();
typename std::vector<VEC3>::iterator in = normals.begin();
typename std::vector<VEC3>::iterator inb = normals.begin();
typename std::vector<VEC3>::iterator inc = normals.begin();
a = map.phi1(d);
while ((*in)[0]>1.0)
{
a = map.phi1(a);
++in;
}
inb = in;
++inb;
Dart b = map.phi1(a);
while ((*inb)[0]>1.0)
{
b = map.phi1(b);
++inb;
}
inc = inb;
++inc;
Dart c = map.phi1(b);
while ((*inc)[0]>1.0)
if (nbs == 3)
{
c = map.phi1(c);
++inc;
buffer.push_back(centerVolumes[d]);
bufferColors.push_back(centerFace);
bufferNormals.push_back(centerNormalFace); // unsused just for fill
buffer.push_back(*iv++);
bufferNormals.push_back(*in++);
bufferColors.push_back(volCol);
buffer.push_back(*iv++);
bufferNormals.push_back(*in++);
bufferColors.push_back(volCol);
buffer.push_back(*iv++);
bufferNormals.push_back(*in++);
bufferColors.push_back(volCol);
}
// loop to cut a polygon in triangle on the fly (works only with convex faces)
do
else
{
buffer.push_back(centerVolumes[a]);
bufferColors.push_back(centerFace);
bufferNormals.push_back(centerFace); // unsused just for fill
buffer.push_back(positions[a]);
bufferColors.push_back(colorPerXXX[a]);
bufferNormals.push_back(*in);
buffer.push_back(positions[b]);
bufferColors.push_back(colorPerXXX[b]);
bufferNormals.push_back(*inb);
buffer.push_back(positions[c]);
bufferColors.push_back(colorPerXXX[c]);
bufferNormals.push_back(*inc);
b = c;
inb = inc;
inc++;
c = map.phi1(b);
while ((*inc)[0]>1.0)
for (unsigned int i=0; i<nbs; ++i)
{
c = map.phi1(c);
++inc;
buffer.push_back(centerVolumes[d]);
bufferColors.push_back(centerFace);
bufferNormals.push_back(centerNormalFace); // unsused just for fill
buffer.push_back(centerFace);
bufferColors.push_back(volCol);
bufferNormals.push_back(centerNormalFace);
buffer.push_back(*iv++);
bufferNormals.push_back(*in++);
bufferColors.push_back(volCol);
buffer.push_back(*iv);
bufferNormals.push_back(*in);
bufferColors.push_back(volCol);
}
} while (c != a);
/*
typename std::vector<VEC3>::iterator in = normals.begin();
a = d;
Dart b = map.phi1(a);
Dart c = map.phi1(b);
// loop to cut a polygon in triangle on the fly (works only with convex faces)
do
{
buffer.push_back(centerVolumes[a]);
bufferColors.push_back(centerFace);
bufferNormals.push_back(centerFace); // unsused just for fill
buffer.push_back(positions[a]);
bufferColors.push_back(colorPerXXX[a]);
bufferNormals.push_back(normals.back());
buffer.push_back(positions[b]);
bufferColors.push_back(colorPerXXX[b]);
bufferNormals.push_back(*in++);
buffer.push_back(positions[c]);
bufferColors.push_back(colorPerXXX[c]);
bufferNormals.push_back(*in);
b = c;
c = map.phi1(b);
} while (c != a);
*/
}
}
......@@ -274,7 +299,7 @@ void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttri
typedef typename PFP::REAL REAL;
VolumeAutoAttribute<VEC3> centerVolumes(map, "centerVolumes");
Algo::Volume::Geometry::Parallel::computeCentroidVolumes<PFP>(map, positions, centerVolumes, good);
Algo::Volume::Geometry::computeCentroidELWVolumes<PFP>(map, positions, centerVolumes, good);
std::vector<VEC3> buffer;
buffer.reserve(16384);
......@@ -283,19 +308,22 @@ void ExplodeVolumeRender::updateSmooth(typename PFP::MAP& map, const VertexAttri
bufferColors.reserve(16384);
std::vector<VEC3> bufferNormals;
bufferNormals.reserve(16384);
std::vector<VEC3> normals;
bufferNormals.reserve(20);