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
#include <iostream>
#include "Geometry/bounding_box.h"
#include "Geometry/plane_3d.h"
#include "Algo/BooleanOperator/mergeVertices.h"
#include <limits>
namespace CGoGN
{
namespace Algo
{
namespace Import
{
inline bool checkXmlNode(xmlNodePtr node, const std::string& name)
{
return (strcmp((char*)(node->name),(char*)(name.c_str())) == 0);
}
template<typename T>
inline bool valueOf(const std::string &s, T &obj)
{
std::istringstream is(s);
return is >> obj;
}
template <typename VEC>
bool posSort(const std::pair<VEC, Dart>& a1, const std::pair<VEC, Dart>& a2)
{
VEC v1 = a1.first;
VEC v2 = a2.first;
return v1[0] < v2[0] || (v1[0] == v2[0] && v1[1] < v2[1]);
}
template <typename VEC3>
void getPolygonFromSVG(std::string allcoords, std::vector<VEC3>& curPoly, bool& closedPoly)
{
closedPoly=false;
std::stringstream is(allcoords);
bool relative=false;
bool push_point;
std::string coord;
int mode = -1;
while ( std::getline( is, coord, ' ' ) )
{
float x,y;
push_point=false;
if(coord[0]=='m' || coord[0]=='l' || coord[0]=='t') //start point, line or quadratic bezier curve
{
mode = 0;
// std::cout << "relative coordinates" << std::endl;
relative=true;
}
else if(coord[0]=='M' || coord[0] == 'L' || coord[0]=='T') //same in absolute coordinates
{
// std::cout << "absolute coordinates" << std::endl;
mode = 1;
relative=false;
}
else if(coord[0]=='h' || coord[0] == 'H') //horizontal line
{
mode = 2;
relative=(coord[0]=='h');
}
else if(coord[0]=='v' || coord[0] == 'V') //vertical line
{
// std::cout << "vertical line" << std::endl;
mode = 3;
relative=(coord[0]=='v');
}
else if(coord[0]=='c' || coord[0] == 'C') //bezier curve
{
// std::cout << "bezier line" << std::endl;
mode = 4;
relative=(coord[0]=='c');
}
else if(coord[0]=='s' || coord[0] == 'S' || coord[0]=='q' || coord[0] == 'Q') //bezier curve 2
{
// std::cout << "bezier line 2" << std::endl;
mode = 5;
relative= ((coord[0]=='s') || (coord[0]=='q'));
}
else if(coord[0]=='a' || coord[0] == 'A') //elliptic arc
{
// std::cout << "elliptic arc" << std::endl;
mode =6;
relative= (coord[0]=='a');
}
else if(coord[0]=='z')
{
// std::cout << "the end" << std::endl;
closedPoly = true;
}
else //coordinates
{
switch(mode)
{
case 0 : //relative
break;
case 1 : //absolute
break;
case 2 : //horizontal
{
std::stringstream streamCoord(coord);
std::string xS;
std::getline(streamCoord, xS, ',' );
valueOf(xS,x);
VEC3 previous = (curPoly)[(curPoly).size()-1];
y = previous[1];
push_point=true;
}
break;
case 3 : //vertical
{
std::stringstream streamCoord(coord);
std::string yS;
std::getline(streamCoord, yS, ',' );
valueOf(yS,y);
typename PFP::VEC3 previous = (curPoly)[(curPoly).size()-1];
x = previous[0];
push_point=true;
}
break;
case 4 : //bezier
{
std::getline( is, coord, ' ' ); //ignore first control point