Commit 200b462f authored by Thomas's avatar Thomas
Browse files

ajout fusion sommet, import chemin svg et debug fction geom

parent 3806dbad
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
#include "Algo/Render/GL2/topo3Render.h" #include "Algo/Render/GL2/topo3Render.h"
#include "Utils/Shaders/shaderSimpleColor.h" #include "Utils/Shaders/shaderSimpleColor.h"
#include "Utils/cgognStream.h" #include "Utils/cgognStream.h"
#include "Utils/drawer.h" #include "Utils/drawer.h"
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __ALGO_BOOLEANOPERATOR_VERTICES_H__
#define __ALGO_BOOLEANOPERATOR_VERTICES_H__
#include "Geometry/basic.h"
#include "Geometry/inclusion.h"
#include "Geometry/orientation.h"
namespace CGoGN
{
namespace Algo
{
namespace BooleanOperator
{
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const typename PFP::TVEC3& positions, Dart d, Dart e);
template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const typename PFP::TVEC3& positions);
}
}
}
#include "mergeVertices.hpp"
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
namespace CGoGN
{
namespace Algo
{
namespace BooleanOperator
{
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const typename PFP::TVEC3& positions, Dart d, Dart e)
{
assert(Geom::arePointsEquals(positions[d],positions[e]) && !map.sameVertex(d,e));
Dart dd;
do
{
dd = map.alpha1(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.alpha1(ee))])==Geom::RIGHT)
{
break;
}
ee = map.alpha1(ee);
} while(ee != e);
map.insertEdgeInVertex(ee,dd);
} while(dd!=d);
}
template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const typename PFP::TVEC3& positions)
{
for(Dart d = map.begin() ; d != map.end() ; map.next(d))
{
CellMarker vM(map,VERTEX);
vM.mark(d);
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);
}
}
}
}
}
}
}
}
...@@ -95,7 +95,7 @@ void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, typename PFP::TV ...@@ -95,7 +95,7 @@ void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, typename PFP::TV
if(position[dd][0]!=position[map.phi1(dd)][0] || position[dd][1]!=position[map.phi1(dd)][1] || position[dd][2]!=position[map.phi1(dd)][2]) { if(position[dd][0]!=position[map.phi1(dd)][0] || position[dd][1]!=position[map.phi1(dd)][1] || position[dd][2]!=position[map.phi1(dd)][2]) {
out << "cylinder{ " << std::endl; out << "cylinder{ " << std::endl;
out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl; out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl;
out << "<" << position[map.phi1(dd)][0] << "," << position[map.phi1(dd)][2] << "," << position[map.phi1(dd)][1] << ">, 0.5" << std::endl; out << "<" << position[map.phi1(dd)][0] << "," << position[map.phi1(dd)][2] << "," << position[map.phi1(dd)][1] << ">, 1.5" << std::endl;
out << "}" << std::endl; out << "}" << std::endl;
} }
dd = map.phi1(dd); dd = map.phi1(dd);
......
...@@ -16,7 +16,7 @@ namespace Import ...@@ -16,7 +16,7 @@ namespace Import
* @param name the name * @param name the name
* @ return true if node has the good name * @ return true if node has the good name
*/ */
bool chechXmlNode(xmlNodePtr node, const std::string& name); bool checkXmlNode(xmlNodePtr node, const std::string& name);
template <typename PFP> template <typename PFP>
bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position, CellMarker& polygons); bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position, CellMarker& polygons);
......
This diff is collapsed.
...@@ -71,6 +71,9 @@ public : ...@@ -71,6 +71,9 @@ public :
void edgeState(const VEC3& current, Geom::Orientation2D sideOfEdge=Geom::ALIGNED); 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
Dart faceOrientationState(const VEC3& toward);
void faceState(const VEC3& current); void faceState(const VEC3& current);
void move(const VEC3& newCurrent) void move(const VEC3& newCurrent)
......
...@@ -45,12 +45,6 @@ typename PFP::VEC3 ParticleCell2D<PFP>::intersectLineEdge(const VEC3& pA, const ...@@ -45,12 +45,6 @@ typename PFP::VEC3 ParticleCell2D<PFP>::intersectLineEdge(const VEC3& pA, const
Geom::intersection2DSegmentSegment(pA,pB,q1,q2,Inter); Geom::intersection2DSegmentSegment(pA,pB,q1,q2,Inter);
// if(VEC3(Inter-pA).norm()>VEC3(pA-pB).norm()) {
// CGoGNout << "probleme : " << pA << "/" << pB << "/" << q1 << "/" << q2 << "/" << Inter << CGoGNendl;
// CGoGNout << "isPointOnHalf " << Algo::Geometry::isPointOnHalfEdge<PFP>(m,d,m_positions,Inter) << CGoGNendl;
// CGoGNout << "isPointOnHalf " << Algo::Geometry::isPointOnHalfEdge<PFP>(m,m.phi1(d),m_positions,Inter) << CGoGNendl;
// }
return Inter; return Inter;
} }
...@@ -74,6 +68,7 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& current) ...@@ -74,6 +68,7 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& current)
if(Algo::Geometry::isPointOnVertex<PFP>(m,d,m_positions,current)) if(Algo::Geometry::isPointOnVertex<PFP>(m,d,m_positions,current))
{ {
state = VERTEX; state = VERTEX;
m_position = current;
return; return;
} }
else else
...@@ -101,6 +96,7 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& current) ...@@ -101,6 +96,7 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& current)
} }
else else
{ {
m_position = current;
state = VERTEX; state = VERTEX;
return; return;
} }
...@@ -176,6 +172,85 @@ void ParticleCell2D<PFP>::edgeState(const VEC3& current, Geom::Orientation2D sid ...@@ -176,6 +172,85 @@ void ParticleCell2D<PFP>::edgeState(const VEC3& current, Geom::Orientation2D sid
vertexState(current); vertexState(current);
return; return;
} }
m_position = current;
}
template <typename PFP>
Dart ParticleCell2D<PFP>::faceOrientationState(const VEC3& toward)
{
#ifdef DEBUG
CGoGNout << "faceOrientationState" << d << CGoGNendl;
#endif
assert(std::isfinite(m_position[0]) && std::isfinite(m_position[1]) && std::isfinite(m_position[2]));
assert(std::isfinite(toward[0]) && std::isfinite(toward[1]) && std::isfinite(toward[2]));
Dart res = d;
Dart dd = d;
float wsoe = getOrientationFace(toward, m_position, m.phi1(res));
// orientation step
if(wsoe != Geom::RIGHT)
{
res = m.phi1(res);
wsoe = getOrientationFace(toward, m_position, m.phi1(res));
while(wsoe != Geom::RIGHT && dd != res)
{
res = m.phi1(res);
wsoe = getOrientationFace(toward, m_position, m.phi1(res));
}
// source and position to reach are the same : verify if no edge is crossed due to numerical approximation
if(dd == res)
{
do
{
switch (getOrientationEdge(toward, res))
{
case Geom::LEFT: res = m.phi1(res);
break;
case Geom::ALIGNED:
return res;
case Geom::RIGHT:
return res;
}
} while(res != dd);
return res;
}
}
else
{
wsoe = getOrientationFace(toward,m_position,d);
while(wsoe == Geom::RIGHT && m.phi_1(res) != dd)
{
res = m.phi_1(res);
wsoe = getOrientationFace(toward, m_position, res);
}
// in case of numerical incoherence
if(m.phi_1(res) == dd && wsoe == Geom::RIGHT)
{
res = m.phi_1(res);
do
{
switch (getOrientationEdge(toward, res))
{
case Geom::LEFT :
res = m.phi1(res);
break;
case Geom::ALIGNED :
return res;
case Geom::RIGHT :
return res;
}
} while(res != dd);
return res;
}
}
return res;
} }
template <typename PFP> template <typename PFP>
...@@ -215,10 +290,11 @@ void ParticleCell2D<PFP>::faceState(const VEC3& current) ...@@ -215,10 +290,11 @@ void ParticleCell2D<PFP>::faceState(const VEC3& current)
case Geom::ALIGNED: m_position = current; case Geom::ALIGNED: m_position = current;
edgeState(current); edgeState(current);
return; return;
case Geom::RIGHT: CGoGNout << "smthg went bad " << m_position << " " << current << CGoGNendl; case Geom::RIGHT:
CGoGNout << "d1 " << m_positions[d] << " d2 " << m_positions[m.phi1(d)] << CGoGNendl; // CGoGNout << "smthg went bad " << m_position << " " << current << CGoGNendl;
// CGoGNout << "d1 " << m_positions[d] << " d2 " << m_positions[m.phi1(d)] << CGoGNendl;
m_position = intersectLineEdge(current, m_position, d); m_position = intersectLineEdge(current, m_position, d);
CGoGNout << " " << m_position << CGoGNendl; // CGoGNout << " " << m_position << CGoGNendl;
edgeState(current,Geom::RIGHT); edgeState(current,Geom::RIGHT);
return; return;
...@@ -265,7 +341,7 @@ void ParticleCell2D<PFP>::faceState(const VEC3& current) ...@@ -265,7 +341,7 @@ void ParticleCell2D<PFP>::faceState(const VEC3& current)
edgeState(current); edgeState(current);
return; return;
case Geom::RIGHT : case Geom::RIGHT :
CGoGNout << "smthg went bad(2) " << m_position << CGoGNendl; // CGoGNout << "smthg went bad(2) " << m_position << CGoGNendl;
m_position = intersectLineEdge(current, m_position, d); m_position = intersectLineEdge(current, m_position, d);
// CGoGNout << " " << m_position << CGoGNendl; // CGoGNout << " " << m_position << CGoGNendl;
edgeState(current, Geom::RIGHT); edgeState(current, Geom::RIGHT);
...@@ -300,6 +376,7 @@ void ParticleCell2D<PFP>::faceState(const VEC3& current) ...@@ -300,6 +376,7 @@ void ParticleCell2D<PFP>::faceState(const VEC3& current)
default : default :
if(wsoe == Geom::ALIGNED) if(wsoe == Geom::ALIGNED)
{ {
d = m.phi1(d); //to check
m_position = m_positions[d]; m_position = m_positions[d];
vertexState(current); vertexState(current);
} }
......
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
NoMathNameAttribute(const T& att): T(att) {} NoMathNameAttribute(const T& att): T(att) {}
NoMathNameAttribute<T>& operator = (const T& fa) { *this = NoMathNameAttribute<T>(fa); } NoMathNameAttribute<T>& operator = (const T& fa) { return *this = NoMathNameAttribute<T>(fa); }
void operator += (const NoMathNameAttribute<T>& fa) {} void operator += (const NoMathNameAttribute<T>& fa) {}
void operator -= (const NoMathNameAttribute<T>& fa) {} void operator -= (const NoMathNameAttribute<T>& fa) {}
void operator *= (double v) {} void operator *= (double v) {}
......
...@@ -314,15 +314,28 @@ Intersection intersection2DSegmentSegment(const VEC3& PA, const VEC3& PB, const ...@@ -314,15 +314,28 @@ Intersection intersection2DSegmentSegment(const VEC3& PA, const VEC3& PB, const
{ {
typedef typename VEC3::DATA_TYPE T ; typedef typename VEC3::DATA_TYPE T ;
VEC3 vp1p2(PB); VEC3 vp1p2 = PB - PA;
vp1p2 -= PA; VEC3 vq1q2 = QB - QA;
VEC3 vq1q2(QB); VEC3 vp1q1 = QA - PA;
vq1q2 -= QA;
VEC3 vp1q1(QA);
vp1q1 -= PA;
T delta = vp1p2[0]*vq1q2[1]- vp1p2[1]*vq1q2[0]; T delta = vp1p2[0]*vq1q2[1]- vp1p2[1]*vq1q2[0];
T coeff = vp1q1[0]*vq1q2[1]- vp1q1[1]*vq1q2[0]; T coeff = vp1q1[0]*vq1q2[1]- vp1q1[1]*vq1q2[0];
Inter = VEC3((PA[0]*delta+vp1p2[0]*coeff)/delta,(PA[1]*delta+vp1p2[1]*coeff)/delta,(PA[2]*delta+vp1p2[2]*coeff)/delta);
if(delta==0) //parallel
{
//test if collinear
if(coeff==0)
{
//collinear
//TODO : check if there is a common point between the two edges
Inter = QA;
return EDGE_INTERSECTION;
}
else
return NO_INTERSECTION;
}
else
Inter = VEC3((PA[0]*delta+vp1p2[0]*coeff)/delta,(PA[1]*delta+vp1p2[1]*coeff)/delta,(PA[2]*delta+vp1p2[2]*coeff)/delta);
//test if inter point is outside the edges //test if inter point is outside the edges
if( (Inter[0]<PA[0] && Inter[0]<PB[0]) || (Inter[0]>PA[0] && Inter[0]>PB[0]) if( (Inter[0]<PA[0] && Inter[0]<PB[0]) || (Inter[0]>PA[0] && Inter[0]>PB[0])
...@@ -332,6 +345,9 @@ Intersection intersection2DSegmentSegment(const VEC3& PA, const VEC3& PB, const ...@@ -332,6 +345,9 @@ Intersection intersection2DSegmentSegment(const VEC3& PA, const VEC3& PB, const
) )
return NO_INTERSECTION; return NO_INTERSECTION;
if(Geom::arePointsEquals(PA,Inter) || Geom::arePointsEquals(PB,Inter) || Geom::arePointsEquals(QA,Inter) || Geom::arePointsEquals(QB,Inter))
return VERTEX_INTERSECTION;
return EDGE_INTERSECTION; return EDGE_INTERSECTION;
} }
......
...@@ -45,11 +45,14 @@ template <typename T> ...@@ -45,11 +45,14 @@ template <typename T>
class Plane3D class Plane3D
{ {
public: public:
static std::string CGoGNnameOfType() ;
/**********************************************/ /**********************************************/
/* CONSTRUCTORS */ /* CONSTRUCTORS */
/**********************************************/ /**********************************************/
Plane3D(); Plane3D(int d = 0);
Plane3D(const Plane3D<T>& p); Plane3D(const Plane3D<T>& p);
......
...@@ -28,13 +28,25 @@ namespace CGoGN ...@@ -28,13 +28,25 @@ namespace CGoGN
namespace Geom namespace Geom
{ {
template <typename T>
std::string Plane3D<T>::CGoGNnameOfType()
{
std::stringstream ss ;
ss << "Geom::Plane3D<" ;
ss << nameOfType(T()) ;
ss << ">" ;
return ss.str() ;
}
/**********************************************/ /**********************************************/
/* CONSTRUCTORS */ /* CONSTRUCTORS */
/**********************************************/ /**********************************************/
template <typename T> template <typename T>
Plane3D<T>::Plane3D() Plane3D<T>::Plane3D(int d) :
{} m_normal(0), m_d(d)
{ }
template <typename T> template <typename T>
Plane3D<T>::Plane3D(const Plane3D<T>& p) Plane3D<T>::Plane3D(const Plane3D<T>& p)
...@@ -110,7 +122,7 @@ void Plane3D<T>::project(Vector<3,T>& p) const ...@@ -110,7 +122,7 @@ void Plane3D<T>::project(Vector<3,T>& p) const
T d = -distance(p) ; T d = -distance(p) ;
if(abs(d) > PRECISION) if(abs(d) > PRECISION)
{ {
Vector<3,T> v = m_normal / d ; Vector<3,T> v = m_normal * d ;
p += v ; p += v ;
} }
#undef PRECISION #undef PRECISION
......
...@@ -49,6 +49,12 @@ public: ...@@ -49,6 +49,12 @@ public:
*/ */
virtual bool deleteVertex(Dart d) ; virtual bool deleteVertex(Dart d) ;
/**
* No attribute is attached to the new edge
* The attributes attached to the face of dart d are kept on the resulting face
*/
virtual void linkVertices(Dart d, Dart e) ;
/** /**
* No attribute is attached to the new vertex * No attribute is attached to the new vertex
* The attributes attached to the old edge are duplicated on both resulting edges * The attributes attached to the old edge are duplicated on both resulting edges
...@@ -84,6 +90,18 @@ public: ...@@ -84,6 +90,18 @@ public:
*/ */
virtual bool flipBackEdge(Dart d) ; virtual bool flipBackEdge(Dart d) ;
/**
* The attributes attached to the vertex of dart d are kept on the resulting vertex
* The attributes attached to the face of dart d are overwritten on the face of dart e
*/
virtual void insertEdgeInVertex(Dart d, Dart e);
/**
* The attributes attached to the vertex of dart d are kept on the resulting vertex
* The attributes attached to the face of dart d are overwritten on the face of dart e
*/
virtual void removeEdgeFromVertex(Dart d);
/** /**
* The attributes attached to the vertices of the edge of d are kept on the vertices of the resulting edge * The attributes attached to the vertices of the edge of d are kept on the vertices of the resulting edge
* The attributes attached to the edge of d are kept on the resulting edge * The attributes attached to the edge of d are kept on the resulting edge
...@@ -107,12 +125,6 @@ public: ...@@ -107,12 +125,6 @@ public:
*/ */
virtual void splitFace(Dart d, Dart e) ; virtual void splitFace(Dart d, Dart e) ;
/**
* No attribute is attached to the new edge
* The attributes attached to the face of dart d are kept on the resulting face
*/
virtual void linkVertices(Dart d, Dart e) ;
/** /**
* The attributes attached to the face of dart d are kept on the resulting face * The attributes attached to the face of dart d are kept on the resulting face
*/ */
......
...@@ -66,6 +66,25 @@ bool EmbeddedMap2<MAP2>::deleteVertex(Dart d) ...@@ -66,6 +66,25 @@ bool EmbeddedMap2<MAP2>::deleteVertex(Dart d)
return false ; return false ;
} }
template <typename MAP2>
void EmbeddedMap2<MAP2>::linkVertices(Dart d, Dart e)
{
Dart dNext = MAP2::phi1(d) ;
MAP2::linkVertices(d,e);