Skip to content

Commit

Permalink
Optimized GNEContour. Refs #14175
Browse files Browse the repository at this point in the history
  • Loading branch information
palvarezlopez committed Dec 20, 2023
1 parent af8ec3b commit e23fb64
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 102 deletions.
199 changes: 108 additions & 91 deletions src/netedit/elements/GNEContour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ GNEContour::calculateContourCircleShape(const GUIVisualizationSettings& s, const
// calculate circle shape
buildContourCircle(s, d, pos, radius, scale);
// check if position or bondary is within circle shape
gViewObjectsHandler.checkCircleElement(d, glObject, pos, (radius * scale));
gViewObjectsHandler.checkCircleElement(d, glObject, pos, (radius * scale), *myContourBoundary);
}
}

Expand Down Expand Up @@ -345,24 +345,25 @@ GNEContour::drawDottedContourGeometryPoints(const GUIVisualizationSettings& s, c
void
GNEContour::drawInnenContourClosed(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
const PositionVector& shape, const double scale, const double lineWidth) const {
// declare scaled shape
PositionVector scaledShape = shape;
// scale shape
scaledShape.scaleRelative(scale);
// close
scaledShape.closePolygon();
// calculate geometry without resampling
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, scaledShape, true);
// reset dotted geometry color
myDottedGeometryColor.reset();
// Push draw matrix
GLHelper::pushMatrix();
// draw dotted
myDottedGeometries->at(0).drawInnenGeometry(lineWidth);
// update contour boundary
updateContourBondary();
// pop matrix
GLHelper::popMatrix();
// set calculated shape
*myCalculatedShape = shape;
// continue only if shape has at least three elements and scale isn't 0
if ((myCalculatedShape->size() > 2) && (scale > 0)) {
// scale shape
myCalculatedShape->scaleRelative(scale);
// close
myCalculatedShape->closePolygon();
// calculate geometry without resampling
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// reset dotted geometry color
myDottedGeometryColor.reset();
// Push draw matrix
GLHelper::pushMatrix();
// draw dotted
myDottedGeometries->at(0).drawInnenGeometry(lineWidth);
// pop matrix
GLHelper::popMatrix();
}
}


Expand All @@ -371,49 +372,59 @@ GNEContour::buildContourClosedShape(const GUIVisualizationSettings& s, const GUI
const PositionVector& shape, const double scale) const {
// set calculated shape
*myCalculatedShape = shape;
// scale shape
myCalculatedShape->scaleRelative(scale);
// close
myCalculatedShape->closePolygon();
// calculate dotted geometry
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// update contour boundary
updateContourBondary();
// continue only if shape has at least three elements and scale isn't 0
if ((myCalculatedShape->size() > 2) && (scale > 0)) {
// scale shape
myCalculatedShape->scaleRelative(scale);
// close
myCalculatedShape->closePolygon();
// calculate dotted geometry
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// update contour boundary
*myContourBoundary = myCalculatedShape->getBoxBoundary();
} else {
myContourBoundary->reset();
}
}


void
GNEContour::buildContourExtrudedShape(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
const PositionVector& shape, const double extrusionWidth, const double scale,
const bool closeFirstExtrem, const bool closeLastExtrem, const double offset) const {
// create top and bot geometries
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, shape, false);
myDottedGeometries->at(2) = GUIDottedGeometry(s, d, shape.reverse(), false);
// move geometries top and bot
myDottedGeometries->at(0).moveShapeToSide((extrusionWidth * scale * -1) + offset);
myDottedGeometries->at(2).moveShapeToSide((extrusionWidth * scale * -1) - offset);
// create left and right geometries
if (closeFirstExtrem) {
myDottedGeometries->at(3) = GUIDottedGeometry(s, d, {
myDottedGeometries->at(2).getBackPosition(),
myDottedGeometries->at(0).getFrontPosition()
}, false);
}
if (closeLastExtrem) {
myDottedGeometries->at(1) = GUIDottedGeometry(s, d, {
myDottedGeometries->at(0).getBackPosition(),
myDottedGeometries->at(2).getFrontPosition()
}, false);
}
// update contour boundary
updateContourBondary();
// reset calculated shape
myCalculatedShape->clear();
for (const auto &position : myDottedGeometries->at(0).getUnresampledShape()) {
myCalculatedShape->push_back(position);
}
for (const auto &position : myDottedGeometries->at(2).getUnresampledShape()) {
myCalculatedShape->push_back(position);
// avoid empty shapes
if (shape.size() > 1 && (extrusionWidth > 0)) {
// create top and bot geometries
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, shape, false);
myDottedGeometries->at(2) = GUIDottedGeometry(s, d, shape.reverse(), false);
// move geometries top and bot
myDottedGeometries->at(0).moveShapeToSide((extrusionWidth * scale * -1) + offset);
myDottedGeometries->at(2).moveShapeToSide((extrusionWidth * scale * -1) - offset);
// create left and right geometries
if (closeFirstExtrem) {
myDottedGeometries->at(3) = GUIDottedGeometry(s, d, {
myDottedGeometries->at(2).getBackPosition(),
myDottedGeometries->at(0).getFrontPosition()
}, false);
}
if (closeLastExtrem) {
myDottedGeometries->at(1) = GUIDottedGeometry(s, d, {
myDottedGeometries->at(0).getBackPosition(),
myDottedGeometries->at(2).getFrontPosition()
}, false);
}
for (const auto &position : myDottedGeometries->at(0).getUnresampledShape()) {
myCalculatedShape->push_back(position);
}
for (const auto &position : myDottedGeometries->at(2).getUnresampledShape()) {
myCalculatedShape->push_back(position);
}
// update contour boundary
*myContourBoundary = myCalculatedShape->getBoxBoundary();
} else {
myContourBoundary->reset();
}
}

