Commit e32aeaa7 authored by David Cazier's avatar David Cazier

Merge Vertex version 1997 ajouté :)

parent cc8261af
......@@ -15,7 +15,6 @@ IF (FORCE_MR EQUAL 1)
add_definitions(-DCGoGN_FORCE_MR=1)
ENDIF (FORCE_MR EQUAL 1)
# for CGoGN in one lib on not
file(STRINGS ${CGoGN_ROOT_DIR}/include/cgogn_onelib.h ONELIB_STR)
IF (ONELIB_STR EQUAL 1)
......@@ -26,28 +25,22 @@ ELSE (ONELIB_STR EQUAL 1)
SET(CGoGN_LIBS_R topology algo container utils)
ENDIF (ONELIB_STR EQUAL 1)
IF(WIN32)
set(CMAKE_PREFIX_PATH ${CGoGN_ROOT_DIR}/windows_dependencies CACHE STRING "path to dependencies")
ENDIF(WIN32)
find_package(OpenGL REQUIRED)
find_package(Boost COMPONENTS regex thread REQUIRED)
find_package(ZLIB REQUIRED)
find_package(LibXml2 REQUIRED)
find_package(GLEW REQUIRED)
IF (DEFINED ASSERTON)
add_definitions(-DCGOGN_ASSERT_BOOL=${ASSERTON})
ELSE (DEFINED ASSERTON)
add_definitions(-DCGOGN_ASSERT_BOOL=false)
ENDIF (DEFINED ASSERTON)
add_definitions(-DSHADERPATH="${CGoGN_ROOT_DIR}/lib/Shaders/")
# define includes of external libs
......@@ -97,7 +90,6 @@ IF (WITH_NUMERICAL)
SET (COMMON_LIBS ${COMMON_LIBS} numerical lapack blas f2c)
ENDIF (WITH_NUMERICAL)
# qq definition specifiques pour mac
IF(APPLE)
# attention a changer pour chercher la bonne version automatiquement
......@@ -123,6 +115,3 @@ IF(WIN32)
ELSE (WIN32)
link_directories( ${CGoGN_ROOT_DIR}/lib/Debug ${CGoGN_ROOT_DIR}/lib/Release)
ENDIF (WIN32)
......@@ -38,6 +38,9 @@ namespace Algo
namespace BooleanOperator
{
template <typename PFP>
bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, Dart f) ;
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e);
......
......@@ -31,42 +31,57 @@ namespace Algo
namespace BooleanOperator
{
template <typename PFP>
bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, Dart f)
{
return CGoGN::Geom::isBetween(positions[map.phi1(d)]-positions[d],
positions[map.phi1(e)]-positions[e],
positions[map.phi1(f)]-positions[f]);
}
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e)
{
assert(Geom::arePointsEquals(positions[d],positions[e]) && !map.sameVertex(d,e));
Dart dd;
do
{
dd = map.phi2_1(d);
map.removeEdgeFromVertex(dd);
Dart ee = e;
do
{
if(Geom::testOrientation2D(positions[map.phi1(dd)],positions[ee],positions[map.phi1(ee)])!=Geom::RIGHT
&& Geom::testOrientation2D(positions[map.phi1(dd)],positions[ee],positions[map.phi1(map.phi2_1(ee))])==Geom::RIGHT)
{
break;
}
ee = map.phi2_1(ee);
} while(ee != e);
map.insertEdgeInVertex(ee,dd);
// d1 traverses the vertex of d (following the alpha1 permutation)
// y is a temporay buffer to stop the loop
Dart d1=d;
// e1 traverses the vertex of e (following the alpha1 permutation)
Dart e1=e;
bool notempty = true;
do {
if (map.phi2_1(e1) == e1) notempty = false;
// detach z from its vertex
map.removeEdgeFromVertex(e1);
// Searchs the dart of the vertex of x where tz may be inserted
Dart nd1 = d1;
do {
if (CGoGN::Algo::BooleanOperator::isBetween<PFP>(map,positions,e1,d1,map.phi2_1(d1))) break;
d1 = map.phi2_1(d1);
} while (d1 != nd1);
map.insertEdgeInVertex(d1,e1);
d1 = e1;
} while (notempty);
} while(dd!=d);
// 0-embed z on the vertex of x without copy of the vertex
// positions[d] = ;
}
template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions)
{
// TODO optimiser en triant les sommets
for(Dart d = map.begin() ; d != map.end() ; map.next(d))
{
CellMarker<VERTEX> vM(map);
vM.mark(d);
std::cout << "." ; std::cout.flush() ;
for(Dart dd = map.begin() ; dd != map.end() ; map.next(dd))
{
if(!vM.isMarked(dd))
{
vM.mark(dd);
if(Geom::arePointsEquals(positions[d],positions[dd]))
{
mergeVertex<PFP>(map,positions,d,dd);
......
......@@ -303,13 +303,14 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
CellMarker<EDGE> brokenMark(map);
EdgeAttribute<float> edgeWidth = map.template addAttribute<float, EDGE>("width");
EdgeAttribute<Dart> edgeOpp = map.template addAttribute<Dart, EDGE>("opp");
EdgeAttribute<NoMathAttribute<Geom::Plane3D<typename PFP::REAL> > > edgePlanes = map.template addAttribute<NoMathAttribute<Geom::Plane3D<typename PFP::REAL> >, EDGE>("planes");
/////////////////////////////////////////////////////////////////////////////////////////////
//create broken lines
DartMarker brokenL(map);
unsigned int nbVertices = 0 ;
std::vector<float >::iterator itW = allBrokenLinesWidth.begin();
for(typename std::vector<POLYGON >::iterator it = allBrokenLines.begin() ; it != allBrokenLines.end() ; ++it)
{
......@@ -320,46 +321,42 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
}
else
{
unsigned int faceDegree = it->size()*2-2;
Dart d = map.newFace(faceDegree);
nbVertices += it->size() ;
polygonsFaces.mark(d);
Dart d = map.newFace(it->size()*2-2,false);
Dart d1=d;
Dart d_1=map.phi_1(d);
//build a degenerated "line" face
for(unsigned int i = 0; i<faceDegree/2 ; ++i)
for(unsigned int i = 0; i<it->size() ; ++i)
{
edgeOpp[d1] = d_1;
edgeOpp[d_1] = d_1;
edgeWidth[d1] = *itW;
edgeWidth[d_1] = *itW;
brokenL.mark(d1);
brokenL.mark(d_1);
map.sewFaces(d1,d_1,false) ;
edgeWidth[d1] = *itW;
d1 = map.phi1(d1);
d_1 = map.phi_1(d_1);
}
polygonsFaces.mark(d);
//embed the line
Dart dd = d;
Dart dOp = d;
d1 = d;
for(typename POLYGON::iterator emb = it->begin(); emb != it->end() ; emb++)
{
bb->addPoint(*emb);
position[dd] = *emb;
position[dOp] = *emb;
dd = map.phi1(dd);
dOp = map.phi_1(dOp);
position[d1] = *emb;
d1 = map.phi1(d1);
}
}
itW++;
}
std::cout << "importSVG : broken lines created." << std::endl;
std::cout << "importSVG : broken lines created : " << nbVertices << " vertices"<< std::endl;
/////////////////////////////////////////////////////////////////////////////////////////////
//create polygons
......@@ -411,6 +408,7 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
// map.closeMap(close);
// map.closeMap();
std::cout << "importSVG : Vertices merging..." << std::endl;
Algo::BooleanOperator::mergeVertices<PFP>(map,position);
std::cout << "importSVG : Vertices merged." << std::endl;
......@@ -455,12 +453,12 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
CellMarker<EDGE> eMTreated(map);
for(Dart d = map.begin();d != map.end(); map.next(d))
{
if(brokenL.isMarked(d) && !eMTreated.isMarked(d) && edgeOpp[d]!=d)
if(brokenL.isMarked(d) && !eMTreated.isMarked(d))
{
// -> we convert broken lines to faces to represent their width
Dart d1 = d;
Dart d2 = edgeOpp[d];
Dart d2 = map.phi2(d);
VEC3 p1 = position[d1];
VEC3 p2 = position[d2];
......@@ -487,7 +485,6 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
Dart dC = map.phi1(d2);
eMTreated.mark(dC);
edgeOpp[dC] = dC;
position[map.phi_1(d1)]=p1;
edgePlanes[map.phi_1(d1)] = Geom::Plane3D<typename PFP::REAL>(v,p1);
......@@ -507,7 +504,6 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
Dart dC = map.phi1(d1);
eMTreated.mark(dC);
edgeOpp[dC] = dC;
position[map.phi_1(d2)]=p2;
edgePlanes[map.phi_1(d2)] = Geom::Plane3D<typename PFP::REAL>(-1.0f*v, p2);
......@@ -548,9 +544,9 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttrib
VEC3 pos = position[d];
pl.project(pos);
// pl = edgePlanes[map.phi_1(d)];
//
// pl.project(pos);
pl = edgePlanes[map.phi_1(d)];
pl.project(pos);
position[d] = pos;
}
}
......
......@@ -35,16 +35,12 @@ namespace Geom
enum OrientationLine
{
CW,
CCW,
INTERSECT
CW, CCW, INTERSECT
} ;
enum Orientation2D
{
ALIGNED,
RIGHT,
LEFT
ALIGNED, RIGHT, LEFT
} ;
/**
......@@ -53,21 +49,21 @@ enum Orientation2D
* return INTERSECT if (a,b) and (c,d) intersect each other
*/
template <typename VEC3>
OrientationLine testOrientationLines(const VEC3& a, const VEC3& b, const VEC3& c, const VEC3& d)
OrientationLine testOrientationLines(const VEC3& a, const VEC3& b, const VEC3& c, const VEC3& d)
{
typedef typename VEC3::DATA_TYPE T ;
T vol = tetraSignedVolume(a,b,c,d) ;
T vol = tetraSignedVolume(a, b, c, d) ;
return vol > T(0) ? CCW : vol < T(0) ? CW : INTERSECT ;
}
/**
* return the orientation of point P w.r.t. the plane defined by 3 points
* @param P the point
* @param A plane point 1
* @param B plane point 2
* @param C plane point 3
* @return the orientation
*/
* return the orientation of point P w.r.t. the plane defined by 3 points
* @param P the point
* @param A plane point 1
* @param B plane point 2
* @param C plane point 3
* @return the orientation
*/
template <typename VEC3>
Orientation3D testOrientation3D(const VEC3& P, const VEC3& A, const VEC3& B, const VEC3& C)
{
......@@ -77,12 +73,12 @@ Orientation3D testOrientation3D(const VEC3& P, const VEC3& A, const VEC3& B, con
}
/**
* return the orientation of point P w.r.t. the plane defined by its normal and 1 point
* @param P the point
* @param N plane normal
* @param PP plane point
* @return the orientation
*/
* return the orientation of point P w.r.t. the plane defined by its normal and 1 point
* @param P the point
* @param N plane normal
* @param PP plane point
* @return the orientation
*/
template <typename VEC3>
Orientation3D testOrientation3D(const VEC3& P, const VEC3& N, const VEC3& PP)
{
......@@ -92,15 +88,54 @@ Orientation3D testOrientation3D(const VEC3& P, const VEC3& N, const VEC3& PP)
}
/**
* return the orientation of point P w.r.t. the vector (Pb-Pa)
* --> tells if P is on/right/left of the line (Pa,Pb)
* @param P the point
* @param Pa origin point
* @param Pb end point
* @return the orientation
*/
* return the orientation of point P w.r.t. the vector (Pb-Pa)
* --> tells if P is on/right/left of the line (Pa,Pb)
* @param P the point
* @param Pa origin point
* @param Pb end point
* @return the orientation
*/
template <typename VEC3>
Orientation2D testOrientation2D(const VEC3& P, const VEC3& Pa, const VEC3& Pb) ;
/**
* return the relative orientation of two vectors in the plane (u,v)
* the return value is
* +1 if u^v > 0
* 0 if u^v = 0
* -1 if u^v < 0
* @param u first vector
* @param v second vector
* @return the orientation
*/
template <typename VEC3>
int orientation2D(const VEC3& u, const VEC3& v) ;
/**
* test if two vectors are aligned or orthogonal, the return value is
* +1 if u and v are ALIGNED and u*v > 0
* 0 if u and v are ORTHOGONAL or u*v = 0
* -1 if u and v are ALIGNED and u*v < 0
* @param u first vector
* @param v second vector
* @return the alignment
*/
template <typename VEC3>
int aligned2D(const VEC3& u, const VEC3& v) ;
/**
* test if vector u is between vectors v and w in the plane (v,w)
* in other words if u is inside the angular sector [v,w[
* (v being included and w being is excluded)
* if u,v,w are aligned the result is true
*
* @param u first vector of the angular sector
* @param v second vector of the angular sector
* @param w the vector to test
* @return the result of the test
*/
template <typename VEC3>
Orientation2D testOrientation2D(const VEC3& P, const VEC3& Pa, const VEC3& Pb);
bool isBetween(const VEC3& u, const VEC3& v, const VEC3& w) ;
/**
* test if the tetrahedron is well oriented depending on the orientation of the faces we want
......
......@@ -35,29 +35,76 @@ Orientation2D testOrientation2D(const VEC3& P, const VEC3& Pa, const VEC3& Pb)
{
typedef typename VEC3::DATA_TYPE T ;
// const T min = std::numeric_limits<T>::min()*T(100);
const T min = 0.0001;
const T zero = 0.0001 ;
T p = (P[0] - Pa[0]) * (Pb[1] - Pa[1]) - (Pb[0] - Pa[0]) * (P[1] - Pa[1]) ;
// T wsof = (Pa[0]-P[0])*(P[1]-Pb[1])-(P[0]-Pb[0])*(Pa[1]-P[1]);
T wsof = (P[0]-Pa[0])*(Pb[1]-Pa[1])-(Pb[0]-Pa[0])*(P[1]-Pa[1]);
if(wsof>min)
if (p > zero)
return RIGHT ;
else if(fabs(wsof)>min)
return LEFT;
return ALIGNED;
// VEC3 dir = Pb - Pa ;
// VEC3 Np = dir ^ N ;
// int o3d = testOrientation3D(P, Np, Pa) ;
// switch(o3d)
// {
// case ON : return ALIGNED ;
// case OVER : return RIGHT ;
// case UNDER : return LEFT ;
// }
else if (-p > zero)
return LEFT ;
else
return ALIGNED ;
}
// TODO use triple product with a normal to the plane that contains u and v
template <typename VEC3>
int orientation2D(const VEC3& u, const VEC3& v)
{
typedef typename VEC3::DATA_TYPE T ;
T p = u[0] * v[1] - u[1] * v[0] ;
const T zero = 0.0001 ;
if (p > zero)
return 1 ;
else if (-p > zero)
return -1 ;
else
return 0 ;
}
// TODO use dot product => include epsilon in vector_gen to test sign
template <typename VEC3>
int aligned2D(const VEC3& u, const VEC3& v)
{
typedef typename VEC3::DATA_TYPE T ;
T p = u[0] * v[0] + u[1] * v[1] ;
const T zero = 0.0001 ;
if (p > zero)
return 1 ;
else if (-p > zero)
return -1 ;
else
return 0 ;
}
template <typename VEC3>
bool isBetween(const VEC3& u, const VEC3& v, const VEC3& w)
{
int orientWV = orientation2D(w,v) ;
if (orientWV > 0)
{
if (orientation2D(v,u) >= 0) return true ;
int orientWU = orientation2D(w,u) ;
if (orientWU < 0) return true ;
return (orientWU == 0) && (aligned2D(w,u) <= 0) ;
}
else if (orientWV < 0 || (orientWV == 0 && aligned2D(w,v) < 0))
{
if (orientation2D(v,u) < 0) return false ;
int orientWU = orientation2D(w,u) ;
if (orientWU < 0) return true ;
return (orientWU == 0) && (aligned2D(w,u) <= 0) ;
}
else // orientWV == 0 && v*u >= 0
// ==> v et u ont même direction ou sont nuls
{
return (orientation2D(v,u) == 0 && aligned2D(v,u) >= 0) ;
}
}
template <typename VEC3>
......@@ -72,7 +119,7 @@ bool isTetrahedronWellOriented(const VEC3 points[4], bool CCW)
VEC3 N = AB ^ AC ;
T dot = N * AD ;
if(CCW)
if (CCW)
return dot <= 0 ;
else
return dot >= 0 ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment