Commit a4ca9f84 authored by Sylvain Thery's avatar Sylvain Thery

Merge branch 'master' of cgogn:~jund/CGoGN

parents d68c5b28 d2c82ad7
......@@ -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 system 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
......@@ -98,7 +91,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
......@@ -124,6 +116,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;
}
}
......
......@@ -100,7 +100,8 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& goal)
do
{
if(Algo::Geometry::isPointOnHalfEdge<PFP>(m,d,positionAttribut,goal)
&& Algo::Geometry::isPointOnHalfEdge<PFP>(m,this->m.phi2(d),positionAttribut,goal))
&& Algo::Geometry::isPointOnHalfEdge<PFP>(m,this->m.phi2(d),positionAttribut,goal)
&& this->getOrientationEdge(goal, this->d) == Geom::ALIGNED)
{
edgeState(goal) ;
return;
......
#ifndef PARTCELL2DMEMO_H
#define PARTCELL2DMEMO_H
//#define DEBUG
#include "particle_cell_2D.h"
#include "Algo/Geometry/inclusion.h"
......@@ -29,34 +29,27 @@ public:
typedef typename PFP::VEC3 VEC3;
typedef VertexAttribute<typename PFP::VEC3> TAB_POS ;
std::list<Dart> memo_cross ;
bool detect_vertex ;
bool detect_edge ;
bool detect_face ;
private:
ParticleCell2DMemo() :
detect_vertex(false), detect_edge(false), detect_face(true)
{
ParticleCell2DMemo(){
}
public:
ParticleCell2DMemo(MAP& map, Dart belonging_cell, VEC3 pos, const TAB_POS& tabPos) :
ParticleCell2D<PFP>(map, belonging_cell, pos, tabPos),
detect_vertex(false),
detect_edge(false),
detect_face(true)
ParticleCell2D<PFP>(map, belonging_cell, pos, tabPos)
{
}
void vertexState(const VEC3& current) ;
void vertexState(const VEC3& current, CellMarkerMemo<FACE> * memo_cross) ;
void edgeState(const VEC3& current, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ;
void edgeState(const VEC3& current, CellMarkerMemo<FACE> * memo_cross, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ;
void faceState(const VEC3& current) ;
void faceState(const VEC3& current, CellMarkerMemo<FACE> * memo_cross) ;
void move(const VEC3& goal) ;
void move(const VEC3& goal, CellMarkerMemo<FACE> * memo_cross) ;
std::vector<Dart> get_memo(const VEC3& goal);
} ;
#include "particle_cell_2D_memo.hpp"
......
template <typename PFP>
void ParticleCell2DMemo<PFP>::move(const VEC3& goal)
void ParticleCell2DMemo<PFP>::move(const VEC3& goal, CellMarkerMemo<FACE> * memo_cross)
{
this->crossCell = NO_CROSS ;
if (!Geom::arePointsEquals(goal, this->getPosition()))
......@@ -7,13 +7,13 @@ void ParticleCell2DMemo<PFP>::move(const VEC3& goal)
switch (this->getState())
{
case VERTEX :
vertexState(goal) ;
vertexState(goal,memo_cross) ;
break ;
case EDGE :
edgeState(goal) ;
edgeState(goal,memo_cross) ;
break ;
case FACE :
faceState(goal) ;
faceState(goal,memo_cross) ;
break ;
}
}
......@@ -22,13 +22,22 @@ void ParticleCell2DMemo<PFP>::move(const VEC3& goal)
}
template <typename PFP>
void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current)
std::vector<Dart> ParticleCell2DMemo<PFP>::get_memo(const VEC3& goal)
{
CellMarkerMemo<FACE> memo_cross(this->m);
memo_cross.mark(this->d);
this->move(goal,&memo_cross);
return memo_cross.get_markedCells();
}
template <typename PFP>
void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current, CellMarkerMemo<FACE> * memo_cross)
{
#ifdef DEBUG
CGoGNout << "vertexState" << d << CGoGNendl ;
CGoGNout << "vertexState" << this->d << CGoGNendl ;
#endif
assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
(*memo_cross).mark(this->d);
this->crossCell = CROSS_OTHER ;
if (Algo::Geometry::isPointOnVertex < PFP > (this->m, this->d, this->positionAttribut, current))
......@@ -67,9 +76,12 @@ void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current)
do
{
if(Algo::Geometry::isPointOnHalfEdge<PFP>(this->m,this->d,this->positionAttribut,current)
&& Algo::Geometry::isPointOnHalfEdge<PFP>(this->m,this->m.phi2(this->d),this->positionAttribut,current))
&& Algo::Geometry::isPointOnHalfEdge<PFP>(this->m,this->m.phi2(this->d),this->positionAttribut,current)
&& this->getOrientationEdge(current, this->d) == Geom::ALIGNED)
{
this->edgeState(current) ;
this->edgeState(current,memo_cross) ;
return;
}
this->d = this->m.phi2_1(this->d) ;
......@@ -94,31 +106,28 @@ void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current)
}
//displacement step
if (detect_vertex)
memo_cross.push_back(this->d) ;
if (this->getOrientationEdge(current, this->d) == Geom::ALIGNED
&& Algo::Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
edgeState(current) ;
edgeState(current,memo_cross) ;
else
{
this->d = this->m.phi1(this->d) ;
faceState(current) ;
faceState(current,memo_cross) ;
}
}
}
template <typename PFP>
void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, Geom::Orientation2D sideOfEdge)
void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, CellMarkerMemo<FACE>* memo_cross, Geom::Orientation2D sideOfEdge)
{
#ifdef DEBUG
CGoGNout << "edgeState" << d << CGoGNendl ;
CGoGNout << "edgeState" << this->d << CGoGNendl ;
#endif
if (detect_edge)
memo_cross.push_back(this->d) ;
assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
// assert(Algo::Geometry::isPointOnEdge<PFP>(m,d,m_positions,m_position));
(*memo_cross).mark(this->d);
if (this->crossCell == NO_CROSS)
{
this->crossCell = CROSS_EDGE ;
......@@ -133,11 +142,11 @@ void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, Geom::Orientation2D
{
case Geom::LEFT :
this->d = this->m.phi1(this->d) ;
faceState(current) ;
faceState(current,memo_cross) ;
return ;
case Geom::RIGHT :
this->d = this->m.phi1(this->m.phi2(this->d)) ;
faceState(current) ;
faceState(current,memo_cross) ;
return ;
default :
this->setState(EDGE) ;
......@@ -148,7 +157,7 @@ void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, Geom::Orientation2D
> (this->m, this->d, this->positionAttribut, current))
{
this->ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
vertexState(current) ;
vertexState(current,memo_cross) ;
return ;
}
else if (!Algo::Geometry::isPointOnHalfEdge < PFP
......@@ -156,7 +165,7 @@ void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, Geom::Orientation2D
{
this->d = this->m.phi2(this->d) ;
this->ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
vertexState(current) ;
vertexState(current,memo_cross) ;
return ;
}
......@@ -164,18 +173,18 @@ void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, Geom::Orientation2D
}
template <typename PFP>
void ParticleCell2DMemo<PFP>::faceState(const VEC3& current)
void ParticleCell2DMemo<PFP>::faceState(const VEC3& current, CellMarkerMemo<FACE> * memo_cross)
{
#ifdef DEBUG
CGoGNout << "faceState" << d << CGoGNendl ;
CGoGNout << "faceState" << this->d << CGoGNendl ;
#endif
if (detect_face) memo_cross.push_back(this->d) ;
assert(
std::isfinite(this->getPosition()[0]) && std::isfinite(this->getPosition()[1])
&& std::isfinite(this->getPosition()[2])) ;
assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
// assert(Algo::Geometry::isPointInConvexFace2D<PFP>(m,d,m_positions,m_position,true));
(*memo_cross).mark(this->d);
Dart dd = this->d ;
float wsoe = this->getOrientationFace(current, this->m.phi1(this->d)) ;
......@@ -202,7 +211,7 @@ void ParticleCell2DMemo<PFP>::faceState(const VEC3& current)
break ;
case Geom::ALIGNED :
this->ParticleBase<PFP>::move(current) ;
edgeState(current) ;
edgeState(current,memo_cross) ;
return ;
case Geom::RIGHT :
// CGoGNout << "smthg went bad " << m_position << " " << current << CGoGNendl;
......@@ -210,7 +219,7 @@ void ParticleCell2DMemo<PFP>::faceState(const VEC3& current)
this->ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
// CGoGNout << " " << m_position << CGoGNendl;
edgeState(current, Geom::RIGHT) ;
edgeState(current,memo_cross, Geom::RIGHT) ;
return ;
}
} while (this->d != dd) ;
......@@ -252,13 +261,13 @@ void ParticleCell2DMemo<PFP>::faceState(const VEC3& current)
case Geom::ALIGNED :
// CGoGNout << "pic" << CGoGNendl;
this->ParticleBase<PFP>::move(current) ;
edgeState(current) ;
edgeState(current,memo_cross) ;
return ;
case Geom::RIGHT :
// CGoGNout << "smthg went bad(2) " << m_position << CGoGNendl;
this->ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
// CGoGNout << " " << m_position << CGoGNendl;
edgeState(current, Geom::RIGHT) ;
edgeState(current,memo_cross ,Geom::RIGHT) ;
return ;
}
} while (this->d != dd) ;
......@@ -294,12 +303,12 @@ void ParticleCell2DMemo<PFP>::faceState(const VEC3& current)
this->d = this->m.phi1(this->d) ; //to check
this->ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
vertexState(current) ;
vertexState(current,memo_cross) ;
}
else
{
this->ParticleBase<PFP>::move(this->intersectLineEdge(current, this->getPosition(), this->d)) ;
edgeState(current, Geom::RIGHT) ;
edgeState(current,memo_cross, Geom::RIGHT) ;
}
}
......
......@@ -35,16 +35,12 @@ namespace Geom
enum OrientationLine
{
CW,
CCW,
INTERSECT
CW, CCW, INTERSECT
} ;
enum Orientation2D
{
ALIGNED,
RIGHT,
LEFT
ALIGNED, RIGHT, LEFT
} ;
/**
......@@ -56,18 +52,18 @@ template <typename VEC3>
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