SUMO - Simulation of Urban MObility
GUIPolygon.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // The GUI-version of a polygon
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include "GUIPolygon.h"
41 #include <utils/gui/div/GLHelper.h>
43 
44 //#define GUIPolygon_DEBUG_DRAW_VERTICES
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
49 GUIPolygon::GUIPolygon(const std::string& id, const std::string& type,
50  const RGBColor& color, const PositionVector& shape, bool fill,
51  double layer, double angle, const std::string& imgFile):
52  SUMOPolygon(id, type, color, shape, fill, layer, angle, imgFile),
54  myDisplayList(0),
55  myLineWidth(1) // m
56 
57 {}
58 
59 
61 
62 
63 
66  GUISUMOAbstractView& parent) {
67  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
68  buildPopupHeader(ret, app, false);
69  FXString t(myType.c_str());
70  new FXMenuCommand(ret, "(" + t + ")", 0, 0, 0);
71  new FXMenuSeparator(ret);
75  buildShowParamsPopupEntry(ret, false);
76  buildPositionCopyEntry(ret, false);
77  return ret;
78 }
79 
80 
85  new GUIParameterTableWindow(app, *this, 3 + (int)getMap().size());
86  // add items
87  ret->mkItem("type", false, myType);
88  ret->mkItem("layer", false, toString(getLayer()));
89  ret->closeBuilding(this);
90  return ret;
91 }
92 
93 
96  Boundary b;
98  b.grow(2);
99  return b;
100 }
101 
102 
103 void APIENTRY beginCallback(GLenum which) {
104  glBegin(which);
105 }
106 
107 void APIENTRY errorCallback(GLenum errorCode) {
108  const GLubyte* estring;
109 
110  estring = gluErrorString(errorCode);
111  fprintf(stderr, "Tessellation Error: %s\n", estring);
112  exit(0);
113 }
114 
115 void APIENTRY endCallback(void) {
116  glEnd();
117 }
118 
119 void APIENTRY vertexCallback(GLvoid* vertex) {
120  glVertex3dv((GLdouble*) vertex);
121 }
122 
123 void APIENTRY combineCallback(GLdouble coords[3],
124  GLdouble* vertex_data[4],
125  GLfloat weight[4], GLdouble** dataOut) {
126  UNUSED_PARAMETER(weight);
127  UNUSED_PARAMETER(*vertex_data);
128  GLdouble* vertex;
129 
130  vertex = (GLdouble*) malloc(7 * sizeof(GLdouble));
131 
132  vertex[0] = coords[0];
133  vertex[1] = coords[1];
134  vertex[2] = coords[2];
135  *dataOut = vertex;
136 }
137 
138 
139 GLfloat INV_POLY_TEX_DIM = 1.0 / 256.0;
140 GLfloat xPlane[] = {INV_POLY_TEX_DIM, 0.0, 0.0, 0.0};
141 GLfloat yPlane[] = {0.0, INV_POLY_TEX_DIM, 0.0, 0.0};
142 
143 void
145  if (s.polySize.getExaggeration(s) == 0) {
146  return;
147  }
148  Boundary boundary = myShape.getBoxBoundary();
149  if (s.scale * MAX2(boundary.getWidth(), boundary.getHeight()) < s.polySize.minSize) {
150  return;
151  }
152  if (getFill()) {
153  if (myShape.size() < 3) {
154  return;
155  }
156  } else {
157  if (myShape.size() < 2) {
158  return;
159  }
160  }
162  //if (myDisplayList == 0 || (!getFill() && myLineWidth != s.polySize.getExaggeration(s))) {
163  // storeTesselation(s.polySize.getExaggeration(s));
164  //}
165  glPushName(getGlID());
166  glPushMatrix();
167  glTranslated(0, 0, getLayer());
168  glRotated(-getNaviDegree(), 0, 0, 1);
169  // set color depending of selection
171  GLHelper::setColor(RGBColor(0, 0, 204));
172  } else {
174  }
175 
176  int textureID = -1;
177  if (getFill()) {
178  const std::string& file = getImgFile();
179  if (file != "") {
180  textureID = GUITexturesHelper::getTextureID(file, true);
181  }
182  }
183  // init generation of texture coordinates
184  if (textureID >= 0) {
185  glEnable(GL_TEXTURE_2D);
186  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
187  glDisable(GL_CULL_FACE);
188  glDisable(GL_DEPTH_TEST); // without DEPTH_TEST vehicles may be drawn below roads
189  glDisable(GL_LIGHTING);
190  glDisable(GL_COLOR_MATERIAL);
191  glDisable(GL_ALPHA_TEST);
192  glEnable(GL_BLEND);
193  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
194  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
195  glBindTexture(GL_TEXTURE_2D, textureID);
196  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
197  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
198  // http://www.gamedev.net/topic/133564-glutesselation-and-texture-mapping/
199  glEnable(GL_TEXTURE_GEN_S);
200  glEnable(GL_TEXTURE_GEN_T);
201  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
202  glTexGenfv(GL_S, GL_OBJECT_PLANE, xPlane);
203  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
204  glTexGenfv(GL_T, GL_OBJECT_PLANE, yPlane);
205  }
206  // recall tesselation
207  //glCallList(myDisplayList);
209  // de-init generation of texture coordinates
210  if (textureID >= 0) {
211  glEnable(GL_DEPTH_TEST);
212  glBindTexture(GL_TEXTURE_2D, 0);
213  glDisable(GL_TEXTURE_2D);
214  glDisable(GL_TEXTURE_GEN_S);
215  glDisable(GL_TEXTURE_GEN_T);
216  }
217 #ifdef GUIPolygon_DEBUG_DRAW_VERTICES
219 #endif
220  glPopMatrix();
221  const Position namePos = myShape.getPolygonCenter();
222  drawName(namePos, s.scale, s.polyName);
223  if (s.polyType.show) {
224  GLHelper::drawText(myType, namePos + Position(0, -0.6 * s.polyType.size / s.scale),
226  }
227  glPopName();
228 }
229 
230 
231 void
234  SUMOPolygon::setShape(shape);
235  //storeTesselation(myLineWidth);
236 }
237 
238 
239 void
240 GUIPolygon::performTesselation(double lineWidth) const {
241  if (getFill()) {
242  // draw the tesselated shape
243  double* points = new double[myShape.size() * 3];
244  GLUtesselator* tobj = gluNewTess();
245  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
246  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &beginCallback);
247  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &endCallback);
248  //gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (APIENTRY*) ()) &errorCallback);
249  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combineCallback);
250  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
251  gluTessBeginPolygon(tobj, NULL);
252  gluTessBeginContour(tobj);
253  for (int i = 0; i != (int)myShape.size(); ++i) {
254  points[3 * i] = myShape[(int) i].x();
255  points[3 * i + 1] = myShape[(int) i].y();
256  points[3 * i + 2] = 0;
257  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
258  }
259  gluTessEndContour(tobj);
260 
261  gluTessEndPolygon(tobj);
262  gluDeleteTess(tobj);
263  delete[] points;
264 
265  } else {
267  GLHelper::drawBoxLines(myShape, lineWidth);
268  }
269  //std::cout << "OpenGL says: '" << gluErrorString(glGetError()) << "'\n";
270 }
271 
272 
273 void
274 GUIPolygon::storeTesselation(double lineWidth) const {
275  if (myDisplayList > 0) {
276  glDeleteLists(myDisplayList, 1);
277  }
278  myDisplayList = glGenLists(1);
279  if (myDisplayList == 0) {
280  throw ProcessError("GUIPolygon::storeTesselation() could not create display list");
281  }
282  glNewList(myDisplayList, GL_COMPILE);
283  performTesselation(lineWidth);
284  glEndList();
285 }
286 
287 
288 /****************************************************************************/
289 
PositionVector myShape
The positions of the polygon.
Definition: SUMOPolygon.h:125
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
const std::string & getImgFile() const
Returns the imgFile of the Shape.
Definition: Shape.h:101
double scale
information about a lane&#39;s width (temporary, used for a single view)
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
a polygon
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:172
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
GLfloat xPlane[]
Definition: GUIPolygon.cpp:140
virtual void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GUIPolygon.cpp:144
GUIPolygon(const std::string &id, const std::string &type, const RGBColor &color, const PositionVector &shape, bool fill, double layer=0, double angle=0, const std::string &imgFile="")
Constructor.
Definition: GUIPolygon.cpp:49
Stores the information about how to visualize structures.
static void debugVertices(const PositionVector &shape, double size, double layer=256)
draw vertex numbers for the given shape (in a random color)
Definition: GLHelper.cpp:527
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
T MAX2(T a, T b)
Definition: StdDefs.h:74
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
void storeTesselation(double lineWidth) const
store the drawing commands in a display list
Definition: GUIPolygon.cpp:274
const std::map< std::string, std::string > & getMap() const
Returns the inner key/value map.
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
GUIGlID getGlID() const
Returns the numerical id of the object.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:40
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
GLuint myDisplayList
id of the display list for the cached tesselation
Definition: GUIPolygon.h:125
std::string myType
The type of the Shape.
Definition: Shape.h:158
GUIVisualizationSizeSettings polySize
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GUIPolygon.cpp:95
virtual void setShape(const PositionVector &shape)
Sets the shape of the polygon.
Definition: SUMOPolygon.h:113
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:162
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:438
double minSize
The minimum size to draw this object.
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:168
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
GUIVisualizationTextSettings polyType
static int getTextureID(const std::string &filename, const bool mirrorX=false)
return texture id for the given filename (initialize on first use)
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GUIPolygon.cpp:82
bool getFill() const
Returns whether the polygon is filled.
Definition: SUMOPolygon.h:92
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:302
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:265
virtual void setShape(const PositionVector &shape)
set a new shape and update the tesselation
Definition: GUIPolygon.cpp:232
const RGBColor & getColor() const
Returns the color of the Shape.
Definition: Shape.h:79
GLfloat INV_POLY_TEX_DIM
Definition: GUIPolygon.cpp:139
double getLayer() const
Returns the layer of the Shape.
Definition: Shape.h:87
void APIENTRY beginCallback(GLenum which)
Definition: GUIPolygon.cpp:103
void APIENTRY endCallback(void)
Definition: GUIPolygon.cpp:115
void APIENTRY combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GUIPolygon.cpp:123
~GUIPolygon()
Destructor.
Definition: GUIPolygon.cpp:60
A mutex encapsulator which locks/unlocks the given mutex on construction/destruction, respectively.
Definition: AbstractMutex.h:71
The popup menu of a globject.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
void APIENTRY vertexCallback(GLvoid *vertex)
Definition: GUIPolygon.cpp:119
MFXMutex myLock
The mutex used to avoid concurrent updates of the shape.
Definition: GUIPolygon.h:122
double myLineWidth
the previous line width for deciding whether the display list must be refreshed
Definition: GUIPolygon.h:128
empty max
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0)
draw Text with given parameters
Definition: GLHelper.cpp:455
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void mkItem(const char *name, bool dynamic, ValueSource< unsigned > *src)
Adds a row which obtains its value from an unsigned-ValueSource.
GUISelectedStorage gSelected
A global holder of selected objects.
double getNaviDegree() const
Returns the angle of the Shape in navigational degrees.
Definition: Shape.h:94
A window containing a gl-object&#39;s parameter.
GLfloat yPlane[]
Definition: GUIPolygon.cpp:141
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GUIPolygon.cpp:65
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void performTesselation(double lineWidth) const
Definition: GUIPolygon.cpp:240
void APIENTRY errorCallback(GLenum errorCode)
Definition: GUIPolygon.cpp:107
GUIVisualizationTextSettings polyName