Tulip  4.0.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
GlComplexPolygon.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 
21 #ifndef GLCOMPLEXPOLYGON_H
22 #define GLCOMPLEXPOLYGON_H
23 
24 #include <tulip/OpenGlConfigManager.h>
25 
26 #ifdef WIN32
27 #include <windows.h>
28 #endif
29 
30 #ifndef CALLBACK
31 #define CALLBACK
32 #endif
33 
34 #include <vector>
35 #include <map>
36 #include <set>
37 
38 #include <tulip/Color.h>
39 #include <tulip/Coord.h>
40 #include <tulip/tulipconf.h>
41 
42 #include <tulip/GlSimpleEntity.h>
43 
44 namespace tlp {
45 
46 typedef struct {
47  GLdouble x, y, z, r, g, b, a;
48 } VERTEX;
49 
50 void CALLBACK beginCallback(GLenum which, GLvoid *polygonData);
51 void CALLBACK errorCallback(GLenum errorCode);
52 void CALLBACK endCallback(GLvoid *polygonData);
53 void CALLBACK vertexCallback(GLvoid *vertex, GLvoid *polygonData);
54 void CALLBACK combineCallback(GLdouble coords[3], VERTEX *d[4], GLfloat w[4], VERTEX** dataOut, GLvoid *polygonData);
55 
56 /**
57  * @ingroup OpenGL
58  * @brief Class to create a complex polygon (concave polygon or polygon with hole)
59  * If you want to create a complex polygon you have 4 constructors :
60  * Constructors with vector of coords : to create a complex polygon without hole
61  * - In this case you have two constructor : with and without outline color
62  * - You can create a polygon like this :
63  * \code
64  * vector <Coord> coords;
65  * coords.push_back(Coord(0,0,0));
66  * coords.push_back(Coord(10,0,0));
67  * coords.push_back(Coord(10,10,0));
68  * coords.push_back(Coord(0,10,0));
69  * GlComplexPolygon *complexPolygon=new GlComplexPolygon(coords,Color(255,0,0,255));
70  * layer->addGlEntity(complexPolygon,"complexPolygon");
71  * \endcode
72  *
73  * Constructors with vector of vector of Coords : to create a complex polygon with hole
74  * - In this case you have two constructor : with and without outline color
75  * - The first vector of coords is the polygon and others vector are holes
76  * - You can create a polygon with hole like this :
77  * \code
78  * vector <vector <Coord> > coords;
79  * vector <Coord> polygon;
80  * vector <Coord> hole;
81  * polygon.push_back(Coord(0,0,0));
82  * polygon.push_back(Coord(10,0,0));
83  * polygon.push_back(Coord(10,10,0));
84  * polygon.push_back(Coord(0,10,0));
85  * hole.push_back(Coord(4,4,0));
86  * hole.push_back(Coord(6,4,0));
87  * hole.push_back(Coord(6,6,0));
88  * hole.push_back(Coord(4,6,0));
89  * coords.push_back(polygon);
90  * coords.push_back(hole);
91  * GlComplexPolygon *complexPolygon=new GlComplexPolygon(coords,Color(255,0,0,255));
92  * layer->addGlEntity(complexPolygon,"complexPolygon");
93  * \endcode
94  *
95  * In constructors you can specify the polygon border style : polygonEdgesType parameter (0 -> straight lines, 1 -> catmull rom curves, 2 -> bezier curves)
96  * You can also specify the texture name if you want to create a textured complex polygon
97  *
98  * In complex polygon you can add a smooth border : see activateQuadBorder(..) function
99  * And you can specify the texture zoom : see setTextureZoom(...) function
100  */
101 class TLP_GL_SCOPE GlComplexPolygon : public GlSimpleEntity {
102 
103  friend void CALLBACK beginCallback(GLenum which, GLvoid *polygonData);
104  friend void CALLBACK errorCallback(GLenum errorCode);
105  friend void CALLBACK endCallback(GLvoid *polygonData);
106  friend void CALLBACK vertexCallback(GLvoid *vertex, GLvoid *polygonData);
107  friend void CALLBACK combineCallback(GLdouble coords[3], VERTEX *d[4], GLfloat w[4], VERTEX** dataOut, GLvoid *polygonData);
108 
109 public:
110  /**
111  * @brief Default constructor
112  * @warning don't use this constructor if you want to create a complex polygon, see others constructors
113  */
115  /**
116  * @brief Constructor with a vector of coords, a fill color, a polygon edges type(0 -> straight lines, 1 -> catmull rom curves, 2 -> bezier curves) and a textureName if you want
117  */
118  GlComplexPolygon(const std::vector<Coord> &coords,Color fcolor,int polygonEdgesType=0,const std::string &textureName = "");
119  /**
120  * @brief Constructor with a vector of coords, a fill color, an outline color, a polygon edges type(0 -> straight lines, 1 -> catmull rom curves, 2 -> bezier curves) and a textureName if you want
121  */
122  GlComplexPolygon(const std::vector<Coord> &coords,Color fcolor,Color ocolor,int polygonEdgesType=0,const std::string &textureName = "");
123  /**
124  * @brief Constructor with a vector of vector of coords (the first vector of coord is the polygon and others vectors are holes in polygon), a fill color, a polygon edges type(0 -> straight lines, 1 -> catmull rom curves, 2 -> bezier curves) and a textureName if you want
125  */
126  GlComplexPolygon(const std::vector<std::vector<Coord> >&coords,Color fcolor,int polygonEdgesType=0,const std::string &textureName = "");
127  /**
128  * @brief Constructor with a vector of vector of coords (the first vector of coord is the polygon and others vectors are holes in polygon), a fill color, an outline color a polygon edges type(0 -> straight lines, 1 -> catmull rom curves, 2 -> bezier curves) and a textureName if you want
129  */
130  GlComplexPolygon(const std::vector<std::vector<Coord> >&coords,Color fcolor,Color ocolor,int polygonEdgesType=0,const std::string &textureName = "");
131 
132  virtual ~GlComplexPolygon() {}
133 
134  /**
135  * @brief Draw the complex polygon
136  */
137  virtual void draw(float lod,Camera *camera);
138 
139  /**
140  * @brief Set if the polygon is outlined or not
141  */
142  void setOutlineMode(const bool);
143 
144  /**
145  * @brief Set size of outline
146  */
147  void setOutlineSize(double size);
148 
149  /**
150  * @brief Get fill color of GlComplexPolygon
151  */
152  Color getFillColor() const {
153  return fillColor;
154  }
155 
156  /**
157  * @brief Set fill color of GlComplexPolygon
158  */
159  void setFillColor(const Color &color) {
160  fillColor=color;
161  }
162 
163  /**
164  * @brief Get outline color of GlComplexPolygon
165  */
166  Color getOutlineColor() const {
167  return outlineColor;
168  }
169 
170  /**
171  * @brief Set outline color of GlComplexPolygon
172  */
173  void setOutlineColor(const Color &color) {
174  outlineColor=color;
175  }
176 
177  /**
178  * @brief Get the texture zoom factor
179  */
180  float getTextureZoom() {
181  return textureZoom;
182  }
183 
184  /**
185  * @brief Set the texture zoom factor
186  *
187  * By default if you have a polygon with a size bigger than (1,1,0) the texture will be repeated
188  * If you want to don't have this texture repeat you have to modify texture zoom
189  * For example if you have a polygon with coords ((0,0,0),(5,0,0),(5,5,0),(0,5,0)) you can set texture zoom to 5. to don't have texture repeat
190  */
191  void setTextureZoom(float zoom) {
192  textureZoom=zoom;
193  runTesselation();
194  }
195 
196  /**
197  * @brief Get the textureName
198  */
199  std::string getTextureName();
200 
201  /**
202  * @brief Set the textureName
203  */
204  void setTextureName(const std::string &name);
205 
206  /**
207  * @brief Draw a thick (textured) border around the polygon.
208  *
209  * The graphic card must support geometry shader to make this feature to work.
210  * The position parameter determines the way the border is drawn (depending on the polygon points ordering):
211  * - 0 : the border is drawn outside (or inside) the polygon
212  * - 1 : the border is centered on the polygon outline
213  * - 2 : the border is drawn inside (or outside) the polygon
214  *
215  * The texCoordFactor parameter determines the way the texture is applied : if < 1, the texture will be expanded and > 1, the texture will be compressed
216  * The polygonId parameter determines on which contour of the polygon, the border will be applied
217  */
218  void activateQuadBorder(const float borderWidth, const Color &color, const std::string &texture = "", const int position = 1,
219  const float texCoordFactor = 1.f, const int polygonId = 0);
220 
221  /**
222  * @brief Desactivate the textured quad border
223  */
224  void desactivateQuadBorder(const int polygonId = 0);
225 
226  QStringList propertiesNames() const;
227 
228  QVariantList propertiesQVariant() const;
229 
230  void setProperty(const QString &name, const QVariant &value);
231 
232  /**
233  * @brief Translate entity
234  */
235  virtual void translate(const Coord& mouvement);
236 
237  /**
238  * @brief Function to export data and type outString (in XML format)
239  */
240  virtual void getXML(std::string &outString);
241 
242  /**
243  * @brief Function to export data in outString (in XML format)
244  */
245  virtual void getXMLOnlyData(std::string &outString);
246 
247  /**
248  * @brief Function to set data with inString (in XML format)
249  */
250  virtual void setWithXML(const std::string &inString, unsigned int &currentPosition);
251 
252  const std::vector<std::vector<Coord> > &getPolygonSides() const {
253  return points;
254  }
255 
256 
257 protected:
258 
259  /**
260  * @brief Add a new point in polygon
261  */
262  virtual void addPoint(const Coord& point);
263  /**
264  * @brief Begin a new hole in the polygon
265  */
266  virtual void beginNewHole();
267 
268  void runTesselation();
269  void createPolygon(const std::vector<Coord> &coords,int polygonEdgesType);
270  void startPrimitive(GLenum primitive);
271  void endPrimitive();
272  void addVertex(const Coord &vertexCoord, const Vec2f &vertexTexCoord);
273  VERTEX *allocateNewVertex();
274 
275  std::vector<std::vector<Coord> > points;
276  std::vector<std::vector<GLfloat> > pointsIdx;
277  std::set<GLenum> primitivesSet;
278  std::map<GLenum, std::vector<Coord> > verticesMap;
279  std::map<GLenum, std::vector<Vec2f> > texCoordsMap;
280  std::map<GLenum, std::vector<int> >startIndicesMap;
281  std::map<GLenum, std::vector<int> >verticesCountMap;
282  std::vector<VERTEX *> allocatedVertices;
283  GLenum currentPrimitive;
284  int nbPrimitiveVertices;
285  int currentVector;
286  bool outlined;
287  Color fillColor;
288  Color outlineColor;
289  double outlineSize;
290  std::string textureName;
291  float textureZoom;
292  std::vector<bool> quadBorderActivated;
293  std::vector<float> quadBorderWidth;
294  std::vector<Color> quadBorderColor;
295  std::vector<std::string> quadBorderTexture;
296  std::vector<int> quadBorderPosition;
297  std::vector<float> quadBorderTexFactor;
298 };
299 
300 }
301 #endif