SUMO - Simulation of Urban MObility
GUIPolygon.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // The GUI-version of a polygon
19 /****************************************************************************/
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <string>
27 #include "GUIPolygon.h"
34 #include <utils/gui/div/GLHelper.h>
35 
36 //#define GUIPolygon_DEBUG_DRAW_VERTICES
37 
38 // ===========================================================================
39 // method definitions
40 // ===========================================================================
41 GUIPolygon::GUIPolygon(const std::string& id, const std::string& type,
42  const RGBColor& color, const PositionVector& shape, bool geo,
43  bool fill, double layer, double angle, const std::string& imgFile,
44  bool relativePath):
45  SUMOPolygon(id, type, color, shape, geo, fill, layer, angle, imgFile, relativePath),
47  myDisplayList(0),
48  myLineWidth(1) // m
49 
50 {}
51 
52 
54 
55 
56 
59  GUISUMOAbstractView& parent) {
60  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
61  buildPopupHeader(ret, app, false);
62  FXString t(getShapeType().c_str());
63  new FXMenuCommand(ret, "(" + t + ")", 0, 0, 0);
64  new FXMenuSeparator(ret);
68  buildShowParamsPopupEntry(ret, false);
69  buildPositionCopyEntry(ret, false);
70  return ret;
71 }
72 
73 
78  new GUIParameterTableWindow(app, *this, 3 + (int)getParametersMap().size());
79  // add items
80  ret->mkItem("type", false, getShapeType());
81  ret->mkItem("layer", false, toString(getShapeLayer()));
82  ret->closeBuilding(this);
83  return ret;
84 }
85 
86 
89  Boundary b;
91  b.grow(2);
92  return b;
93 }
94 
95 
96 void APIENTRY beginCallback(GLenum which) {
97  glBegin(which);
98 }
99 
100 void APIENTRY errorCallback(GLenum errorCode) {
101  const GLubyte* estring;
102 
103  estring = gluErrorString(errorCode);
104  fprintf(stderr, "Tessellation Error: %s\n", estring);
105  exit(0);
106 }
107 
108 void APIENTRY endCallback(void) {
109  glEnd();
110 }
111 
112 void APIENTRY vertexCallback(GLvoid* vertex) {
113  glVertex3dv((GLdouble*) vertex);
114 }
115 
116 void APIENTRY combineCallback(GLdouble coords[3],
117  GLdouble* vertex_data[4],
118  GLfloat weight[4], GLdouble** dataOut) {
119  UNUSED_PARAMETER(weight);
120  UNUSED_PARAMETER(*vertex_data);
121  GLdouble* vertex;
122 
123  vertex = (GLdouble*) malloc(7 * sizeof(GLdouble));
124 
125  vertex[0] = coords[0];
126  vertex[1] = coords[1];
127  vertex[2] = coords[2];
128  *dataOut = vertex;
129 }
130 
131 
132 GLfloat INV_POLY_TEX_DIM = 1.0 / 256.0;
133 GLfloat xPlane[] = {INV_POLY_TEX_DIM, 0.0, 0.0, 0.0};
134 GLfloat yPlane[] = {0.0, INV_POLY_TEX_DIM, 0.0, 0.0};
135 
136 void
138  if (s.polySize.getExaggeration(s) == 0) {
139  return;
140  }
141  Boundary boundary = myShape.getBoxBoundary();
142  if (s.scale * MAX2(boundary.getWidth(), boundary.getHeight()) < s.polySize.minSize) {
143  return;
144  }
145  if (getFill()) {
146  if (myShape.size() < 3) {
147  return;
148  }
149  } else {
150  if (myShape.size() < 2) {
151  return;
152  }
153  }
155  //if (myDisplayList == 0 || (!getFill() && myLineWidth != s.polySize.getExaggeration(s))) {
156  // storeTesselation(s.polySize.getExaggeration(s));
157  //}
158  glPushName(getGlID());
159  glPushMatrix();
160  glTranslated(0, 0, getShapeLayer());
161  glRotated(-getShapeNaviDegree(), 0, 0, 1);
162  setColor(s);
163 
164  int textureID = -1;
165  if (getFill()) {
166  const std::string& file = getShapeImgFile();
167  if (file != "") {
168  textureID = GUITexturesHelper::getTextureID(file, true);
169  }
170  }
171  // init generation of texture coordinates
172  if (textureID >= 0) {
173  glEnable(GL_TEXTURE_2D);
174  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
175  glDisable(GL_CULL_FACE);
176  glDisable(GL_DEPTH_TEST); // without DEPTH_TEST vehicles may be drawn below roads
177  glDisable(GL_LIGHTING);
178  glDisable(GL_COLOR_MATERIAL);
179  glDisable(GL_ALPHA_TEST);
180  glEnable(GL_BLEND);
181  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
182  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
183  glBindTexture(GL_TEXTURE_2D, textureID);
184  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
185  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
186  // http://www.gamedev.net/topic/133564-glutesselation-and-texture-mapping/
187  glEnable(GL_TEXTURE_GEN_S);
188  glEnable(GL_TEXTURE_GEN_T);
189  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
190  glTexGenfv(GL_S, GL_OBJECT_PLANE, xPlane);
191  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
192  glTexGenfv(GL_T, GL_OBJECT_PLANE, yPlane);
193  }
194  // recall tesselation
195  //glCallList(myDisplayList);
197  // de-init generation of texture coordinates
198  if (textureID >= 0) {
199  glEnable(GL_DEPTH_TEST);
200  glBindTexture(GL_TEXTURE_2D, 0);
201  glDisable(GL_TEXTURE_2D);
202  glDisable(GL_TEXTURE_GEN_S);
203  glDisable(GL_TEXTURE_GEN_T);
204  }
205 #ifdef GUIPolygon_DEBUG_DRAW_VERTICES
207 #endif
208  glPopMatrix();
209  const Position namePos = myShape.getPolygonCenter();
210  drawName(namePos, s.scale, s.polyName, s.angle);
211  if (s.polyType.show) {
212  GLHelper::drawText(getShapeType(), namePos + Position(0, -0.6 * s.polyType.size / s.scale),
214  }
215  glPopName();
216 }
217 
218 
219 void
222  SUMOPolygon::setShape(shape);
223  //storeTesselation(myLineWidth);
224 }
225 
226 
227 void
228 GUIPolygon::performTesselation(double lineWidth) const {
229  if (getFill()) {
230  // draw the tesselated shape
231  double* points = new double[myShape.size() * 3];
232  GLUtesselator* tobj = gluNewTess();
233  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
234  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &beginCallback);
235  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &endCallback);
236  //gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (APIENTRY*) ()) &errorCallback);
237  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combineCallback);
238  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
239  gluTessBeginPolygon(tobj, NULL);
240  gluTessBeginContour(tobj);
241  for (int i = 0; i != (int)myShape.size(); ++i) {
242  points[3 * i] = myShape[(int) i].x();
243  points[3 * i + 1] = myShape[(int) i].y();
244  points[3 * i + 2] = 0;
245  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
246  }
247  gluTessEndContour(tobj);
248 
249  gluTessEndPolygon(tobj);
250  gluDeleteTess(tobj);
251  delete[] points;
252 
253  } else {
255  GLHelper::drawBoxLines(myShape, lineWidth);
256  }
257  //std::cout << "OpenGL says: '" << gluErrorString(glGetError()) << "'\n";
258 }
259 
260 
261 void
262 GUIPolygon::storeTesselation(double lineWidth) const {
263  if (myDisplayList > 0) {
264  glDeleteLists(myDisplayList, 1);
265  }
266  myDisplayList = glGenLists(1);
267  if (myDisplayList == 0) {
268  throw ProcessError("GUIPolygon::storeTesselation() could not create display list");
269  }
270  glNewList(myDisplayList, GL_COMPILE);
271  performTesselation(lineWidth);
272  glEndList();
273 }
274 
275 
276 void
278  const GUIColorer& c = s.polyColorer;
279  const int active = c.getActive();
280  if (s.netedit && active != 1 && gSelected.isSelected(GLO_POLYGON, getGlID())) {
281  // override with special colors (unless the color scheme is based on selection)
282  GLHelper::setColor(RGBColor(0, 0, 204));
283  } else if (active == 0) {
285  } else if (active == 1) {
287  } else {
289  }
290 }
291 
292 /****************************************************************************/
293 
PositionVector myShape
The positions of the polygon.
Definition: SUMOPolygon.h:120
void setColor(const GUIVisualizationSettings &s) const
set color
Definition: GUIPolygon.cpp:277
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:178
const std::string & getShapeImgFile() const
Returns the imgFile of the Shape.
Definition: Shape.h:103
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:133
void performTesselation(double lineWidth) const
Definition: GUIPolygon.cpp:228
void storeTesselation(double lineWidth) const
store the drawing commands in a display list
Definition: GUIPolygon.cpp:262
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:720
void mkItem(const char *name, bool dynamic, ValueSource< T > *src)
Adds a row which obtains its value from a ValueSource.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
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, int align=0, double width=-1)
Definition: GLHelper.cpp:611
T MAX2(T a, T b)
Definition: StdDefs.h:76
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:155
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
bool netedit
Whether the settings are for Netedit.
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.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
GLuint myDisplayList
id of the display list for the cached tesselation
Definition: GUIPolygon.h:123
const std::string & getShapeType() const
Returns the (abstract) type of the Shape.
Definition: Shape.h:75
GUIVisualizationSizeSettings polySize
virtual void setShape(const PositionVector &shape)
Sets the shape of the polygon.
Definition: SUMOPolygon.h:108
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:573
double minSize
The minimum size to draw this object.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
A list of positions.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
const RGBColor & getShapeColor() const
Returns the color of the Shape.
Definition: Shape.h:82
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:75
GUIColorer polyColorer
The polygon colorer.
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
GUIPolygon(const std::string &id, const std::string &type, const RGBColor &color, const PositionVector &shape, bool geo, bool fill, double layer=0, double angle=0, const std::string &imgFile="", bool relativePath=false)
Constructor.
Definition: GUIPolygon.cpp:41
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
double angle
The current view rotation angle.
const T getColor(const double value) const
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:270
virtual void setShape(const PositionVector &shape)
set a new shape and update the tesselation
Definition: GUIPolygon.cpp:220
bool getFill() const
Returns whether the polygon is filled.
Definition: SUMOPolygon.h:88
double getShapeLayer() const
Returns the layer of the Shape.
Definition: Shape.h:89
GLfloat INV_POLY_TEX_DIM
Definition: GUIPolygon.cpp:132
void APIENTRY beginCallback(GLenum which)
Definition: GUIPolygon.cpp:96
virtual void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GUIPolygon.cpp:137
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:161
void APIENTRY endCallback(void)
Definition: GUIPolygon.cpp:108
void APIENTRY combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GUIPolygon.cpp:116
~GUIPolygon()
Destructor.
Definition: GUIPolygon.cpp:53
A mutex encapsulator which locks/unlocks the given mutex on construction/destruction, respectively.
Definition: AbstractMutex.h:59
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:112
MFXMutex myLock
The mutex used to avoid concurrent updates of the shape.
Definition: GUIPolygon.h:120
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
GUIGlID getGlID() const
Returns the numerical id of the object.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
double myLineWidth
the previous line width for deciding whether the display list must be refreshed
Definition: GUIPolygon.h:126
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
empty max
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GUIPolygon.cpp:88
GUISelectedStorage gSelected
A global holder of selected objects.
A window containing a gl-object&#39;s parameter.
GLfloat yPlane[]
Definition: GUIPolygon.cpp:134
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GUIPolygon.cpp:58
double getShapeNaviDegree() const
Returns the angle of the Shape in navigational degrees.
Definition: Shape.h:96
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void APIENTRY errorCallback(GLenum errorCode)
Definition: GUIPolygon.cpp:100
GUIVisualizationTextSettings polyName