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 @@
#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);
......
......@@ -16,7 +16,7 @@ namespace Import
* @param name the 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>
bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position, CellMarker& polygons);
......
#include <iostream>
#include "Geometry/bounding_box.h"
#include "Geometry/plane_3d.h"
#include "Algo/BooleanOperator/mergeVertices.h"
#include <limits>
namespace CGoGN
......@@ -11,7 +13,7 @@ namespace Algo
namespace Import
{
inline bool chechXmlNode(xmlNodePtr node, const std::string& name)
inline bool checkXmlNode(xmlNodePtr node, const std::string& name)
{
return (strcmp((char*)(node->name),(char*)(name.c_str())) == 0);
}
......@@ -31,6 +33,158 @@ bool posSort(const std::pair<VEC, Dart>& a1, const std::pair<VEC, Dart>& a2)
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
std::getline( is, coord, ' ' ); //ignore second control point
}
break;
case 5 : //bezier 2
{
std::getline( is, coord, ' ' ); //ignore control point
}
break;
case 6 : //elliptic
std::getline( is, coord, ' ' ); //ignore rx
std::getline( is, coord, ' ' ); //ignore ry
std::getline( is, coord, ' ' ); //ignore x-rotation
std::getline( is, coord, ' ' ); //ignore large arc flag
std::getline( is, coord, ' ' ); //ignore sweep flag
break;
}
std::stringstream streamCoord(coord);
std::string xS,yS;
std::getline(streamCoord, xS, ',' );
std::getline(streamCoord, yS, ',' );
valueOf(xS,x);
valueOf(yS,y);
push_point = true;
}
//if there is a point to push
if(push_point)
{
VEC3 previous;
if(curPoly.size()>0)
previous = (curPoly)[(curPoly).size()-1];
if(relative)
{
x += previous[0];
y += previous[1];
}
// std::cout << "coord " << x << " " << y << std::endl;
if(curPoly.size()==0 || (curPoly.size()>0 && (x!=previous[0] || y!= previous[1])))
curPoly.push_back(VEC3(x,y,0));
}
}
}
template <typename PFP>
bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP::TVEC3& position, CellMarker& polygons, CellMarker& polygonsFaces)
{
......@@ -40,190 +194,49 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP
xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0);
xmlNodePtr map_node = xmlDocGetRootElement(doc);
if (!chechXmlNode(map_node,"svg"))
if (!checkXmlNode(map_node,"svg"))
{
CGoGNerr << "Wrong xml format: Root node != svg"<< CGoGNendl;
return false;
}
std::vector<POLYGON> allPoly;
std::vector<POLYGON> allBrokenLines;
std::vector<float> allBrokenLinesWidth;
bool closedPoly;
for (xmlNode* cur_node = map_node->children; cur_node; cur_node = cur_node->next)
{
// for each layer
if (chechXmlNode(cur_node, "g"))
if (checkXmlNode(cur_node, "g"))
{
CGoGNout << "----load layer----"<< CGoGNendl;
// CGoGNout << "----load layer----"<< CGoGNendl;
for (xmlNode* cur_path = cur_node->children; cur_path; cur_path = cur_path->next)
for (xmlNode* cur_path = cur_node->children ; cur_path; cur_path = cur_path->next)
{
if (chechXmlNode(cur_path, "path"))
if (checkXmlNode(cur_path, "path"))
{
bool closedPoly=false;
POLYGON curPoly;
CGoGNout << "--load a path--"<< CGoGNendl;
// CGoGNout << "--load a path--"<< CGoGNendl;
xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "d");
// CGoGNout << "path "<< prop << CGoGNendl;
std::string allcoords((reinterpret_cast<const char*>(prop)));
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
std::getline( is, coord, ' ' ); //ignore second control point
}
break;
case 5 : //bezier 2
{
std::getline( is, coord, ' ' ); //ignore control point
}
break;
case 6 : //elliptic
std::getline( is, coord, ' ' ); //ignore rx
std::getline( is, coord, ' ' ); //ignore ry
std::getline( is, coord, ' ' ); //ignore x-rotation
std::getline( is, coord, ' ' ); //ignore large arc flag
std::getline( is, coord, ' ' ); //ignore sweep flag
break;
}
std::stringstream streamCoord(coord);
std::string xS,yS;
std::getline(streamCoord, xS, ',' );
std::getline(streamCoord, yS, ',' );
valueOf(xS,x);
valueOf(yS,y);
push_point = true;
}
//if there is a point to push
if(push_point)
{
if(relative && curPoly.size()>0)
{
VEC3 previous = (curPoly)[(curPoly).size()-1];
x += previous[0];
y += previous[1];
}
std::cout << "coord " << x << " " << y << std::endl;
curPoly.push_back(VEC3(x,y,0));
}
}
getPolygonFromSVG(allcoords,curPoly,closedPoly);
//check orientation : set in CCW
if(curPoly.size()>2)
{
VEC3 v1(curPoly[1]-curPoly[0]);
VEC3 v2(curPoly[2]-curPoly[1]);
if((v1^v2)[2]<0)
if((v1^v2)[2]>0)
{
std::cout << "reverse !" << std::endl;
std::reverse(curPoly.begin(), curPoly.end());
}
}
if(closedPoly)
allPoly.push_back(curPoly);
else {
else
{
allBrokenLines.push_back(curPoly);
xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "style");
std::string allstyle((reinterpret_cast<const char*>(prop)));
......@@ -237,13 +250,56 @@ bool importSVG(typename PFP::MAP& map, const std::string& filename, typename PFP
std::getline( isSize, style, ':' );
float sizeOfLine;
isSize >> sizeOfLine;
std::cout << "sizeOfLine : " << sizeOfLine << std::endl;
allBrokenLinesWidth.push_back(sizeOfLine);
}
}
}
}
}
}
else
{
xmlNode* cur_path = cur_node;
if (checkXmlNode(cur_path, "path"))
{
POLYGON curPoly;
// CGoGNout << "--load a path--"<< CGoGNendl;
xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "d");
std::string allcoords((reinterpret_cast<const char*>(prop)));
getPolygonFromSVG(allcoords,curPoly,closedPoly);
//check orientation : set in CCW
if(curPoly.size()>2)
{
VEC3 v1(curPoly[1]-curPoly[0]);
VEC3 v2(curPoly[2]-curPoly[1]);
if((v1^v2)[2]>0)
{
std::reverse(curPoly.begin(), curPoly.end());
}
}
if(closedPoly)
allPoly.push_back(curPoly);
else
{
allBrokenLines.push_back(curPoly);
xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "style");
std::string allstyle((reinterpret_cast<const char*>(prop)));
std::stringstream is(allstyle);
std::string style;
while ( std::getline( is, style, ';' ) )
{
if(style.find("stroke-width:")!=std::string::npos)
{
std::stringstream isSize(style);
std::getline( isSize, style, ':' );
float sizeOfLine;
isSize >> sizeOfLine;
std::cout << "sizeOfLine : " << sizeOfLine << std::endl;