Expand All @@ -424,23 +435,28 @@ GNEContour::buildContourRectangle(const GUIVisualizationSettings& s, const GUIVi
const double offsetY, const double rot, const double scale) const {
// reset calculated shape
myCalculatedShape->clear();
// make rectangle
myCalculatedShape->push_back(Position(0 + width, 0 + height));
myCalculatedShape->push_back(Position(0 + width, 0 - height));
myCalculatedShape->push_back(Position(0 - width, 0 - height));
myCalculatedShape->push_back(Position(0 - width, 0 + height));
// move shape
myCalculatedShape->add(offsetX, offsetY, 0);
// scale
myCalculatedShape->scaleRelative(scale);
// rotate shape
myCalculatedShape->rotate2D(DEG2RAD((rot * -1) + 90));
// move to position
myCalculatedShape->add(pos);
// calculate dotted geometry
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// update contour boundary
updateContourBondary();
// check sizes
if (((width + height) > 0) && (scale > 0)) {
// make rectangle
myCalculatedShape->push_back(Position(0 + width, 0 + height));
myCalculatedShape->push_back(Position(0 + width, 0 - height));
myCalculatedShape->push_back(Position(0 - width, 0 - height));
myCalculatedShape->push_back(Position(0 - width, 0 + height));
// move shape
myCalculatedShape->add(offsetX, offsetY, 0);
// scale
myCalculatedShape->scaleRelative(scale);
// rotate shape
myCalculatedShape->rotate2D(DEG2RAD((rot * -1) + 90));
// move to position
myCalculatedShape->add(pos);
// calculate dotted geometry
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// update contour boundary
*myContourBoundary = myCalculatedShape->getBoxBoundary();
} else {
myContourBoundary->reset();
}
}


Expand All @@ -449,21 +465,28 @@ GNEContour::buildContourCircle(const GUIVisualizationSettings& s, const GUIVisua
const Position& pos, double radius, const double scale) const {
// reset calculated shape
myCalculatedShape->clear();
// continue depending of resolution
if (d <= GUIVisualizationSettings::Detail::CircleResolution32) {
*myCalculatedShape = GUIGeometry::getVertexCircleAroundPosition(pos, radius * scale, 16);
} else if (d <= GUIVisualizationSettings::Detail::CircleResolution16) {
*myCalculatedShape = GUIGeometry::getVertexCircleAroundPosition(pos, radius * scale, 8);
// get scaled radius
const double scaledRadius = radius * scale;
// check scaled radius
if (scaledRadius > POSITION_EPS) {
// continue depending of resolution
if (d <= GUIVisualizationSettings::Detail::CircleResolution32) {
*myCalculatedShape = GUIGeometry::getVertexCircleAroundPosition(pos, scaledRadius, 16);
} else if (d <= GUIVisualizationSettings::Detail::CircleResolution16) {
*myCalculatedShape = GUIGeometry::getVertexCircleAroundPosition(pos, scaledRadius, 8);
} else {
myCalculatedShape->push_back(Position(pos.x() - radius, pos.y() - radius));
myCalculatedShape->push_back(Position(pos.x() - radius, pos.y() + radius));
myCalculatedShape->push_back(Position(pos.x() + radius, pos.y() + radius));
myCalculatedShape->push_back(Position(pos.x() + radius, pos.y() - radius));
}
// calculate dotted geometry
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// update contour boundary
*myContourBoundary = myCalculatedShape->getBoxBoundary();
} else {
myCalculatedShape->push_back(Position(pos.x() - radius, pos.y() - radius));
myCalculatedShape->push_back(Position(pos.x() - radius, pos.y() + radius));
myCalculatedShape->push_back(Position(pos.x() + radius, pos.y() + radius));
myCalculatedShape->push_back(Position(pos.x() + radius, pos.y() - radius));
myContourBoundary->reset();
}
// calculate dotted geometry
myDottedGeometries->at(0) = GUIDottedGeometry(s, d, *myCalculatedShape, true);
// update contour boundary
updateContourBondary();
}


Expand Down Expand Up @@ -496,15 +519,15 @@ GNEContour::buildContourEdge(const GUIVisualizationSettings& s, const GUIVisuali
myDottedGeometries->at(2).getFrontPosition()
}, false);
}
// update contour boundary
updateContourBondary();
// update calculated shape
for (const auto &position : myDottedGeometries->at(0).getUnresampledShape()) {
myCalculatedShape->push_back(position);
}
for (const auto &position : myDottedGeometries->at(2).getUnresampledShape()) {
myCalculatedShape->push_back(position);
}
// update contour boundary
*myContourBoundary = myCalculatedShape->getBoxBoundary();
}


