Commit f33a7c45 authored by Sylvain Thery's avatar Sylvain Thery

cleaning svg rendering & update usage

parent a2b1046d
......@@ -242,12 +242,13 @@ void MyQT::cb_keyPress(int code)
{
if (code == 's')
{
std::string filename = selectFileSave("Export SVG file ");
CGoGNout << "Exporting "<<filename<<CGoGNendl;
Algo::Render::SVG::SVGOut svg(filename,modelViewMatrix(),projectionMatrix());
// svg.renderLinesToSVG<PFP>(myMap,position);
svg.setColor(Geom::Vec3f(1.,0.,0.));
svg.renderFacesToSVG<PFP>(myMap,position,0.8f);
std::string filename = selectFileSave("Export SVG file ",".","(*.svg)");
Utils::SVG::SVGOut svg(filename,modelViewMatrix(),projectionMatrix());
svg.setWidth(1.0f);
svg.setColor(Geom::Vec3f(0.0f,0.0f,0.5f));
Algo::Render::SVG::renderEdges<PFP>(svg,myMap,position);
svg.setWidth(5.0f);
Algo::Render::SVG::renderVertices<PFP>(svg,myMap,position);
//svg destruction close the file
}
if (code == 't')
......
......@@ -38,7 +38,8 @@ int main(int argc, char **argv)
sqt.setDock(& sqt.dock);
sqt.setCallBack( sqt.dock.listOper, SIGNAL(currentRowChanged(int)), SLOT(operation(int)) );
sqt.setCallBack( sqt.dock.svg, SIGNAL(clicked()), SLOT(svg()) );
sqt.setCallBack( sqt.dock.widthSlider, SIGNAL(valueChanged(int)), SLOT(width(int)) );
int n=3;
if (argc==2)
n = atoi(argv[1]);
......@@ -46,6 +47,8 @@ int main(int argc, char **argv)
// example code itself
sqt.createMap(n);
sqt.width(5);
// set help message in menu
sqt.setHelpMsg("First Tuto: \nCreate two faces\nsew them\nand affect positions");
// final show for redraw
......@@ -283,11 +286,30 @@ void MyQT::cb_keyPress(int keycode)
}
break;
case 's':
m_render_topo->svgout<PFP>(myMap, "/tmp/toto.svg", modelViewMatrix(),projectionMatrix(),nb);
case 'b':
for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d))
{
if (!myMap.isBoundaryMarked(d))
{
colorDarts[d] = Geom::Vec3f(0.0f,0.0f,0.0f);
m_render_topo->setDartColor(d,0.0f,0.0f,0.0f);
}
}
break;
}
updateGL();
}
void MyQT::svg()
{
std::string filename = selectFileSave("snapshot file", ".", "(*.svg)");
m_render_topo->svgout2D(filename, modelViewMatrix(),projectionMatrix());
}
void MyQT::width(int w)
{
m_render_topo->setDartWidth(w);
m_render_topo->setRelationWidth(w);
updateGL();
}
......@@ -105,6 +105,8 @@ public:
public slots:
void operation(int x);
void svg();
void width(int w);
};
......
......@@ -96,6 +96,29 @@
</item>
</widget>
</item>
<item>
<widget class="QSlider" name="widthSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="svg">
<property name="text">
<string>SnapshotSVG</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
......
......@@ -36,7 +36,8 @@
#include "Geometry/vector_gen.h"
#include "Utils/vbo.h"
#include "Algo/Render/SVG/mapSVGRender.h"
#include "Utils/svg.h"
// forward
namespace CGoGN { namespace Utils { class ShaderSimpleColor; } }
......@@ -76,10 +77,17 @@ protected:
*/
GLuint m_nbDarts;
/**
* number of relations 1 to draw
*/
GLuint m_nbRel1;
/**
* number of relations 2 to draw
*/
GLuint m_nbRel2;
/**
* width of lines use to draw darts
*/
......@@ -220,8 +228,7 @@ public:
void updateDataGMap(typename PFP::MAP& map, const typename PFP::TVEC3& positions, float ke, float kf, const FunctorSelect& good = allDarts);
template<typename PFP>
void svgout(typename PFP::MAP& map, const std::string& filename, const glm::mat4& model, const glm::mat4& proj, const FunctorSelect& good = allDarts);
void svgout2D(const std::string& filename, const glm::mat4& model, const glm::mat4& proj);
};
// just for compatibility with old code
......
......@@ -139,9 +139,9 @@ void TopoRender::updateDataMap(typename PFP::MAP& mapx, const typename PFP::TVEC
m_attIndex[d] = indexDC;
indexDC+=2;
*positionDartBuf++ = P;
*colorDartBuf++ = m_dartsColor;
*positionDartBuf++ = Q;
*colorDartBuf++ = m_dartsColor;
*colorDartBuf++ = m_dartsColor;
VEC3 f = P*0.5f + Q*0.5f;
fv2[d] = f;
f = P*0.1f + Q*0.9f;
......@@ -172,7 +172,6 @@ void TopoRender::updateDataMap(typename PFP::MAP& mapx, const typename PFP::TVEC
VEC3* positionF2 = reinterpret_cast<VEC3*>(PositionBuffer2);
m_nbRel2 =0;
for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
{
Dart d = *id;
......@@ -191,6 +190,7 @@ void TopoRender::updateDataMap(typename PFP::MAP& mapx, const typename PFP::TVEC
*positionF1++ = fv1[d];
*positionF1++ = fv11[e];
}
m_nbRel1 = vecDarts.size()/2;
m_vbo1->bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
......@@ -225,6 +225,8 @@ void TopoRender::updateDataGMap(typename PFP::MAP& mapx, const typename PFP::TVE
}
m_nbDarts = vecDarts.size();
// debut phi1
AutoAttributeHandler<VEC3> fv1(map, DART);
// fin phi1
......@@ -333,15 +335,11 @@ void TopoRender::updateDataGMap(typename PFP::MAP& mapx, const typename PFP::TVE
VEC3* positionF1 = reinterpret_cast<VEC3*>(PositionBuffer1);
VEC3* positionF2 = reinterpret_cast<VEC3*>(PositionBuffer2);
m_nbRel2 =0;
m_nbRel2 = 0;
for(std::vector<Dart>::iterator id = vecDarts.begin(); id!= vecDarts.end(); id++)
{
Dart d = *id;
Dart e = map.beta2(d);
// if (good(e) && (e.index > d.index))
if (good(e) && (d < e ))
{
*positionF2++ = fv2[d];
......@@ -353,6 +351,7 @@ void TopoRender::updateDataGMap(typename PFP::MAP& mapx, const typename PFP::TVE
*positionF1++ = fv1[d];
*positionF1++ = fv1[e];
}
m_nbRel1 = vecDarts.size()/2;
m_vbo1->bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
......@@ -422,80 +421,6 @@ Dart TopoRender::picking(typename PFP::MAP& map,int x, int y, const FunctorSelec
}
template<typename PFP>
void TopoRender::svgout(typename PFP::MAP& map, const std::string& filename, const glm::mat4& model, const glm::mat4& proj, const FunctorSelect& good)
{
Algo::Render::SVG::SVGOut svg(filename,model,proj);
svg.setWidth(3.0f);
// PHI2
m_vbo2->bind();
Geom::Vec3f* ptr = reinterpret_cast<typename PFP::VEC3*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));
svg.beginLines();
for (unsigned int i=0; i<m_nbRel2; ++i)
svg.addLine(ptr[2*i], ptr[2*i+1],Geom::Vec3f(1.0f,0.0f,0.0f));
svg.endLines();
m_vbo2->bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
//PHI1
m_vbo1->bind();
ptr = reinterpret_cast<typename PFP::VEC3*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));
svg.beginLines();
for (unsigned int i=0; i<m_nbDarts; ++i)
svg.addLine(ptr[2*i], ptr[2*i+1],Geom::Vec3f(0.0f,1.0f,1.0f));
svg.endLines();
m_vbo1->bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
m_vbo0->bind();
ptr= reinterpret_cast<typename PFP::VEC3*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));
m_vbo3->bind();
Geom::Vec3f* colorsPtr = reinterpret_cast<typename PFP::VEC3*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY));
svg.setWidth(5.0f);
svg.beginLines();
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if (good(d))
{
unsigned int id = m_attIndex[d];
// svg.addLine(ptr[id], ptr[id+1], colorsPtr[id]);
svg.addLine(ptr[id], ptr[id+1], Geom::Vec3f(0.0f,0.0f,0.0f));
}
}
svg.endLines();
svg.beginPoints();
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if (good(d))
{
unsigned int id = m_attIndex[d];
// svg.addPoint(ptr[id], colorsPtr[id]);
svg.addPoint(ptr[id], Geom::Vec3f(0.0f,0.0f,0.0f));
}
}
svg.endPoints();
m_vbo0->bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
m_vbo3->bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
// relations:
}
}//end namespace GL2
......
......@@ -22,211 +22,60 @@
* *
*******************************************************************************/
#ifndef _MAP_SVG_RENDER
#define _MAP_SVG_RENDER
#ifndef _MAP_SVG_RENDER_
#define _MAP_SVG_RENDER_
#include <vector>
#include <fstream>
#include <sstream>
#include "Geometry/vector_gen.h"
#include "Topology/generic/functor.h"
#include "Topology/generic/dartmarker.h"
#include "Utils/svg.h"
#include "Topology/generic/traversorCell.h"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_precision.hpp"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_projection.hpp"
#include "glm/gtc/matrix_transform.hpp"
/**
* A set of functions that allow the creation of rendering
* object using Vertex-Buffer-Object.
* Function are made for dual-2-map and can be used on
* any subset of a dual-N-map which is a 2-map
*/
namespace CGoGN
{
namespace Algo
{
namespace Render
{
namespace SVG
{
class SvgObj
{
protected:
std::vector<Geom::Vec3f> m_vertices;
std::vector<Geom::Vec3f> m_colors;
std::vector<Geom::Vec3f> m_vertices3D;
Geom::Vec3f m_color;
float m_width;
public:
void addVertex(const Geom::Vec3f& v);
void addVertex3D(const Geom::Vec3f& v);
void addVertex(const Geom::Vec3f& v, const Geom::Vec3f& C);
void addVertex3D(const Geom::Vec3f& v, const Geom::Vec3f& C);
// void addColor(const Geom::Vec3f& c);
void setColor(const Geom::Vec3f& c);
void setWidth(float w) { m_width=w;}
void close();
virtual void save(std::ofstream& out)=0;
unsigned int nbv() const { return m_vertices3D.size();}
const Geom::Vec3f& P(unsigned int i) const { return m_vertices3D[i];}
Geom::Vec3f normal();
};
class SvgPoints: public SvgObj
{
public:
void save(std::ofstream& out);
};
class SvgPolyline: public SvgObj
{
public:
void save(std::ofstream& out);
};
class SvgLines: public SvgObj
{
public:
void save(std::ofstream& out);
};
class SvgPolygon: public SvgObj
{
protected:
Geom::Vec3f m_colorFill;
public:
void setColorFill(const Geom::Vec3f& c);
void save(std::ofstream& out);
};
class SVGOut
{
protected:
std::ofstream* m_out;
const glm::mat4& m_model;
const glm::mat4& m_proj;
glm::i32vec4 m_viewport;
Geom::Vec3f global_color;
float global_width;
std::vector<SvgObj*> m_objs;
SvgObj* m_current;
public:
/**
* Object that allow the rendering/exporting in svg file
* @param filename file name ended by .svg
* @param model the modelview matrix
* @param proj the projection matrix
/**
* render vertices in a SVGOut
* @warning no depth ordering
*/
SVGOut(const std::string& filename, const glm::mat4& model, const glm::mat4& proj);
template <typename PFP>
void renderVertices(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good=allDarts, unsigned int thread=0);
/**
* destructor
* flush and close the file
/**
* render colored vertices in a SVGOut
* @warning no depth ordering
*/
~SVGOut();
void setColor(const Geom::Vec3f& col);
void setWidth(float w);
void closeFile();
template <typename PFP>
void renderLinesToSVG(typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good = allDarts, unsigned int thread=0);
template <typename PFP>
void renderFacesToSVG(typename PFP::MAP& map, const typename PFP::TVEC3& position, float shrink, bool cull = false, const FunctorSelect& good = allDarts, unsigned int thread=0);
template <typename PFP>
void renderPointsToSVG(typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good = allDarts, unsigned int thread=0);
template <typename PFP>
void renderVertices(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::TVEC3& color, const FunctorSelect& good=allDarts, unsigned int thread=0);
void orderPrimitives(std::list<SvgObj*>& primitives);
void beginPoints();
void endPoints();
void addPoint(const Geom::Vec3f& P);
void addPoint(const Geom::Vec3f& P, const Geom::Vec3f& C);
void beginLines();
void endLines();
void addLine(const Geom::Vec3f& P, const Geom::Vec3f& P2);
void addLine(const Geom::Vec3f& P, const Geom::Vec3f& P2, const Geom::Vec3f& C);
};
struct compSvgObj
{
int points_plane (SvgPolygon* pol_points, SvgPolygon* pol_plane, float& averageZ);
bool operator() (SvgObj* a, SvgObj*b);
};
/**
* render edges in a SVGOut
* @warning no depth ordering
*/
template <typename PFP>
void renderEdges(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good=allDarts, unsigned int thread=0);
struct compNormObj
{
// int points_plane (SvgPolygon* pol_points, SvgPolygon* pol_plane);
bool operator() (SvgObj* a, SvgObj*b);
};
//
//class BSP_SVG
//{
//protected:
// std::list<BSP_SVG*> m_front;
// std::list<BSP_SVG*> m_back;
// std::list<BSP_SVG*> m_intersect;
// SvgObj* m_obj;
//
//public:
// void insert(SvgObj*)
//};
/**
* render colored edges in a SVGOut
* @warning no depth ordering
*/
template <typename PFP>
void renderEdges(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::TVEC3& color, const FunctorSelect& good=allDarts, unsigned int thread=0);
} // namespace SVG
} // namespace Render
} // namespace Algo
} // namespace CGoGN
}
}
}
}
#include "Algo/Render/SVG/mapSVGRender.hpp"
......
......@@ -23,123 +23,60 @@
*******************************************************************************/
#include "GL/glew.h"
#include "Algo/Geometry/centroid.h"
namespace CGoGN
{
namespace Algo
{
namespace Render
{
namespace SVG
{
template <typename PFP>
void SVGOut::renderPointsToSVG(typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good, unsigned int thread)
void renderVertices(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good, unsigned int thread)
{
SvgPoints* points = new SvgPoints();
points->setColor(global_color);
points->setWidth(global_width);
TraversorV<typename PFP::MAP> trav(map,good,thread);
for(Dart d = trav.begin(); d != trav.end(); d=trav.next())
{
const Geom::Vec3f& P = position[d];
glm::vec3 Q = glm::project(glm::vec3(P[0],P[1],P[2]),m_model,m_proj,m_viewport);
glm::vec3 R = glm::project(glm::vec3(P[0],P[1],P[2]),m_model,glm::mat4(1.0),m_viewport);
points->addVertex(Geom::Vec3f(Q[0],float(m_viewport[3])-Q[1],Q[2]));
}
m_objs.push_back(points);
TraversorCell<typename PFP::MAP> trac(map,VERTEX,good);
svg.beginPoints();
for (Dart d=trac.begin(); d!=trac.end(); d=trac.next())
svg.addPoint(position[d]);
svg.endPoints();
}
template <typename PFP>
void SVGOut::renderLinesToSVG(typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good, unsigned int thread)
void renderVertices(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::TVEC3& color, const FunctorSelect& good, unsigned int thread)
{
TraversorE<typename PFP::MAP> trav(map,good,thread);
for(Dart d = trav.begin(); d != trav.end(); d=trav.next())
{
const Geom::Vec3f& P = position[d];
glm::vec3 Q = glm::project(glm::vec3(P[0],P[1],P[2]),m_model,m_proj,m_viewport);
glm::vec3 R = glm::project(glm::vec3(P[0],P[1],P[2]),m_model,glm::mat4(1.0),m_viewport);
const Geom::Vec3f& P2 = position[map.phi1(d)];
glm::vec3 Q2 = glm::project(glm::vec3(P2[0],P2[1],P2[2]),m_model,m_proj,m_viewport);
glm::vec3 R2 = glm::project(glm::vec3(P2[0],P2[1],P2[2]),m_model,glm::mat4(1.0),m_viewport);
SvgPolyline* pol = new SvgPolyline();
pol->addVertex(Geom::Vec3f(Q[0],float(m_viewport[3])-Q[1],Q[2]));
pol->addVertex(Geom::Vec3f(Q2[0],float(m_viewport[3])-Q2[1],Q2[2]));
pol->addVertex3D(Geom::Vec3f(R[0],float(m_viewport[3])-R[1],R[2]));
pol->addVertex3D(Geom::Vec3f(R2[0],float(m_viewport[3])-R2[1],R2[2]));
pol->setColor(global_color);
pol->setWidth(global_width);
m_objs.push_back(pol);
}
TraversorCell<typename PFP::MAP> trac(map,VERTEX,good);
svg.beginPoints();
for (Dart d=trac.begin(); d!=trac.end(); d=trac.next())
svg.addPoint(position[d],color[d]);
svg.endPoints();
}
template <typename PFP>
void SVGOut::renderFacesToSVG(typename PFP::MAP& map, const typename PFP::TVEC3& position, float shrink, bool cull, const FunctorSelect& good, unsigned int thread)
void renderEdges(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const FunctorSelect& good, unsigned int thread)
{
TraversorF<typename PFP::MAP> trav(map,good,thread);
for(Dart d = trav.begin(); d != trav.end(); d=trav.next())
{
bool cullFace=false;
if (cull)
{
const Geom::Vec3f& P = position[d];
TraversorCell<typename PFP::MAP> trac(map,EDGE,good);
svg.beginLines();
for (Dart d=trac.begin(); d!=trac.end(); d=trac.next())
svg.addLine(position[d],position[map.phi1(d)]);
svg.endLines();
}
glm::vec3 Q = glm::project(glm::vec3(P[0],P[1],P[2]),m_model,m_proj,m_viewport);
const Geom::Vec3f& P2 = position[map.phi1(d)];
glm::vec3 R = glm::project(glm::vec3(P2[0],P2[1],P2[2]),m_model,m_proj,m_viewport);
const Geom::Vec3f& P3 = position[map.phi1(map.phi1(d))];
glm::vec3 S = glm::project(glm::vec3(P3[0],P3[1],P3[2]),m_model,m_proj,m_viewport);
glm::vec3 N = glm::cross(S-R,Q-R);
if (N[2]<0.0f)
cullFace=true;
}
template <typename PFP>
void renderEdges(Utils::SVG::SVGOut& svg, typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::TVEC3& color, const FunctorSelect& good, unsigned int thread)
{
TraversorCell<typename PFP::MAP> trac(map,EDGE,good);
svg.beginLines();
for (Dart d=trac.begin(); d!=trac.end(); d=trac.next())
svg.addLine(position[d],position[map.phi1(d)],color[d]);
svg.endLines();
}
if (!cullFace)
{