Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file GUIDottedGeometry.cpp
15 : /// @author Pablo Alvarez Lopez
16 : /// @date Oct 2021
17 : ///
18 : // File for dotted geometry classes and functions
19 : /****************************************************************************/
20 : #include <utils/geom/GeomHelper.h>
21 : #include <utils/gui/div/GLHelper.h>
22 : #include <utils/gui/globjects/GLIncludes.h>
23 : #include <utils/gui/globjects/GUIGlObjectTypes.h>
24 :
25 : #include "GUIDottedGeometry.h"
26 : #include "GUIGeometry.h"
27 :
28 :
29 : #define MAXIMUM_DOTTEDGEOMETRYLENGTH 500.0
30 :
31 : // ===========================================================================
32 : // method definitions
33 : // ===========================================================================
34 :
35 : // ---------------------------------------------------------------------------
36 : // GUIDottedGeometry::DottedGeometryColor - methods
37 : // ---------------------------------------------------------------------------
38 :
39 0 : GUIDottedGeometry::DottedGeometryColor::DottedGeometryColor() :
40 0 : myColorFlag(true) {}
41 :
42 :
43 : const RGBColor
44 0 : GUIDottedGeometry::DottedGeometryColor::getColor(const GUIVisualizationSettings& settings, DottedContourType type) {
45 0 : switch (type) {
46 0 : case DottedContourType::INSPECT:
47 0 : if (myColorFlag) {
48 0 : myColorFlag = false;
49 0 : return settings.dottedContourSettings.firstInspectedColor;
50 : } else {
51 0 : myColorFlag = true;
52 0 : return settings.dottedContourSettings.secondInspectedColor;
53 : }
54 0 : case DottedContourType::FRONT:
55 0 : if (myColorFlag) {
56 0 : myColorFlag = false;
57 0 : return settings.dottedContourSettings.firstFrontColor;
58 : } else {
59 0 : myColorFlag = true;
60 0 : return settings.dottedContourSettings.secondFrontColor;
61 : }
62 0 : case DottedContourType::FROM:
63 0 : if (myColorFlag) {
64 0 : myColorFlag = false;
65 0 : return RGBColor::GREEN;
66 : } else {
67 0 : myColorFlag = true;
68 0 : return RGBColor::GREEN.changedBrightness(-30);
69 : }
70 0 : case DottedContourType::TO:
71 0 : if (myColorFlag) {
72 0 : myColorFlag = false;
73 0 : return RGBColor::MAGENTA;
74 : } else {
75 0 : myColorFlag = true;
76 0 : return RGBColor::MAGENTA.changedBrightness(-30);
77 : }
78 0 : case DottedContourType::REMOVE:
79 0 : if (myColorFlag) {
80 0 : myColorFlag = false;
81 0 : return RGBColor(229, 233, 255);
82 : } else {
83 0 : myColorFlag = true;
84 0 : return RGBColor(255, 109, 196);
85 : }
86 0 : case DottedContourType::SELECT:
87 0 : if (myColorFlag) {
88 0 : myColorFlag = false;
89 0 : return RGBColor::BLUE;
90 : } else {
91 0 : myColorFlag = true;
92 0 : return RGBColor::BLUE.changedBrightness(-30);
93 : }
94 0 : case DottedContourType::MOVE:
95 0 : if (myColorFlag) {
96 0 : myColorFlag = false;
97 0 : return RGBColor(220, 0, 0);
98 : } else {
99 0 : myColorFlag = true;
100 0 : return RGBColor(220, 0, 0).changedBrightness(-30);
101 : }
102 0 : case DottedContourType::OVER:
103 0 : if (myColorFlag) {
104 0 : myColorFlag = false;
105 0 : return RGBColor::ORANGE;
106 : } else {
107 0 : myColorFlag = true;
108 0 : return RGBColor::ORANGE.changedBrightness(-30);
109 : }
110 0 : case DottedContourType::RELATED:
111 0 : if (myColorFlag) {
112 0 : myColorFlag = false;
113 0 : return RGBColor::CYAN;
114 : } else {
115 0 : myColorFlag = true;
116 0 : return RGBColor::CYAN.changedBrightness(-30);
117 : }
118 0 : case DottedContourType::WALKINGAREA:
119 0 : return settings.junctionColorer.getScheme().getColor(6);
120 0 : default:
121 0 : return RGBColor::BLACK;
122 : }
123 : }
124 :
125 :
126 : void
127 0 : GUIDottedGeometry::DottedGeometryColor::changeColor() {
128 0 : if (myColorFlag) {
129 0 : myColorFlag = false;
130 : } else {
131 0 : myColorFlag = true;
132 : }
133 0 : }
134 :
135 :
136 : void
137 0 : GUIDottedGeometry::DottedGeometryColor::reset() {
138 0 : myColorFlag = true;
139 0 : }
140 :
141 : // ---------------------------------------------------------------------------
142 : // GUIDottedGeometry::Segment - methods
143 : // ---------------------------------------------------------------------------
144 :
145 0 : GUIDottedGeometry::Segment::Segment() {}
146 :
147 :
148 0 : GUIDottedGeometry::Segment::Segment(PositionVector newShape) :
149 : shape(newShape) {
150 0 : }
151 :
152 : // ---------------------------------------------------------------------------
153 : // GUIDottedGeometry - methods
154 : // ---------------------------------------------------------------------------
155 :
156 0 : GUIDottedGeometry::GUIDottedGeometry() {}
157 :
158 :
159 0 : GUIDottedGeometry::GUIDottedGeometry(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
160 0 : PositionVector shape, const bool closeShape) {
161 : // set shape as unresampled shape
162 : myUnresampledShape = shape;
163 : // check if shape has to be closed
164 0 : if (closeShape && (myUnresampledShape.size() > 2)) {
165 0 : myUnresampledShape.closePolygon();
166 : }
167 0 : if (myUnresampledShape.size() > 1) {
168 : // get shape
169 0 : for (int i = 1; i < (int)myUnresampledShape.size(); i++) {
170 0 : myDottedGeometrySegments.push_back(Segment({myUnresampledShape[i - 1], myUnresampledShape[i]}));
171 : }
172 : // check if resample
173 0 : if (d <= GUIVisualizationSettings::Detail::DottedContoursResampled) {
174 : // calculate segment length
175 0 : double segmentLength = s.dottedContourSettings.segmentLength;
176 0 : if (myUnresampledShape.length2D() > MAXIMUM_DOTTEDGEOMETRYLENGTH) {
177 0 : segmentLength = myUnresampledShape.length2D() / (MAXIMUM_DOTTEDGEOMETRYLENGTH * 0.5);
178 : }
179 : // resample all dotted geometries
180 0 : for (auto& segment : myDottedGeometrySegments) {
181 0 : segment.shape = segment.shape.resample(segmentLength, true);
182 : }
183 : }
184 : // calculate shape rotations and lengths
185 0 : calculateShapeRotationsAndLengths();
186 : }
187 0 : }
188 :
189 :
190 : void
191 0 : GUIDottedGeometry::updateDottedGeometry(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
192 : const PositionVector& laneShape) {
193 : // set shape as unresampled shape
194 : myUnresampledShape = laneShape;
195 : // reset segments
196 : myDottedGeometrySegments.clear();
197 : // get shape
198 0 : for (int i = 1; i < (int)myUnresampledShape.size(); i++) {
199 0 : myDottedGeometrySegments.push_back(Segment({myUnresampledShape[i - 1], myUnresampledShape[i]}));
200 : }
201 : // check if resample
202 0 : if (d <= GUIVisualizationSettings::Detail::DottedContoursResampled) {
203 0 : for (auto& segment : myDottedGeometrySegments) {
204 0 : segment.shape = segment.shape.resample(s.dottedContourSettings.segmentLength, true);
205 : }
206 : }
207 : // calculate shape rotations and lengths
208 0 : calculateShapeRotationsAndLengths();
209 0 : }
210 :
211 :
212 : void
213 0 : GUIDottedGeometry::updateDottedGeometry(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
214 : PositionVector shape, const bool closeShape) {
215 : // set shape as unresampled shape
216 : myUnresampledShape = shape;
217 : // reset segments
218 : myDottedGeometrySegments.clear();
219 : // check if shape has to be closed
220 0 : if (closeShape && (myUnresampledShape.size() > 2)) {
221 0 : myUnresampledShape.closePolygon();
222 : }
223 0 : if (myUnresampledShape.size() > 1) {
224 : // get shape
225 0 : for (int i = 1; i < (int)myUnresampledShape.size(); i++) {
226 0 : myDottedGeometrySegments.push_back(Segment({myUnresampledShape[i - 1], myUnresampledShape[i]}));
227 : }
228 : // check if resample
229 0 : if (d <= GUIVisualizationSettings::Detail::DottedContoursResampled) {
230 0 : for (auto& segment : myDottedGeometrySegments) {
231 0 : segment.shape = segment.shape.resample(s.dottedContourSettings.segmentLength, true);
232 : }
233 : }
234 : // calculate shape rotations and lengths
235 0 : calculateShapeRotationsAndLengths();
236 : }
237 0 : }
238 :
239 :
240 : void
241 0 : GUIDottedGeometry::drawDottedGeometry(const GUIVisualizationSettings& s, GUIDottedGeometry::DottedContourType type,
242 : DottedGeometryColor& dottedGeometryColor, const double lineWidth, const bool addOffset) const {
243 : // iterate over all segments
244 0 : for (auto& segment : myDottedGeometrySegments) {
245 : // iterate over shape
246 0 : for (int i = 0; i < ((int)segment.shape.size() - 1); i++) {
247 : // set color
248 0 : GLHelper::setColor(dottedGeometryColor.getColor(s, type));
249 : // draw box line depending of addOffset
250 0 : if (addOffset) {
251 0 : GLHelper::drawBoxLine(segment.shape[i], segment.rotations.at(i), segment.lengths.at(i), lineWidth, -lineWidth);
252 : } else {
253 0 : GLHelper::drawBoxLine(segment.shape[i], segment.rotations.at(i), segment.lengths.at(i), lineWidth);
254 : }
255 : }
256 : }
257 0 : }
258 :
259 :
260 : void
261 0 : GUIDottedGeometry::drawInnenGeometry(const double lineWidth) const {
262 : // iterate over all segments
263 0 : for (auto& segment : myDottedGeometrySegments) {
264 : // iterate over shape
265 0 : for (int i = 0; i < ((int)segment.shape.size() - 1); i++) {
266 0 : GLHelper::drawBoxLine(segment.shape[i], segment.rotations.at(i), segment.lengths.at(i), lineWidth, lineWidth);
267 : }
268 : }
269 0 : }
270 :
271 :
272 : void
273 0 : GUIDottedGeometry::moveShapeToSide(const double value) {
274 : // move to side all dotted geometry segments
275 0 : for (auto& segment : myDottedGeometrySegments) {
276 0 : segment.shape.move2side(value);
277 : }
278 : // also unresampled shape
279 0 : myUnresampledShape.move2side(value);
280 0 : }
281 :
282 :
283 : Position
284 0 : GUIDottedGeometry::getFrontPosition() const {
285 0 : if (myUnresampledShape.size() > 0) {
286 0 : return myUnresampledShape.front();
287 : } else {
288 0 : return Position::INVALID;
289 : }
290 : }
291 :
292 :
293 : Position
294 0 : GUIDottedGeometry::getBackPosition() const {
295 0 : if (myUnresampledShape.size() > 0) {
296 0 : return myUnresampledShape.back();
297 : } else {
298 0 : return Position::INVALID;
299 : }
300 : }
301 :
302 :
303 : const PositionVector&
304 0 : GUIDottedGeometry::getUnresampledShape() const {
305 0 : return myUnresampledShape;
306 : }
307 :
308 :
309 : void
310 0 : GUIDottedGeometry::clearDottedGeometry() {
311 : myDottedGeometrySegments.clear();
312 : myUnresampledShape.clear();
313 0 : }
314 :
315 :
316 : void
317 0 : GUIDottedGeometry::calculateShapeRotationsAndLengths() {
318 : // iterate over all segments
319 0 : for (auto& segment : myDottedGeometrySegments) {
320 : // Get number of parts of the shape
321 0 : int numberOfSegments = (int)segment.shape.size() - 1;
322 : // If number of segments is more than 0
323 0 : if (numberOfSegments >= 0) {
324 : // Reserve memory (To improve efficiency)
325 0 : segment.rotations.reserve(numberOfSegments);
326 0 : segment.lengths.reserve(numberOfSegments);
327 : // Calculate lengths and rotations for every shape
328 0 : for (int i = 0; i < numberOfSegments; i++) {
329 0 : segment.rotations.push_back(GUIGeometry::calculateRotation(segment.shape[i], segment.shape[i + 1]));
330 0 : segment.lengths.push_back(GUIGeometry::calculateLength(segment.shape[i], segment.shape[i + 1]));
331 : }
332 : }
333 : }
334 0 : }
335 :
336 : /****************************************************************************/
|