Expand All @@ -516,12 +539,6 @@ GNEContour::buildContourEdges(const GUIVisualizationSettings& /*s*/, const GUIVi
}


void
GNEContour::updateContourBondary() const {
*myContourBoundary = myCalculatedShape->getBoxBoundary();
}


void
GNEContour::drawDottedContour(const GUIVisualizationSettings& s, GUIDottedGeometry::DottedContourType type,
const double lineWidth, const bool addOffset) const {
Expand Down
4 changes: 0 additions & 4 deletions src/netedit/elements/GNEContour.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,6 @@ class GNEContour {
/// @brief build contour between two from-to edgeds
void buildContourEdges(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
const GNEEdge* fromEdge, const GNEEdge* toEdge) const;

/// @brief update contour boundary
void updateContourBondary() const;

/// @}

/// @brief draw dotted contour
Expand Down
16 changes: 10 additions & 6 deletions src/utils/gui/div/GUIViewObjectsHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ GUIViewObjectsHandler::checkBoundaryParentElement(const GUIGlObject* GLObject, c

bool
GUIViewObjectsHandler::checkCircleElement(const GUIVisualizationSettings::Detail d, const GUIGlObject* GLObject,
const Position &center, const double radius) {
const Position &center, const double radius, const Boundary &circleBoundary) {
// first check that object doesn't exist
if (isElementSelected(GLObject)) {
return false;
Expand All @@ -118,16 +118,16 @@ GUIViewObjectsHandler::checkCircleElement(const GUIVisualizationSettings::Detail
if (mySelectionBoundary.isInitialised()) {
// continue depending of detail level
if (d <= GUIVisualizationSettings::Detail::PreciseSelection) {
// make a boundary using center and radius
Boundary b;
b.add(center);
b.grow(radius);
// avoid empty boundaries
if (!circleBoundary.isInitialised()) {
return false;
}
// check if selection boundary contains the centering boundary of object
if (mySelectionBoundary.contains(GLObject->getCenteringBoundary())) {
return addElementUnderCursor(GLObject, false, true);
}
// check if boundary overlaps
if (mySelectionBoundary.overlapsWith(b)) {
if (mySelectionBoundary.overlapsWith(circleBoundary)) {
return addElementUnderCursor(GLObject, false, false);
}
// check if the four boundary vertex are within circle
Expand Down Expand Up @@ -238,6 +238,10 @@ GUIViewObjectsHandler::checkShapeElement(const GUIGlObject* GLObject, const Posi
if (isElementSelected(GLObject)) {
return false;
}else if (mySelectionBoundary.isInitialised()) {
// avoid invalid boundaries
if (!shapeBoundary.isInitialised()) {
return false;
}
// check if selection boundary contains the centering boundary of object
if (mySelectionBoundary.contains(shapeBoundary)) {
return addElementUnderCursor(GLObject, false, true);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/gui/div/GUIViewObjectsHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class GUIViewObjectsHandler {

/// @brief check if mouse is within elements geometry (for circles)
bool checkCircleElement(const GUIVisualizationSettings::Detail d, const GUIGlObject* GLObject,
const Position &center, const double radius);
const Position &center, const double radius, const Boundary &circleBoundary);

/// @brief check if mouse is within geometry point
bool checkGeometryPoint(const GUIVisualizationSettings::Detail d, const GUIGlObject* GLObject,
Expand Down

0 comments on commit e23fb64

Please sign in to comment.