Commit 271c50a6 authored by Sylvain Thery's avatar Sylvain Thery

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

Conflicts:
	include/Algo/Import/importSvg.hpp
parents a07476af 0f35dc93
...@@ -45,10 +45,10 @@ template <typename PFP> ...@@ -45,10 +45,10 @@ template <typename PFP>
bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, Dart f) ; bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, Dart f) ;
template <typename PFP> template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e); void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e);
template <typename PFP> template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions); void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions);
} }
......
...@@ -43,55 +43,61 @@ bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3> ...@@ -43,55 +43,61 @@ bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>
} }
template <typename PFP> template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e) void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, Dart d, Dart e, int precision)
{ {
assert(Geom::arePointsEquals(positions[d],positions[e]) && !map.sameVertex(d,e)); assert(positions[d].isNear(positions[e], precision) && !map.sameVertex(d, e)) ;
// 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);
// 0-embed z on the vertex of x without copy of the vertex bool notempty = true ;
// positions[d] = ; do // While vertex of e contains more than one dart
} {
Dart e1 = map.alpha1(e) ; // e1 stores next dart of vertex of e
if (e1 == e)
notempty = false ; // last dart of vertex of e
else {
map.removeEdgeFromVertex(e) ; // detach e from its vertex
}
// Searchs where e may be inserted in the vertex of d
Dart d1 = d ;
do
{
if (CGoGN::Algo::BooleanOperator::isBetween<PFP>(map, positions, e, d,
map.alpha1(d))) break ;
d = map.alpha1(d) ;
} while (d != d1) ;
// Inserted e in the correct place (after d)
map.insertEdgeInVertex(d, e) ;
// Go on with next darts
d = e ;
e = e1 ;
} while (notempty) ;
}
template <typename PFP> template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3>& positions) void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& positions, int precision)
{ {
// TODO optimiser en triant les sommets // TODO optimiser en triant les sommets
for(Dart d = map.begin() ; d != map.end() ; map.next(d)) // map.template enableQuickTraversal<VERTEX>();
TraversorV<typename PFP::MAP> travV1(map) ;
CellMarker<VERTEX> vM(map);
for(Dart d1 = travV1.begin() ; d1 != travV1.end() ; d1 = travV1.next())
{ {
CellMarker<VERTEX> vM(map); vM.mark(d1);
vM.mark(d); TraversorV<typename PFP::MAP> travV2(map) ;
std::cout << "." ; std::cout.flush() ; for(Dart d2 = travV2.begin() ; d2 != travV2.end() ; d2 = travV2.next())
for(Dart dd = map.begin() ; dd != map.end() ; map.next(dd))
{ {
if(!vM.isMarked(dd)) if(!vM.isMarked(d2))
{ {
if(Geom::arePointsEquals(positions[d],positions[dd])) if(positions[d1].isNear(positions[d2], precision))
{ {
mergeVertex<PFP>(map,positions,d,dd); if (map.sameVertex(d1,d2)) std::cout << "fusion: sameVertex" << std::endl ;
if (!map.sameVertex(d1,d2)) mergeVertex<PFP>(map,positions,d1,d2,precision);
} }
} }
} }
} }
// map.template disableQuickTraversal<VERTEX>();
} }
} }
......
This diff is collapsed.
...@@ -176,9 +176,6 @@ Dart revolution(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& ...@@ -176,9 +176,6 @@ Dart revolution(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>&
* @param the_map the map in which include created surface * @param the_map the map in which include created surface
* @param d a dart of the face to extrude * @param d a dart of the face to extrude
* @param N the vector use to extrude face center (point) of axis revolution * @param N the vector use to extrude face center (point) of axis revolution
* @param axis direction of axis revolution
* @param profile_closed profile is a closed polygon or not ?
* @param nbSide number of steps around the revolution
*/ */
template<typename PFP> template<typename PFP>
Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& positions, Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& positions,
...@@ -188,10 +185,7 @@ Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3> ...@@ -188,10 +185,7 @@ Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>
* Face extrusion * Face extrusion
* @param the_map the map in which include created surface * @param the_map the map in which include created surface
* @param d a dart of the face to extrude * @param d a dart of the face to extrude
* @param N the vector use to extrude face center (point) of axis revolution * @param dist the height to extrude face
* @param axis direction of axis revolution
* @param profile_closed profile is a closed polygon or not ?
* @param nbSide number of steps around the revolution
*/ */
template<typename PFP> template<typename PFP>
Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& positions, Dart extrudeFace(typename PFP::MAP& the_map, VertexAttribute<typename PFP::VEC3>& positions,
......
...@@ -453,36 +453,42 @@ void LoopSubdivision(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3> ...@@ -453,36 +453,42 @@ void LoopSubdivision(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>
template <typename PFP, typename EMBV, typename EMB> template <typename PFP, typename EMBV, typename EMB>
void TwoNPlusOneSubdivision(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected) void TwoNPlusOneSubdivision(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected)
{ {
EdgeAutoAttribute<Dart> tablePred(map);
CellMarker<EDGE> m0(map); CellMarker<EDGE> m0(map);
CellMarker<FACE> m1(map);
std::vector<Dart> dOrig; std::vector<Dart> dOrig;
std::vector<EMB> cOrig;
m0.unmarkAll();
m1.unmarkAll();
//first pass cut edge //first pass cut edge
for (Dart d = map.begin(); d != map.end(); map.next(d)) for (Dart d = map.begin(); d != map.end(); map.next(d))
{ {
if(selected(d)) if(selected(d))
{ {
if(!m0.isMarked(d)) { if(!m0.isMarked(d))
dOrig.push_back(d); {
if(!m1.isMarked(d))
Dart dd = d; {
do { m1.mark(d);
if(!m0.isMarked(dd)) { dOrig.push_back(d);
EMB e1 = attributs[dd]; }
EMB e2 = attributs[map.phi1(dd)];
map.cutEdge(dd);
attributs[map.phi1(dd)] = e1*2.0f/3.0f+e2/3.0f;
map.cutEdge(map.phi1(dd));
attributs[map.phi1(map.phi1(dd))] = e2*2.0f/3.0f+e1/3.0f;
m0.mark(dd);
m0.mark(map.phi1(dd));
m0.mark(map.template phi<11>(dd));
}
dd = map.template phi<111>(dd);
} while(dd!=d);
if(selected(map.phi2(d)) && !m1.isMarked(map.phi2(d)))
{
m1.mark(map.phi2(d));
dOrig.push_back(map.phi2(d));
}
EMB e1 = attributs[d];
EMB e2 = attributs[map.phi1(d)];
map.cutEdge(d);
attributs[map.phi1(d)] = e1*2.0f/3.0f+e2/3.0f;
map.cutEdge(map.phi1(d));
attributs[map.phi1(map.phi1(d))] = e2*2.0f/3.0f+e1/3.0f;
m0.mark(d);
m0.mark(map.phi1(d));
m0.mark(map.template phi<11>(d));
} }
} }
} }
......
...@@ -70,14 +70,14 @@ public: ...@@ -70,14 +70,14 @@ public:
Geom::Orientation2D getOrientationFace(VEC3 sourcePoint, Dart d) ; Geom::Orientation2D getOrientationFace(VEC3 sourcePoint, Dart d) ;
void vertexState(const VEC3& current) ; virtual void vertexState(const VEC3& current) ;
void edgeState(const VEC3& current, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ; virtual void edgeState(const VEC3& current, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ;
//just an orientation test : check which dart is aimed to leave the current face to reach an other position //just an orientation test : check which dart is aimed to leave the current face to reach an other position
Dart faceOrientationState(const VEC3& toward) ; Dart faceOrientationState(const VEC3& toward) ;
void faceState(const VEC3& current) ; virtual void faceState(const VEC3& current) ;
void move(const VEC3& goal) void move(const VEC3& goal)
{ {
......
...@@ -42,11 +42,11 @@ public: ...@@ -42,11 +42,11 @@ public:
} }
void vertexState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross) ; virtual void vertexState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross) ;
void edgeState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ; virtual void edgeState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ;
void faceState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross) ; virtual void faceState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross) ;
std::vector<Dart> move(const VEC3& goal) ; std::vector<Dart> move(const VEC3& goal) ;
std::vector<Dart> move(const VEC3& goal, CellMarkerMemo<FACE>& memo_cross) ; std::vector<Dart> move(const VEC3& goal, CellMarkerMemo<FACE>& memo_cross) ;
......
#ifndef PARTCELL2DMEMOSECURED_H
#define PARTCELL2DMEMOSECURED_H
//#define DEBUG
#include "particle_cell_2D_memo.h"
#include "Algo/Geometry/inclusion.h"
#include "Geometry/intersection.h"
#include "Geometry/orientation.h"
#include <iostream>
/* A particle cell secured : version of particle cell-memo where particles might go outside the navigation map
* this class should be used for debug mode only */
namespace CGoGN
{
namespace Algo
{
namespace MovingObjects
{
template <typename PFP>
class ParticleCell2DSecured : public ParticleCell2DMemo<PFP>
{
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3;
typedef VertexAttribute<typename PFP::VEC3> TAB_POS ;
private:
ParticleCell2DSecured(){
std::cout << "Particle Secured : for debugging (unoptimized)" << std::endl;
}
public:
ParticleCell2DSecured(MAP& map, Dart belonging_cell, VEC3 pos, const TAB_POS& tabPos) :
ParticleCell2DMemo<PFP>(map, belonging_cell, pos, tabPos)
{
std::cout << "Particle Memo : for debugging (unoptimized)" << std::endl;
}
virtual void vertexState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross) ;
virtual void edgeState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross, Geom::Orientation2D sideOfEdge = Geom::ALIGNED) ;
virtual void faceState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross) ;
std::vector<Dart> move(const VEC3& goal) ;
std::vector<Dart> move(const VEC3& goal, CellMarkerMemo<FACE>& memo_cross) ;
} ;
#include "particle_cell_2D_secured.hpp"
} //MovingObject
} //Algo
} //CGoGN
#endif
template <typename PFP>
std::vector<Dart> ParticleCell2DSecured<PFP>::move(const VEC3& goal)
{
this->crossCell = NO_CROSS ;
if (!Geom::arePointsEquals(goal, this->getPosition()))
{
CellMarkerMemo<FACE> memo_cross(this->m);
// memo_cross.mark(this->d);
switch (this->getState())
{
case VERTEX :
vertexState(goal,memo_cross) ;
break ;
case EDGE :
edgeState(goal,memo_cross) ;
break ;
case FACE :
faceState(goal,memo_cross) ;
break ;
}
return memo_cross.get_markedCells();
}
else
this->ParticleBase<PFP>::move(goal) ;
std::vector<Dart> res;
res.push_back(this->d);
return res;
}
template <typename PFP>
void ParticleCell2DSecured<PFP>::vertexState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross)
{
#ifdef DEBUG
CGoGNout << "vertexState" << this->d << CGoGNendl ;
#endif
// std::vector<Dart> mc = memo_cross.get_markedCells();
// if(std::find(mc.begin(),mc.end(),this->d)!=mc.end())
// {
// std::cout << "Error : particle outside map (vertex) " << std::endl;
// return;
// }
// else
{
assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
this->crossCell = CROSS_OTHER ;
if (Algo::Geometry::isPointOnVertex < PFP > (this->m, this->d, this->positionAttribut, current))
{
this->setState(VERTEX) ;
this->ParticleBase<PFP>::move(current) ;
return ;
}
else
{
//orientation step
if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0] && this->positionAttribut[this->d][1] == this->positionAttribut[this->m.phi1(this->d)][1])
this->d = this->m.phi2_1(this->d) ;
if (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT)
{
Dart dd_vert = this->d ;
do
{
this->d = this->m.phi2_1(this->d) ;
if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0]
&& this->positionAttribut[this->d][1]== this->positionAttribut[this->m.phi1(this->d)][1])
this->d = this->m.phi2_1(this->d) ;
} while (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d) ;
if (dd_vert == this->d)
{
//orbit with 2 edges : point on one edge
if (this->m.phi2_1(this->m.phi2_1(this->d)) == this->d)
{
if (!Algo::Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
this->d = this->m.phi2_1(this->d) ;
}
else
{
//checking : case with 3 orthogonal darts and point on an edge
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)
&& this->getOrientationEdge(current, this->d) == Geom::ALIGNED)
{
this->edgeState(current,memo_cross) ;
return;
}
this->d = this->m.phi2_1(this->d) ;
} while (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d) ;
this->ParticleBase<PFP>::move(current) ;
this->setState(VERTEX) ;
return ;
}
}
}
else
{
Dart dd_vert = this->m.phi2_1(this->d) ;
while (this->getOrientationEdge(current, this->d) == Geom::RIGHT && dd_vert != this->d)
{
this->d = this->m.phi12(this->d) ;
if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0]
&& this->positionAttribut[this->d][1] == this->positionAttribut[this->m.phi1(this->d)][1])
this->d = this->m.phi12(this->d) ;
}
}
//displacement step
if (this->getOrientationEdge(current, this->d) == Geom::ALIGNED
&& Algo::Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
edgeState(current,memo_cross) ;
else
{
this->d = this->m.phi1(this->d) ;
faceState(current,memo_cross) ;
}
}
}
}
template <typename PFP>
void ParticleCell2DSecured<PFP>::edgeState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross, Geom::Orientation2D sideOfEdge)
{
#ifdef DEBUG
CGoGNout << "edgeState" << this->d << CGoGNendl ;
#endif
// std::vector<Dart> mc = memo_cross.get_markedCells();
// if(std::find(mc.begin(),mc.end(),this->d)!=mc.end())
// {
// std::cout << "Error : particle outside map (edge)" << std::endl;
// return;
// }
// else
{
assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
// assert(Algo::Geometry::isPointOnEdge<PFP>(m,d,m_positions,m_position));
if (this->crossCell == NO_CROSS)
{
this->crossCell = CROSS_EDGE ;
this->lastCrossed = this->d ;
}
else
this->crossCell = CROSS_OTHER ;
if (sideOfEdge == Geom::ALIGNED) sideOfEdge = this->getOrientationEdge(current, this->d) ;
switch (sideOfEdge)
{
case Geom::LEFT :
this->d = this->m.phi1(this->d) ;
faceState(current,memo_cross) ;
return ;
case Geom::RIGHT :
this->d = this->m.phi1(this->m.phi2(this->d)) ;
faceState(current,memo_cross) ;
return ;
default :
this->setState(EDGE) ;
break ;
}
if (!Algo::Geometry::isPointOnHalfEdge < PFP
> (this->m, this->d, this->positionAttribut, current))
{
this->ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
vertexState(current,memo_cross) ;
return ;
}
else if (!Algo::Geometry::isPointOnHalfEdge < PFP
> (this->m, this->m.phi2(this->d), this->positionAttribut, current))
{
this->d = this->m.phi2(this->d) ;
this->ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
vertexState(current,memo_cross) ;
return ;
}
this->ParticleBase<PFP>::move(current) ;
}
}
template <typename PFP>
void ParticleCell2DSecured<PFP>::faceState(const VEC3& current, CellMarkerMemo<FACE>& memo_cross)
{
#ifdef DEBUG
CGoGNout << "faceState" << this->d << CGoGNendl ;
#endif
std::vector<Dart> mc = memo_cross.get_markedCells();
if(std::find(mc.begin(),mc.end(),this->d)!=mc.end())
{
std::cout << "Error : particle outside map (face)" << std::endl;
return;
}
else
{
ParticleCell2DMemo<PFP>::faceState(current,memo_cross);
}
}
...@@ -35,7 +35,7 @@ Orientation2D testOrientation2D(const VEC3& P, const VEC3& Pa, const VEC3& Pb) ...@@ -35,7 +35,7 @@ Orientation2D testOrientation2D(const VEC3& P, const VEC3& Pa, const VEC3& Pb)
{ {
typedef typename VEC3::DATA_TYPE T ; typedef typename VEC3::DATA_TYPE T ;
const T zero = 0.0001 ; const T zero = 0.00001 ;
T p = (P[0] - Pa[0]) * (Pb[1] - Pa[1]) - (Pb[0] - Pa[0]) * (P[1] - Pa[1]) ; T p = (P[0] - Pa[0]) * (Pb[1] - Pa[1]) - (Pb[0] - Pa[0]) * (P[1] - Pa[1]) ;
......
...@@ -117,7 +117,7 @@ void Plane3D<T>::project(Vector<3,T>& p) const ...@@ -117,7 +117,7 @@ void Plane3D<T>::project(Vector<3,T>& p) const
{ {
#define PRECISION 1e-10 #define PRECISION 1e-10
T d = -distance(p) ; T d = -distance(p) ;
if(abs(d) > PRECISION) if(std::abs(d) > PRECISION)
{ {
Vector<3,T> v = m_normal * d ; Vector<3,T> v = m_normal * d ;
p += v ; p += v ;
......
...@@ -127,8 +127,16 @@ public: ...@@ -127,8 +127,16 @@ public:
double norm() const ; double norm() const ;
/*
* normalize the vector and returns its norm
*/
double normalize() ; double normalize() ;
/*
* Return a normalized copy
*/
Vector<DIM, T> normalized() const;
// dot product // dot product
T operator*(const Vector<DIM, T> v) const ; T operator*(const Vector<DIM, T> v) const ;
...@@ -152,13 +160,21 @@ public: ...@@ -152,13 +160,21 @@ public:
*/ */
bool isNormalized(const T& epsilon) const ; bool isNormalized(const T& epsilon) const ;
/**
* Tests if current and given vectors are near within 1/precision (equal if precision is zero)
* @param V a vector
* @param epsilon tolerated error
* @return true if orthogonal
*/
bool isNear(const Vector<DIM, T>& v, int precision) const ;
/** /**
* Tests if current and given vectors are orthogonal * Tests if current and given vectors are orthogonal
* @param V a vector * @param V a vector
* @param epsilon tolerated error * @param epsilon tolerated error
* @return true if orthogonal * @return true if orthogonal
*/ */
bool isOrthogonal(const Vector<DIM, T>& V, const T& epsilon = 1e-5) const ; bool isOrthogonal(const Vector<DIM, T>& v, const T& epsilon = 1e-5) const ;
/**********************************************/ /**********************************************/