Commit 3c7e8f3c authored by CGoGN GIT Supervisor's avatar CGoGN GIT Supervisor

Merge branch 'master' of /home/untereiner/CGoGN

* 'master' of /home/untereiner/CGoGN:
  boulette
  ...
  ihm3
  ajout fusion sommet, import chemin svg et debug fction geom
  lecture des path simple non ferme dans importSVG
  ajout fction linkVertices
  debbug svg
  ajout import svg
parents 7e3d811a 5a1ed4a6
......@@ -49,6 +49,8 @@
#include "Algo/Render/GL2/topo3Render.h"
#include "Utils/Shaders/shaderSimpleColor.h"
#include "Utils/cgognStream.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
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 << "<" << 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;
}
dd = map.phi1(dd);
......
......@@ -24,6 +24,7 @@
#include "Algo/Geometry/normal.h"
#include "Algo/Geometry/centroid.h"
#include "intersection.h"
#include <limits>
......@@ -37,17 +38,18 @@ namespace Geometry
{
template <typename PFP>
bool intersectionLineConvexFace(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, const typename PFP::VEC3& P, const typename PFP::VEC3& Dir, typename PFP::VEC3& Inter)
bool intersectionLineConvexFace(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& positions, const typename PFP::VEC3& P, const typename PFP::VEC3& Dir, typename PFP::VEC3& Inter)
{
typedef typename PFP::VEC3 VEC3 ;
const float SMALL_NUM = std::numeric_limits<typename PFP::REAL>::min() * 5.0f;
VEC3 p1 = position[d];
VEC3 n = faceNormal<PFP>(map, d, position);
VEC3 p1 = positions[d];
VEC3 n = faceNormal<PFP>(map,d,positions);
VEC3 w0 = P - p1;
float a = -(n * w0);
float b = n * Dir;
float a = -(n*w0);
float b = n*Dir;
if (fabs(b) < SMALL_NUM)
return false;
......@@ -56,7 +58,7 @@ bool intersectionLineConvexFace(typename PFP::MAP& map, Dart d, const typename P
Inter = P + r * Dir; // intersect point of ray and plane
// is I inside the face?
VEC3 p2 = position[map.phi1(d)];
VEC3 p2 = positions[map.phi1(d)];
VEC3 v = p2 - p1 ;
VEC3 vInter = Inter - p1;
float dirV = v * vInter;
......@@ -67,7 +69,7 @@ bool intersectionLineConvexFace(typename PFP::MAP& map, Dart d, const typename P
while(it != d)
{
p1 = p2;
p2 = position[map.phi1(it)];
p2 = positions[map.phi1(it)];
v = p2 - p1;
vInter = Inter - p1;
float dirD = v * vInter;
......@@ -83,22 +85,22 @@ bool intersectionLineConvexFace(typename PFP::MAP& map, Dart d, const typename P
}
template <typename PFP>
bool intersectionSegmentConvexFace(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, const typename PFP::VEC3& PA, const typename PFP::VEC3& PB, typename PFP::VEC3& Inter)
bool intersectionSegmentConvexFace(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& positions, const typename PFP::VEC3& PA, const typename PFP::VEC3& PB, typename PFP::VEC3& Inter)
{
typename PFP::VEC3 dir = PB - PA;
if (intersectionLineConvexFace(map, d, position, PA, dir, Inter))
if (intersectionLineConvexFace(map,d,positions,PA,dir,Inter))
{
typename PFP::VEC3 dirA = PA - Inter;
typename PFP::VEC3 dirB = PB - Inter;
typename PFP::VEC3 dirB = PB -Inter;
if (dirA * dirB < 0)
if ( (dirA*dirB) < 0 )
return true;
}
return false;
}
template <typename PFP>
bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, const typename PFP::TVEC3& position)
bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, const typename PFP::TVEC3& positions)
{
typedef typename PFP::VEC3 VEC3 ;
......@@ -107,8 +109,8 @@ bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, co
VEC3 tris2[3];
for (unsigned int i = 0; i < 3; ++i)
{
tris1[i] = position[tri1];
tris2[i] = position[tri2];
tris1[i] = positions[tri1];
tris2[i] = positions[tri2];
tri1 = map.phi1(tri1);
tri2 = map.phi1(tri2);
}
......@@ -165,8 +167,8 @@ bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, co
// return isSegmentInTriangle2D(inter1,inter2,tris2[0],tris2[1],triS2[2],nTri2);
//compute face normal
VEC3 normale1 = faceNormal<PFP>(map, tri1, position);
VEC3 bary1 = faceCentroid<PFP>(map, tri1, position);
VEC3 normale1 = faceNormal<PFP>(map,tri1,positions);
VEC3 bary1 = faceCentroid<PFP>(map,tri1,positions);
int pos = 0;
int neg = 0;
......@@ -186,8 +188,8 @@ bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, co
return false;
//same for the second triangle
VEC3 normale2 = faceNormal<PFP>(map, tri2, position);
VEC3 bary2 = faceCentroid<PFP>(map, tri2, position);
VEC3 normale2 = faceNormal<PFP>(map,tri2,positions);
VEC3 bary2 = faceCentroid<PFP>(map,tri2,positions);
pos = 0;
neg = 0;
for (unsigned int i = 0; i < 3 ; ++i)
......@@ -208,7 +210,7 @@ bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, co
for (unsigned int i = 0; i < 3 && !intersection; ++i)
{
VEC3 inter;
intersection = Geom::intersectionSegmentTriangle(tris1[i], tris1[(i+1)%3], tris2[0], tris2[1], tris2[2], inter);
intersection = Geom::intersectionSegmentTriangle(tris1[i],tris1[(i+1)%3],tris2[0],tris2[1],tris2[2],inter);
}
if (intersection)
......@@ -217,34 +219,14 @@ bool areTrianglesInIntersection(typename PFP::MAP& map, Dart tri1, Dart tri2, co
for (unsigned int i = 0; i < 3 && !intersection; ++i)
{
VEC3 inter;
intersection = Geom::intersectionSegmentTriangle(tris2[i], tris2[(i+1)%3], tris1[0], tris1[1], tris1[2], inter);
intersection = Geom::intersectionSegmentTriangle(tris2[i],tris2[(i+1)%3],tris1[0],tris1[1],tris1[2],inter);
}
return intersection;
}
template <typename PFP>
bool intersectionSphereEdge(typename PFP::MAP& map, typename PFP::VEC3& center, typename PFP::REAL radius, Dart d, const typename PFP::TVEC3& position, typename PFP::REAL& alpha)
{
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
const typename PFP::VEC3& p1 = position[d];
const typename PFP::VEC3& p2 = position[map.phi1(d)];
if(Geom::isPointInSphere(p1, center, radius) && !Geom::isPointInSphere(p2, center, radius))
{
VEC3 p = p1 - center;
VEC3 qminusp = p2 - center - p;
REAL s = p * qminusp;
REAL n2 = qminusp.norm2();
alpha = (- s + sqrt(s*s + n2 * (radius*radius - p.norm2()))) / n2;
return true ;
}
return false ;
}
} // namespace Geometry
} // namespace Algo
}
} // namespace CGoGN
}
......@@ -62,6 +62,15 @@ void coarsenFace(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
template <typename PFP>
void coarsenVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
/***********************************************************************************
* Raffinement
***********************************************************************************/
/*
* Un brin de la face oppose aux faces a spliter
*/
template <typename PFP>
void splitVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
/*******************************************************
*
*/
......
......@@ -173,12 +173,11 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi
assert(map.getDartLevel(d) <= map.getCurrentLevel() || !"Access to a dart introduced after current level") ;
assert(!map.volumeIsSubdivided(d) || !"Trying to subdivide an already subdivided volume") ;
unsigned int vLevel = map.volumeLevel(d) ;
Dart old = map.volumeOldestDart(d) ;
unsigned int cur = map.getCurrentLevel() ;
map.setCurrentLevel(vLevel) ; // go to the level of the face to subdivide its edges
unsigned int vLevel = map.volumeLevel(d);
Dart old = map.volumeOldestDart(d);
unsigned int cur = map.getCurrentLevel();
map.setCurrentLevel(vLevel);
/*
* au niveau du volume courant i
......@@ -740,10 +739,81 @@ void coarsenVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position
}
/***********************************************************************************
* Raffinement
***********************************************************************************/
template <typename PFP>
void splitVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position)
{
assert(map.getDartLevel(d) <= map.getCurrentLevel() || !"Access to a dart introduced after current level") ;
assert(!map.volumeIsSubdivided(d) || !"Trying to subdivide an already subdivided volume") ;
unsigned int cur = map.getCurrentLevel() ;
unsigned int vLevel = map.volumeLevel(d) ;
map.setCurrentLevel(vLevel) ;
// first cut the edges (if they are not already)
Dart t = d;
do
{
if(!map.edgeIsSubdivided(map.phi1(map.phi2(t))))
Algo::IHM::subdivideEdge<PFP>(map, map.phi1(map.phi2(t)), position) ;
t = map.phi1(t);
}
while(t != d);
unsigned int fLevel = map.faceLevel(map.phi1(d));
map.setCurrentLevel(fLevel+1) ; // go to the level of the face to subdivide its edges
Dart neighboordVolume = map.phi1(map.phi1(map.phi2(d)));
//map.setCurrentLevel(cur) ; // go to the next level to perform volume subdivision
//Split the faces and open the midlle
do
{
Dart t2 = map.phi2(t);
unsigned int fLevel = map.faceLevel(t2) ;
map.setCurrentLevel(fLevel+1) ; // go to the level of the face to subdivide its edges
Dart face2 = map.phi1(map.phi1(t2));
map.splitFace(map.phi_1(t2), face2);
map.unsewFaces(map.phi1(map.phi1(t2)));
//id de face pour les 2 nouveaux brins
unsigned int idface = map.getFaceId(t2);
map.setFaceId(map.phi1(map.phi1(t2)), idface, DART);
map.setFaceId(map.phi_1(face2), idface, DART);
t = map.phi1(t);
}
while(t != d);
//close the middle to create volumes & sew them
map.setCurrentLevel(vLevel + 1) ; // go to the next level to perform volume subdivision
map.closeHole(map.phi1(map.phi1(map.phi2(d))));
map.closeHole(map.phi_1(neighboordVolume));
map.sewVolumes(map.phi2(map.phi1(map.phi1(map.phi2(d)))), map.phi2(map.phi_1(neighboordVolume)));
unsigned int idface = map.getNewFaceId();
map.setFaceId(map.phi2(map.phi_1(neighboordVolume)), idface, FACE);
do
{
Dart t211 = map.phi1(map.phi1(map.phi2(t)));
unsigned int idedge = map.getNewEdgeId();
map.setEdgeId(t211, idedge, EDGE);
t = map.phi1(t);
}
while(t != d);
map.setCurrentLevel(cur) ;
}
/*************************************************************************************
*
*/
template <typename PFP>
void subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position, SubdivideType sType)
{
......
#ifndef __IMPORTSVG_H__
#define __IMPORTSVG_H__
namespace CGoGN
{
namespace Algo
{
namespace Import
{
/**
* check if an xml node has a given name
* @param node the xml node
* @param name the name
* @ return true if node has the good name
*/
bool checkXmlNode(xmlNodePtr node, const std::string& name);
template <typename PFP>
bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position, CellMarker& polygons);
/**
*
*/
template <typename PFP>
bool readSVG(const std::string& filename, std::vector<std::vector<typename PFP::VEC3 > > &allPoly);
template <typename PFP>
bool importBB(const std::string& filename, std::vector<Geom::BoundingBox<typename PFP::VEC3> > &bb);
template <typename PFP>
bool importSVG(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames);
}
}
}
#include "Algo/Import/importSvg.hpp"
#endif
This diff is collapsed.
......@@ -71,6 +71,9 @@ public :
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 move(const VEC3& newCurrent)
......@@ -86,6 +89,8 @@ public :
display();
}
else
m_position = newCurrent;
}
};
......
......@@ -45,12 +45,6 @@ typename PFP::VEC3 ParticleCell2D<PFP>::intersectLineEdge(const VEC3& pA, const
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;
}
......@@ -74,6 +68,7 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& current)
if(Algo::Geometry::isPointOnVertex<PFP>(m,d,m_positions,current))
{
state = VERTEX;
m_position = current;
return;
}
else
......@@ -101,6 +96,7 @@ void ParticleCell2D<PFP>::vertexState(const VEC3& current)
}
else
{
m_position = current;
state = VERTEX;
return;
}
......@@ -176,6 +172,85 @@ void ParticleCell2D<PFP>::edgeState(const VEC3& current, Geom::Orientation2D sid
vertexState(current);
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;