Commit e5a1279a authored by Luna Riegel's avatar Luna Riegel
Browse files

Fix: Add highlighting of topology errors

parent c06d3a89
Pipeline #12424 failed with stage
in 1 minute and 10 seconds
...@@ -15,16 +15,11 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; ...@@ -15,16 +15,11 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractLinearRing.LinearRingType; import de.hft.stuttgart.citydoctor2.datastructure.AbstractLinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.gui.gl.FloatList; import de.hft.stuttgart.citydoctor2.gui.gl.FloatList;
import de.hft.stuttgart.citydoctor2.gui.gl.GLViewport; import de.hft.stuttgart.citydoctor2.gui.gl.GLViewport;
import de.hft.stuttgart.citydoctor2.math.Triangle3d; import de.hft.stuttgart.citydoctor2.math.Triangle3d;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.CollisionRecord; import de.hft.stuttgart.citydoctor2.utils.CollisionRecord;
import javafx.application.Platform;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
/** /**
...@@ -137,7 +132,16 @@ public class HighlightController { ...@@ -137,7 +132,16 @@ public class HighlightController {
push(); push();
} }
public void highlight(Geometry geometry) {
highlightPolygons(geometry.getPolygons());
}
private void addHighlight(LinearRing ring, Color pointColor) { private void addHighlight(LinearRing ring, Color pointColor) {
addHighlight(ring, pointColor, Color.ORANGE);
}
private void addHighlight(LinearRing ring, Color pointColor, Color lineColor) {
if (ring == null) { if (ring == null) {
return; return;
} }
...@@ -147,7 +151,7 @@ public class HighlightController { ...@@ -147,7 +151,7 @@ public class HighlightController {
for (int i = 0; i < ring.getVertices().size() - 1; i++) { for (int i = 0; i < ring.getVertices().size() - 1; i++) {
Vertex v1 = ring.getVertices().get(i); Vertex v1 = ring.getVertices().get(i);
Vertex v2 = ring.getVertices().get(i + 1); Vertex v2 = ring.getVertices().get(i + 1);
addLine(v1, v2, Color.ORANGE); addLine(v1, v2, lineColor);
} }
} }
...@@ -172,15 +176,6 @@ public class HighlightController { ...@@ -172,15 +176,6 @@ public class HighlightController {
push(); push();
} }
// /**
// * Clears existing highlights and adds a highlight geometry to a {@link TriangulatedGeometry}.
// * @param p a polygon to highlight
// * @param triGeom the TriangulatedGeometry
// */
// public void highlight(Polygon p, TriangulatedGeometry triGeom) {
// clearHighlights();
// addPolygonHighlight(p, triGeom, Color.RED, Color.BLUE, Color.ORANGE);
// }
// //
// /** // /**
// * Clears existing highlights and adds a highlight geometry to a {@link TriangulatedGeometry}. // * Clears existing highlights and adds a highlight geometry to a {@link TriangulatedGeometry}.
...@@ -340,6 +335,20 @@ public class HighlightController { ...@@ -340,6 +335,20 @@ public class HighlightController {
// } // }
// } // }
/**
// * Clears existing highlights and highlights a collection of edges
// * @param edges a collection of edges to highlight
// * @param triGeom the TriangulatedGeometry
// */
public void highlightEdges(Collection<Edge> edges) {
clearHighlights();
for (Edge e : edges) {
addHighlight(e);
}
push();
}
public void addHighlight(Vertex v, Color c) { public void addHighlight(Vertex v, Color c) {
if (v == null) { if (v == null) {
return; return;
...@@ -347,113 +356,42 @@ public class HighlightController { ...@@ -347,113 +356,42 @@ public class HighlightController {
addPoint(v, c); addPoint(v, c);
push(); push();
} }
/**
* Adds an edge highlight to a {@link TriangulatedGeometry}.
* @param e the polygon to highlight
* @param triGeom the TriangulatedGeometry
* @param pointColor color for the vertex highlights
* @param edgeColor color for the edge highlight
*/
private void addEdgeHighlight(Edge e, TriangulatedGeometry triGeom, Color pointColor, Color edgeColor) {
if (triGeom == null || e == null) {
return;
}
Vector3d movedBy = triGeom.getMovedBy();
addSegmentHighlight(e.getFrom(), e.getTo(), movedBy, edgeColor);
addPointHighlight(movedBy, e.getFrom(), pointColor);
addPointHighlight(movedBy, e.getTo(), pointColor);
}
/** public void highlightPolygons(List<Polygon> polygons) {
* Adds a vertex highlight to a {@link TriangulatedGeometry}.
* @param v the polygon to highlight
* @param triGeom the TriangulatedGeometry
* @param color color for the highlight
*/
public void addVertexHighlight(Vertex v, TriangulatedGeometry triGeom, Color color) {
if (triGeom == null || v == null) {
return;
}
Vector3d movedBy = triGeom.getMovedBy();
addPointHighlight(movedBy, v, color);
}
/**
* Creates a colored point in the JavaFX scenegraph at the relative position of a Vertex within a {@link TriangulatedGeometry}.
* @param movedBy offset vector of the origin of the TriangulatedGeometry
* @param v the vertex to highlight
* @param color color for the highlight
*/
private void addPointHighlight(Vector3d movedBy, Vertex v, Color color) {
Sphere sp = new Sphere(0.5);
sp.setMaterial(new PhongMaterial(color));
sp.setTranslateX(v.getX() - movedBy.getX());
sp.setTranslateY(v.getY() - movedBy.getY());
sp.setTranslateZ(v.getZ() - movedBy.getZ());
sp.setScaleX(scale);
sp.setScaleY(scale);
sp.setScaleZ(scale);
sp.setUserData(new VertexClickDispatcher(v));
points.getChildren().add(sp);
}
/**
* Creates a colored segment in the JavaFX scenegraph at the relative position of an edge within a {@link TriangulatedGeometry}.
* @param v1 start point of the edge
* @param v2 end point of the edge
* @param movedBy offset vector of the origin of the TriangulatedGeometry
* @param color color for the highlight
*/
private void addSegmentHighlight(Vector3d v1, Vector3d v2, Vector3d movedBy, Color color) {
Point3D origin = new Point3D(v1.getX() - movedBy.getX(), v1.getY() - movedBy.getY(),
v1.getZ() - movedBy.getZ());
Point3D target = new Point3D(v2.getX() - movedBy.getX(), v2.getY() - movedBy.getY(),
v2.getZ() - movedBy.getZ());
Point3D yAxis = new Point3D(0, 1, 0);
Point3D diff = target.subtract(origin);
double height = diff.magnitude();
Point3D mid = target.midpoint(origin);
Translate moveToMidpoint = new Translate(mid.getX(), mid.getY(), mid.getZ());
Point3D axisOfRotation = diff.crossProduct(yAxis);
double angle = Math.acos(diff.normalize().dotProduct(yAxis));
Rotate rotateAroundCenter = new Rotate(-Math.toDegrees(angle), axisOfRotation);
Cylinder cy = new Cylinder(scale / 10, height);
cy.setMaterial(new PhongMaterial(color));
cy.getTransforms().addAll(moveToMidpoint, rotateAroundCenter);
edges.getChildren().add(cy);
}
public void highlightEdges(List<Edge> errorEdges) {
resetBuffers(); resetBuffers();
for (Edge e : errorEdges) { for (Polygon p : polygons) {
addHighlight(e); addHighlight(p);
} }
push(); push();
} }
public void addPolygonSkeletonHighlight(Polygon p) {
if (p == null) {
return;
}
addHighlight(p.getExteriorRing(), Color.GRAY, Color.LIGHTGRAY);
for (LinearRing intRing : p.getInnerRings()) {
addHighlight(intRing, Color.DARKGRAY, Color.LIGHTGRAY);
}
push();
}
/** /**
* Adds a gray wireframe highlight of a CityObject to a {@link TriangulatedGeometry} to allow for unobtrusive * Adds a gray wireframe highlight of a CityObject to allow for unobtrusive
* highlighting/display of objects. * highlighting/display of objects.
* @param candidate the candidate feature * @param candidate the candidate feature
* @param triGeom the TriangulatedGeometry
*/ */
public void addSkeletonHighlight(CityObject candidate, TriangulatedGeometry triGeom) { public void addObjectSkeletonHighlight(CityObject candidate) {
candidate.accept(new CheckableUtilsVisitor() { candidate.accept(new CheckableUtilsVisitor() {
@Override @Override
public void check(Geometry geom) { public void check(Geometry geom) {
geom.getPolygons().forEach(p -> { geom.getPolygons().forEach(p -> addPolygonSkeletonHighlight(p));
addPolygonHighlight(p, triGeom, Color.GRAY, Color.GRAY, Color.DARKGRAY);
});
} }
}); });
push();
} }
public void highlightPolygons(List<List<Polygon>> components) { public void highlightPolygonClusters(List<List<Polygon>> components) {
resetBuffers(); resetBuffers();
for (int i = 0; i < components.size(); i++) { for (int i = 0; i < components.size(); i++) {
Color extColor; Color extColor;
...@@ -479,44 +417,45 @@ public class HighlightController { ...@@ -479,44 +417,45 @@ public class HighlightController {
} }
push(); push();
} }
public void addObjectHighlight(CityObject object, TriangulatedGeometry triGeom) {
public void addObjectHighlight(CityObject object) {
object.accept(new CheckableUtilsVisitor() { object.accept(new CheckableUtilsVisitor() {
@Override @Override
public void check(Geometry geom) { public void check(Geometry geom) {
geom.getPolygons().forEach(p -> { geom.getPolygons().forEach(p -> addHighlight(p));
addPolygonHighlight(p, triGeom);
});
} }
}); });
} }
/**
* Adds a polygon highlight to a {@link TriangulatedGeometry}.
* @param p the polygon to highlight public void addCandidatePolygonHighlight(Polygon p) {
* @param triGeom the TriangulatedGeometry if (p == null) {
*/ return;
public void addPolygonHighlight(Polygon p, TriangulatedGeometry triGeom) { }
addPolygonHighlight(p, triGeom, Color.RED, Color.BLUE, Color.ORANGE); addHighlight(p.getExteriorRing(), Color.DARKRED, Color.ROSYBROWN);
} for (LinearRing intRing : p.getInnerRings()) {
addHighlight(intRing, Color.NAVY, Color.ROSYBROWN);
}
push();
}
/** /**
* Adds a polygon highlight to a {@link TriangulatedGeometry}, using darker colors to differentiate candidate polygons. * Adds a polygon highlight using darker colors to differentiate candidate polygons.
* @param p the polygon to highlight * @param p the polygon to highlight
* @param triGeom the TriangulatedGeometry
*/ */
public void addCandidateHighlight(Polygon p, TriangulatedGeometry triGeom) { public void addCandidateHighlight(Polygon p) {
addPolygonHighlight(p, triGeom, Color.DARKRED, Color.NAVY, Color.ROSYBROWN); addCandidatePolygonHighlight(p);
} }
/** /**
* Adds highlights for a collection of polygons to a {@link TriangulatedGeometry}, using darker colors to * Adds highlights for a collection of polygons using darker colors to
* differentiate candidate polygons. * differentiate candidate polygons.
* @param polys the polygons to highlight * @param polys the polygons to highlight
* @param triGeom the TriangulatedGeometry
*/ */
public void addCandidateHighlight(Collection<Polygon> polys, TriangulatedGeometry triGeom) { public void addCandidateHighlight(Collection<Polygon> polys) {
for (Polygon p : polys) { for (Polygon p : polys) {
addCandidateHighlight(p, triGeom); addCandidateHighlight(p);
} }
} }
...@@ -525,16 +464,15 @@ public class HighlightController { ...@@ -525,16 +464,15 @@ public class HighlightController {
push(); push();
} }
/** /**
* Clears existing highlights and highlights polygons within a {@link TriangulatedGeometry}, which were found to be * Clears existing highlights and highlights polygons which were found to be
* colliding by the feature collision check. Darker colors will be used for differentiating the candidate polygons. * colliding by the feature collision check. Darker colors will be used for differentiating the candidate polygons.
* *
* @param collRecord the collision record of the check * @param collRecord the collision record of the check
* @param triGeom the TriangulatedGeometry
*/ */
public void highlightGeometryCollisions(CollisionRecord collRecord, TriangulatedGeometry triGeom) { public void highlightGeometryCollisions(CollisionRecord collRecord) {
Map<Polygon, List<Polygon>> collisionMap = collRecord.collisionMap(); Map<Polygon, List<Polygon>> collisionMap = collRecord.collisionMap();
Set<Polygon> collidingPolys = collisionMap.values().stream().flatMap(List::stream).collect(Collectors.toSet()); Set<Polygon> collidingPolys = collisionMap.values().stream().flatMap(List::stream).collect(Collectors.toSet());
highlightTopoPolygonGroups(collisionMap.keySet(), collidingPolys, triGeom); highlightTopoPolygonGroups(collisionMap.keySet(), collidingPolys);
} }
public void highlight(Triangle3d t) { public void highlight(Triangle3d t) {
...@@ -544,30 +482,29 @@ public class HighlightController { ...@@ -544,30 +482,29 @@ public class HighlightController {
push(); push();
} }
/** /**
* Clears existing highlights and highlight a polygon pair within a {@link TriangulatedGeometry}, which were found to * Clears existing highlights and highlight a polygon pair found to be conflicting a topological requirement.
* be conflicting a topological requirement. Darker colors will be used for differentiating the candidate polygon. * Darker colors will be used for differentiating the candidate polygon.
* *
* @param subject the subject polygon * @param subject the subject polygon
* @param candidate the candidate polygon * @param candidate the candidate polygon
* @param triGeom the TriangulatedGeometry
*/ */
public void highlightTopoPolygonPair(Polygon subject, Polygon candidate,TriangulatedGeometry triGeom) { public void highlightTopoPolygonPair(Polygon subject, Polygon candidate) {
highlight(subject, triGeom); highlight(subject);
addCandidateHighlight(candidate, triGeom); addCandidateHighlight(candidate);
} }
/** /**
* Clears existing highlights and highlights polygons {@link TriangulatedGeometry} which were found to * Clears existing highlights and highlights polygons which were found to
* be conflicting a topological requirement. Darker colors will be used for differentiating the candidate polygons. * be conflicting a topological requirement. Darker colors will be used for differentiating the candidate polygons.
* *
* @param subjectPolys the subject polygons * @param subjectPolys the subject polygons
* @param candidatePolys the candidate polygons * @param candidatePolys the candidate polygons
* @param triGeom the TriangulatedGeometry
*/ */
public void highlightTopoPolygonGroups(Collection<Polygon> subjectPolys, Collection<Polygon> candidatePolys, public void highlightTopoPolygonGroups(Collection<Polygon> subjectPolys, Collection<Polygon> candidatePolys) {
TriangulatedGeometry triGeom) { resetBuffers();
highlightPolygons(subjectPolys, triGeom); subjectPolys.forEach(this::addHighlight);
addCandidateHighlight(candidatePolys, triGeom); addCandidateHighlight(candidatePolys);
push();
} }
......
...@@ -78,7 +78,7 @@ public class ListErrorVisitor implements ErrorVisitor { ...@@ -78,7 +78,7 @@ public class ListErrorVisitor implements ErrorVisitor {
@Override @Override
public void visit(MultipleConnectedComponentsError err) { public void visit(MultipleConnectedComponentsError err) {
controller.highlightPolygons(err.getComponents()); controller.highlightPolygonClusters(err.getComponents());
} }
@Override @Override
...@@ -91,7 +91,7 @@ public class ListErrorVisitor implements ErrorVisitor { ...@@ -91,7 +91,7 @@ public class ListErrorVisitor implements ErrorVisitor {
@Override @Override
public void visit(NonManifoldVertexError err) { public void visit(NonManifoldVertexError err) {
controller.highlightPolygons(err.getComponents()); controller.highlightPolygonClusters(err.getComponents());
controller.addHighlight(err.getVertex(), Color.BLUEVIOLET); controller.addHighlight(err.getVertex(), Color.BLUEVIOLET);
} }
...@@ -304,7 +304,7 @@ public class ListErrorVisitor implements ErrorVisitor { ...@@ -304,7 +304,7 @@ public class ListErrorVisitor implements ErrorVisitor {
@Override @Override
public void visit(FeatureCollisionError err){ public void visit(FeatureCollisionError err){
// controller.highlightGeometryCollisions(err.getCollisionRecord(), geom); controller.highlightGeometryCollisions(err.getCollisionRecord());
//TODO: Implement handling of error here //TODO: Implement handling of error here
} }
......
...@@ -427,45 +427,29 @@ public class Renderer { ...@@ -427,45 +427,29 @@ public class Renderer {
public void highlightTopoErrorGeometry(Geometry geom, boolean isCandidate) { public void highlightTopoErrorGeometry(Geometry geom, boolean isCandidate) {
// TODO: Rework to opengl // TODO: Rework to opengl
// if (isCandidate) { if (isCandidate) {
// highlightController.clearHighlights(); highlightController.clearHighlights();
// highlightController.addCandidateHighlight(geom.getPolygons(), currentTriGeom); highlightController.addCandidateHighlight(geom.getPolygons());
// } else { } else {
// highlightController.highlightPolygons(geom.getPolygons(), currentTriGeom); highlightController.highlight(geom);
// } }
}
public void highlightTopoErrorPolygon(Polygon polygon, boolean isCandidate) {
// TODO: Rework to opengl
// if(isCandidate) {
// highlightController.clearHighlights();
// highlightController.addCandidateHighlight(polygon, currentTriGeom);
// } else {
// highlightController.highlight(polygon, currentTriGeom);
// }
} }
public void highlightTopoErrorPolygons(Collection<Polygon> subjects, Collection<Polygon> candidates) {
// TODO: Rework to opengl
// highlightController.highlightPolygons(subjects, currentTriGeom);
// highlightController.addCandidateHighlight(candidates, currentTriGeom);
}
public void highlightTopoErrorPolygons(Polygon subject, Collection<Polygon> candidates) { public void highlightTopoErrorPolygons(Polygon subject, Collection<Polygon> candidates) {
// TODO: Rework to opengl // TODO: Rework to opengl
// highlightController.highlight(subject, currentTriGeom); highlightController.highlight(subject);
// highlightController.addCandidateHighlight(candidates, currentTriGeom); highlightController.addCandidateHighlight(candidates);
} }
public void highlightTopoErrorPolygons(Polygon subject, Polygon candidate) { public void highlightTopoErrorPolygons(Polygon subject, Polygon candidate) {
// TODO: Rework to opengl highlightController.highlight(subject);
// highlightController.highlight(subject, currentTriGeom); highlightController.addCandidateHighlight(candidate);
// highlightController.addCandidateHighlight(candidate, currentTriGeom);
} }
public void addCandidateSkeletonHighlight(GmlId candidateId){ public void addCandidateSkeletonHighlight(GmlId candidateId){
// TODO: Rework to opengl // TODO: Rework to opengl
// highlightController.addSkeletonHighlight(mainWindow.retrieveCityObject(candidateId), currentTriGeom); highlightController.addObjectSkeletonHighlight(mainWindow.retrieveCityObject(candidateId));
} }
public void highlight(Polygon p) { public void highlight(Polygon p) {
...@@ -488,17 +472,7 @@ public class Renderer { ...@@ -488,17 +472,7 @@ public class Renderer {
highlightController.highlight(highlightedRings); highlightController.highlight(highlightedRings);
} }
public void highlightEdges(List<Edge> edges) {
highlightController.highlightEdges(edges);
}
public void highlightPolygons(List<List<Polygon>> components) {
highlightController.highlightPolygons(components);
}
public void addHighlight(Vertex vertex, Color c) {
highlightController.addHighlight(vertex, c);
}
public void highlight(CheckError err) { public void highlight(CheckError err) {
err.accept(errVisitor); err.accept(errVisitor);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment