Commit 5d40c7b6 authored by Matthias Betz's avatar Matthias Betz
Browse files

CityDoctor2 validation open source release

parents
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class UnitVector2d extends Vector2d {
public static UnitVector2d convertFrom(Vector2d v) {
double length = v.getLength();
double x = v.getX() / length;
double y = v.getY() / length;
return new UnitVector2d(x, y);
}
private UnitVector2d(double x, double y) {
super(x, y);
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class UnitVector3d extends Vector3d {
public static UnitVector3d of(Vector3d vec) {
UnitVector3d unitVec = new UnitVector3d(vec.getX(), vec.getY(), vec.getZ());
unitVec.normalize();
return unitVec;
}
public static UnitVector3d of(double x, double y, double z) {
double length = Math.sqrt(x * x + y * y + z * z);
return new UnitVector3d(x / length, y / length, z / length);
}
private UnitVector3d(double x, double y, double z) {
super(x, y, z);
}
public double dot(UnitVector3d other) {
double scalar = getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ();
if (scalar > 1.0) {
return 1.0;
}
if (scalar < -1.0) {
return -1.0;
}
return scalar;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
public class Vector2d {
private double x;
private double y;
public Vector2d(double x, double y) {
this.x = x;
this.y = y;
}
public Vector2d getPerpendicularVector() {
return new Vector2d(y, -x);
}
public double dot(Vector2d other) {
return (getX() * other.getX() + getY() * other.getY());
}
public Vector2d mult(double scalar) {
return new Vector2d(x * scalar, y * scalar);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public UnitVector2d normalize() {
return UnitVector2d.convertFrom(this);
}
public double getLength() {
return Math.sqrt(getLength2());
}
public double getLength2() {
return x * x + y * y;
}
@Override
public String toString() {
return "Vector2d [x=" + x + ", y=" + y + "]";
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.Arrays;
public class Vector3d {
private double[] val = new double[3];
public Vector3d(double x, double y, double z) {
val[0] = x;
val[1] = y;
val[2] = z;
}
public Vector3d(Point3d point) {
this(point.getX(), point.getY(), point.getZ());
}
public double getLength() {
double value = val[0] * val[0] + val[1] * val[1] + val[2] * val[2];
return Math.sqrt(value);
}
public void normalize() {
double length = getLength();
if (length < Global.getHighAccuracyTolerance()) {
val[0] = 0;
val[1] = 0;
val[2] = 0;
} else {
val[0] = val[0] /= length;
val[1] = val[1] /= length;
val[2] = val[2] /= length;
}
}
public Vector3d cross(Vector3d crV2) {
return new Vector3d(getY() * crV2.getZ() - crV2.getY() * getZ(), getZ() * crV2.getX() - crV2.getZ() * getX(),
getX() * crV2.getY() - crV2.getX() * getY());
}
public UnitVector3d toUnitVector() {
return UnitVector3d.of(this);
}
public Vector3d mult(double d) {
return new Vector3d(val[0] * d, val[1] * d, val[2] * d);
}
public Vector3d plus(Vector3d other) {
return new Vector3d(getX() + other.getX(), getY() + other.getY(), getZ() + other.getZ());
}
public double getX() {
return val[0];
}
public double getY() {
return val[1];
}
public double getZ() {
return val[2];
}
public double getLength2() {
return val[0] * val[0] + val[1] * val[1] + val[2] * val[2];
}
public double dot(Vector3d crVector) {
return this.val[0] * crVector.getX() + this.val[1] * crVector.getY() + this.val[2] * crVector.getZ();
}
public static boolean areParallel(Vector3d crV1, Vector3d crV2, double angleEpsilon) {
return Math.abs((crV1.dot(crV2)) - (crV1.getLength() * crV2.getLength())) < angleEpsilon;
}
public static boolean areAntiParallel(Vector3d crV1, Vector3d crV2, double angleEpsilon) {
return Math.abs((crV1.dot(crV2)) + (crV1.getLength() * crV2.getLength())) < angleEpsilon;
}
public static boolean areAntiParallel(Vector3d rDir1, Vector3d rDir2) {
return areAntiParallel(rDir1, rDir2, Global.getTolVectorsParallel());
}
public static boolean areParallel(Vector3d rDir1, Vector3d rDir2) {
return areParallel(rDir1, rDir2, Global.getTolVectorsParallel());
}
public double[] toArray() {
return Arrays.copyOf(val, 3);
}
@Override
public String toString() {
return "Vector3d [val=" + Arrays.toString(val) + "]";
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.edge;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.Test;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
public class MeshSurfaceUtilsTest {
@Test
public void testIntersectionTwoTrianglesOneSharedEdgeInPlane() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 0);
Vertex v2 = new Vertex(10, 0, 0);
Vertex v3 = new Vertex(10, 10, 0);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v4 = new Vertex(0, 10, 0);
ext.addVertex(v1);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = polygons.get(0);
List<Coordinate3d> coordinates = edgePoly1.getCoordinates();
assertEquals(3, coordinates.size());
Coordinate3d coord1 = coordinates.get(0);
assertEquals(0, coord1.getPoint().getX(), 0.0000001);
assertEquals(0, coord1.getPoint().getY(), 0.0000001);
assertEquals(0, coord1.getPoint().getZ(), 0.0000001);
List<HalfEdge> parents = coord1.getParents(HalfEdge.class);
assertEquals(4, parents.size());
Coordinate3d coord2 = coordinates.get(1);
assertEquals(10, coord2.getPoint().getX(), 0.0000001);
assertEquals(0, coord2.getPoint().getY(), 0.0000001);
assertEquals(0, coord2.getPoint().getZ(), 0.0000001);
Coordinate3d coord3 = coordinates.get(2);
assertEquals(10, coord3.getPoint().getX(), 0.0000001);
assertEquals(10, coord3.getPoint().getY(), 0.0000001);
assertEquals(0, coord3.getPoint().getZ(), 0.0000001);
List<HalfEdge> halfEdges = edgePoly1.getHalfEdges();
assertEquals(3, halfEdges.size());
List<HalfEdge> children = edgePoly1.getChildren(HalfEdge.class);
assertEquals(3, children.size());
HalfEdge firstHalfEdge = edgePoly1.getFirstHalfEdge();
Coordinate3d start = firstHalfEdge.getStart();
assertEquals(0, start.getPoint().getX(), 0.0000001);
assertEquals(0, start.getPoint().getY(), 0.0000001);
assertEquals(0, start.getPoint().getZ(), 0.0000001);
EdgePolygon polygon = firstHalfEdge.getPolygon();
assertNotNull(polygon);
Coordinate3d end = firstHalfEdge.getEnd();
assertEquals(10, end.getPoint().getX(), 0.0000001);
assertEquals(0, end.getPoint().getY(), 0.0000001);
assertEquals(0, end.getPoint().getZ(), 0.0000001);
HalfEdge partner = firstHalfEdge.getPartner();
assertNull(partner);
HalfEdge next = firstHalfEdge.getNext();
start = next.getStart();
assertSame(start, end);
end = next.getEnd();
assertEquals(10, end.getPoint().getX(), 0.0000001);
assertEquals(10, end.getPoint().getY(), 0.0000001);
assertEquals(0, end.getPoint().getZ(), 0.0000001);
HalfEdge next2 = next.getNext();
HalfEdge partner2 = next2.getPartner();
assertNotNull(partner2);
assertSame(partner2.getStart(), next2.getEnd());
assertSame(partner2.getEnd(), next2.getStart());
assertSame(partner2.getPartner(), next2);
start = next2.getStart();
assertSame(start, end);
HalfEdge next3 = next2.getNext();
assertSame(firstHalfEdge, next3);
List<Coordinate3d> coordChildren = firstHalfEdge.getChildren(Coordinate3d.class);
assertEquals(2, coordChildren.size());
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsTwoSharedEdges() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 0);
Vertex v2 = new Vertex(10, 0, 0);
Vertex v3 = new Vertex(10, 10, 0);
Vertex v4 = new Vertex(5, 10, 0);
Vertex v5 = new Vertex(5, 5, 0);
Vertex v6 = new Vertex(0, 5, 0);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v7 = new Vertex(0, 10, 0);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v7);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsOneSharedEdgeIntersectionPolygonPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 0);
Vertex v2 = new Vertex(10, 0, 0);
Vertex v3 = new Vertex(10, 10, 0);
Vertex v4 = new Vertex(5, 10, 0);
Vertex v5 = new Vertex(5, 5, 0);
Vertex v6 = new Vertex(0, 5, 0);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v7 = new Vertex(0, 10, 0);
v6 = new Vertex(0, 4, 0);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v7);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertEquals(1, intersectPolygons.size());
PolygonPolygonIntersection in = intersectPolygons.get(0);
assertEquals(IntersectionType.PARTIALLY_EMBEDDED_POLYGON, in.getIntersectionType());
PolyLine polyLine = in.getPolyLine();
PolyLineSegment firstSegment = polyLine.getFirstSegment();
Point3d start = firstSegment.getStart().getPoint();
assertEquals(0, start.getX(), 0.0000001);
assertEquals(5, start.getY(), 0.0000001);
assertEquals(0, start.getZ(), 0.0000001);
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertEquals(1, intersectPolygons.size());
in = intersectPolygons.get(0);
assertEquals(IntersectionType.PARTIALLY_EMBEDDED_POLYGON, in.getIntersectionType());
}
@Test
public void testIntersectionTwoPolygonsOneSharedEdgeCloseEdgePlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 0);
Vertex v2 = new Vertex(10, 0, 0);
Vertex v3 = new Vertex(10, 10, 0);
Vertex v4 = new Vertex(5, 10, 0);
Vertex v5 = new Vertex(5, 5, 0);
Vertex v6 = new Vertex(0, 5, 0);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v7 = new Vertex(0, 10, 0);
v6 = new Vertex(0, 5.0000001, 0);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v7);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsOneSharedEdgeNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 0);
Vertex v2 = new Vertex(10, 0, 0);
Vertex v3 = new Vertex(10, 10, 0);
Vertex v4 = new Vertex(5, 10, 0);
Vertex v5 = new Vertex(5, 5, 0);
Vertex v6 = new Vertex(0, 5, 0);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v7 = new Vertex(0, 10, 5);
v6 = new Vertex(0, 5, 5);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v7);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsOneSharedPointNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(5, 10, 1);
Vertex v5 = new Vertex(5, 5, 1);
Vertex v6 = new Vertex(0, 5, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
v6 = new Vertex(0, 5, 5);
v5 = new Vertex(8, 4, 0);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
}
@Test
public void testIntersectionTwoPolygonsTouchingInOnePointNoIntersectionNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(5, 10, 1);
Vertex v5 = new Vertex(5, 5, 1);
Vertex v6 = new Vertex(0, 5, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
v6 = new Vertex(0, 5, 5);
v5 = new Vertex(4, 6, 1);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsNotInSamePlaneBelow() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(5, 10, 1);
Vertex v5 = new Vertex(5, 5, 1);
Vertex v6 = new Vertex(0, 5, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
v6 = new Vertex(0, 5, 0);
v5 = new Vertex(4, 5, 0);
v4 = new Vertex(5, 10, 0);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsNotInSamePlaneAbove() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(5, 10, 1);
Vertex v5 = new Vertex(5, 5, 1);
Vertex v6 = new Vertex(0, 5, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
v6 = new Vertex(0, 5, 2);
v5 = new Vertex(4, 5, 2);
v4 = new Vertex(5, 10, 2);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsNotInSamePlaneAboveInverted() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(5, 10, 1);
Vertex v5 = new Vertex(5, 5, 1);
Vertex v6 = new Vertex(0, 5, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
v6 = new Vertex(0, 5, 2);
v5 = new Vertex(4, 5, 2);
v4 = new Vertex(5, 10, 2);
ext.addVertex(v6);
ext.addVertex(v4);
ext.addVertex(v5);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsTouchingNoPointsSameNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v6 = new Vertex(0, 5, 5);
Vertex v5 = new Vertex(4, 5, 1.00000000001);
v4 = new Vertex(5, 10, 1.00000000001);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
}
@Test
public void testIntersectionTwoPolygonsTouchingEdgeNoPointsSameNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v6 = new Vertex(0, 5, 1);
Vertex v5 = new Vertex(0, 5.0000000001, 1);
v4 = new Vertex(-5, 10, 5);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
}
@Test
public void testIntersectionTwoPolygonsTouchingEdgeInPointNoPointsSameNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v6 = new Vertex(0, 5, 1);
Vertex v5 = new Vertex(-4, 6, 5);
v4 = new Vertex(-5, 10, 5);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
}
@Test
public void testIntersectionTwoPolygonsTwoTouchingEdgesNotPlanar() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v6 = new Vertex(0, 5, 0);
Vertex v5 = new Vertex(0, 5, 5);
v4 = new Vertex(-5, 10, 5);
ext.addVertex(v6);
ext.addVertex(v5);
ext.addVertex(v4);
ext.addVertex(v6);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertFalse(intersectPolygons.isEmpty());
for (PolygonPolygonIntersection in : intersectPolygons) {
assertEquals(IntersectionType.NORMAL_INTERSECTION, in.getIntersectionType());
}
}
@Test
public void testIntersectionTwoPolygonsPlanarInnerRingsContained() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
LinearRing inner = new LinearRing(LinearRingType.INTERIOR);
p1.addInteriorRing(inner);
Vertex v11 = new Vertex(2, 2, 1);
Vertex v12 = new Vertex(2, 8, 1);
Vertex v13 = new Vertex(8, 8, 1);
Vertex v14 = new Vertex(8, 2, 1);
inner.addVertex(v11);
inner.addVertex(v14);
inner.addVertex(v13);
inner.addVertex(v12);
inner.addVertex(v11);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v5 = new Vertex(3, 3, 1);
Vertex v6 = new Vertex(3, 7, 1);
Vertex v7 = new Vertex(7, 7, 1);
Vertex v8 = new Vertex(7, 3, 1);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v7);
ext.addVertex(v8);
ext.addVertex(v5);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsPlanarInnerRingsContainedConnected() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
LinearRing inner = new LinearRing(LinearRingType.INTERIOR);
p1.addInteriorRing(inner);
Vertex v11 = new Vertex(2, 2, 1);
Vertex v12 = new Vertex(2, 8, 1);
Vertex v13 = new Vertex(8, 8, 1);
Vertex v14 = new Vertex(8, 2, 1);
inner.addVertex(v11);
inner.addVertex(v14);
inner.addVertex(v13);
inner.addVertex(v12);
inner.addVertex(v11);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
ext.addVertex(v11);
ext.addVertex(v12);
ext.addVertex(v13);
ext.addVertex(v14);
ext.addVertex(v11);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsInnerRingsConnected() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
LinearRing inner = new LinearRing(LinearRingType.INTERIOR);
p1.addInteriorRing(inner);
Vertex v11 = new Vertex(2, 2, 1);
Vertex v12 = new Vertex(2, 8, 1);
Vertex v13 = new Vertex(8, 8, 1);
Vertex v14 = new Vertex(8, 2, 1);
inner.addVertex(v11);
inner.addVertex(v14);
inner.addVertex(v13);
inner.addVertex(v12);
inner.addVertex(v11);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v7 = new Vertex(7, 7, 5);
Vertex v8 = new Vertex(7, 3, 5);
ext.addVertex(v11);
ext.addVertex(v12);
ext.addVertex(v7);
ext.addVertex(v8);
ext.addVertex(v11);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
@Test
public void testIntersectionTwoPolygonsInnerRingsThroughHole() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Polygon p1 = new ConcretePolygon();
geom.addPolygon(p1);
LinearRing ext = new LinearRing(LinearRingType.EXTERIOR);
p1.setExteriorRing(ext);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(10, 0, 1);
Vertex v3 = new Vertex(10, 10, 1);
Vertex v4 = new Vertex(0, 10, 1);
ext.addVertex(v1);
ext.addVertex(v2);
ext.addVertex(v3);
ext.addVertex(v4);
ext.addVertex(v1);
LinearRing inner = new LinearRing(LinearRingType.INTERIOR);
p1.addInteriorRing(inner);
Vertex v11 = new Vertex(2, 2, 1);
Vertex v12 = new Vertex(2, 8, 1);
Vertex v13 = new Vertex(8, 8, 1);
Vertex v14 = new Vertex(8, 2, 1);
inner.addVertex(v11);
inner.addVertex(v14);
inner.addVertex(v13);
inner.addVertex(v12);
inner.addVertex(v11);
Polygon p2 = new ConcretePolygon();
geom.addPolygon(p2);
ext = new LinearRing(LinearRingType.EXTERIOR);
p2.setExteriorRing(ext);
Vertex v5 = new Vertex(3, 3, 0);
Vertex v6 = new Vertex(3, 7, 0);
Vertex v7 = new Vertex(7, 7, 5);
Vertex v8 = new Vertex(7, 3, 5);
ext.addVertex(v5);
ext.addVertex(v6);
ext.addVertex(v7);
ext.addVertex(v8);
ext.addVertex(v5);
MeshSurface meshSurface = MeshSurface.of(geom);
List<CDPolygonNs> polygons = meshSurface.getPolygons();
assertEquals(2, polygons.size());
CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0);
CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1);
List<PolygonPolygonIntersection> intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly1, edgePoly2, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
intersectPolygons = IntersectPlanarPolygons.intersectPolygons(edgePoly2, edgePoly1, 0.000001, 0.001);
assertNotNull(intersectPolygons);
assertTrue(intersectPolygons.isEmpty());
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
<version>3.7.0-SNAPSHOT</version>
</parent>
<artifactId>CityDoctorModel</artifactId>
<name>CityDoctorModel</name>
<dependencies>
<dependency>
<groupId>org.citygml4j</groupId>
<artifactId>citygml4j</artifactId>
</dependency>
<dependency>
<groupId>org.citygml4j.ade</groupId>
<artifactId>energy-ade-citygml4j</artifactId>
</dependency>
<dependency>
<groupId>gov.nist.math</groupId>
<artifactId>jama</artifactId>
</dependency>
<dependency>
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-main</artifactId>
</dependency>
<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.osgeo</groupId>
<artifactId>proj4j</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.check.error.DependenciesNotMetError;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingInstallation;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingPart;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.LandObject;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Opening;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation;
import de.hft.stuttgart.citydoctor2.datastructure.WaterObject;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
/**
* The general check class containing the methods which will be called by check
* engine. To create a new check override one or more check(...) methods and
* implement the {@link Check#getApplicableToClasses()} method by returning a
* list of classes you wish to check. CheckResult objects can be attached to
* every Checkable. If the check has parameters override the
* {@link Check#init(Map, ParserConfiguration)} method to get the value of a
* parameter if a user has specified one in the validation plan. It will be
* contained in the Map as a string. If you have parameters you will need to
* override the {@link Check#getDefaultParameter()} method as well to declare
* which parameters you have, which name and default value they have. The name
* will be the key for the Map in the init method previously mentioned. If your
* check has dependencies you can declare them in the
* {@link Check#getDependencies()} method. Be sure not to create cyclic
* dependencies as that would result in undefined behavior.
*
* @author Matthias Betz
*
*/
public abstract class Check {
private CheckId id;
public Check(CheckId id) {
this.id = id;
}
/**
* Returns all classes for which the check needs to be executed
*
* @return a list of classes which the check applies to
*/
public abstract List<Class<? extends Checkable>> getApplicableToClasses();
/**
* A list of dependencies which the check depends on. Each of those dependencies
* needs to be executed and must have reported no error before this check can be
* executed.
*
* @return a list of CheckIds which the check depends on.
*/
public List<CheckId> getDependencies() {
return Collections.emptyList();
}
/**
* Getter for the check id.
*
* @return the check id.
*/
public CheckId getCheckId() {
return id;
}
/**
* Getter for the check type.
*
* @return the check type
*/
public abstract CheckType getType();
/**
* Checks whether the check can be executed on this checkable, meaning the
* checkable or its content can not have any error of any check dependent on
* this check. <br>
* If the check cannot be executed a CheckResult will be created with the
* ResultStatus = DEPENDENCIES_NOT_MET.
*
* @param c the checkable
* @param crc container for all check results
* @return true if the check can be executed, false if the checkable itself or
* one of its containing checkables have an error.
*/
public boolean canExecute(Checkable c) {
// ignore objects where this check doesn't apply to
if (!getApplicableToClasses().contains(c.getCheckClass())) {
return false;
}
// check that object doesn't have errors for dependencies of this check
for (CheckId dependencyCheck : getDependencies()) {
boolean hasError = c.containsError(dependencyCheck);
if (hasError) {
// check whether a result was already inserted
if (!c.hasDependencyNotMetError(id)) {
// insert dependency error
CheckError err = new DependenciesNotMetError(dependencyCheck);
CheckResult cr = new CheckResult(this.id, ResultStatus.DEPENDENCIES_NOT_MET, err);
c.addCheckResult(cr);
}
return false;
}
}
return true;
}
/**
* check anything
*
* @param checkable a checkable
*/
public void check(Checkable checkable) {
}
/**
* check buildings and building parts
*
* @param ab building or building part
*/
public void check(AbstractBuilding ab) {
}
/**
* check boundary surfaces
*
* @param bs a boundary surface
*/
public void check(BoundarySurface bs) {
}
/**
* check bridges
*
* @param bo a bridge
*/
public void check(BridgeObject bo) {
}
/**
* check only buildings
*
* @param b a building
*/
public void check(Building b) {
}
/**
* check building installations
*
* @param bi a building installation
*/
public void check(BuildingInstallation bi) {
}
/**
* check only building parts
*
* @param bp a building part
*/
public void check(BuildingPart bp) {
}
/**
* check all city objects
*
* @param co a city object
*/
public void check(CityObject co) {
}
/**
* check land use objects
*
* @param lo a land use object
*/
public void check(LandObject lo) {
}
/**
* check openings
*
* @param o an opening
*/
public void check(Opening o) {
}
/**
* check transportation objects
*
* @param to a transportation object
*/
public void check(TransportationObject to) {
}
/**
* check vegetation objects
*
* @param veg a vegetation object
*/
public void check(Vegetation veg) {
}
/**
* check water objects
*
* @param wo a water object
*/
public void check(WaterObject wo) {
}
/**
* check geometries
*
* @param geom a geometry
*/
public void check(Geometry geom) {
}
/**
* check polygons
*
* @param poly a polygon
*/
public void check(Polygon poly) {
}
/**
* check linear rings
*
* @param ring a linear ring
*/
public void check(LinearRing ring) {
}
/**
* The initialization method of this check. It will be called before any check
* method will be executed. Override this if you want to have configurable
* parameters.
*
* @param params the parameter map containing the parameters for the check in
* String form. The key should be the same String provided by the
* {@link Check#getDefaultParameter()} method
* @param config sometimes there are global parameters which can be used by
* checks. Those are be stored in this container
*/
public void init(Map<String, String> params, ParserConfiguration config) {
}
/**
* This methods gives checks the possibility to declare default parameters, used
* primarily in the GUI.
*
* @return a list of default parameters, not null
*/
public List<DefaultParameter> getDefaultParameter() {
return Collections.emptyList();
}
@Override
public String toString() {
return "Check [id=" + id + "]";
}
/**
* Create a new instance of this check. This is needed to keep the checks
* dynamic
*
* @return a new instance of this check
*/
public abstract Check createNewInstance();
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.io.Serializable;
import java.util.Objects;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
/**
* Abstract container class for all errors. If your check creates a new error,
* implement a new class from this one. This class has entry points for
* reporting, healing and general access, which will need to be implemented to
* properly function.
*
* @author Matthias Betz
*
*/
public abstract class CheckError implements Serializable {
private static final long serialVersionUID = -4428235366383090704L;
private ErrorType type;
private ErrorId id;
private GmlElement feature;
/**
* Necessary information for every error type needs to be provided in this
* constructor.
*
* @param id the error id (not null)
* @param type the error type (not null)
* @param feature element in which the error occurred
*/
public CheckError(ErrorId id, ErrorType type, GmlElement feature) {
Objects.requireNonNull(id, "id may not be null");
Objects.requireNonNull(type, "type may not be null");
this.type = type;
this.id = id;
this.feature = feature;
}
/**
* Getter for the error type
*
* @return the error type
*/
public ErrorType getType() {
return type;
}
/**
* Getter for the error id
*
* @return the error id
*/
public ErrorId getErrorId() {
return id;
}
/**
* The gml feature in which the error occured
*
* @return the gml feature
*/
public GmlElement getFeature() {
return feature;
}
/**
* A general visitor will have a look at this error. Visitor pattern.
*
* @param errorVisitor the visitor, call {@link ErrorVisitor#visit(CheckError)})
* on this.
*/
public abstract void accept(ErrorVisitor errorVisitor);
/**
* Visitor pattern for the healing methods. Call
* {@link HealingMethod#visit(CheckError, ModificationListener)} in the
* implementation and return the boolean.
*
* @param method the healing method visitor
* @param l a modification listener when a healing method changes something
* @return true if the healing method changed something in the model
*/
public abstract boolean accept(HealingMethod method, ModificationListener l);
/**
* This method functions as interface to various reporting places. The
* implementor of the error decides which information is written into the report
* or shown on the GUI.
*
* @param report
*/
public abstract void report(ErrorReport report);
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
public enum CheckId {
C_GE_R_TOO_FEW_POINTS("C_GE_R_TOO_FEW_POINTS"), C_GE_R_NOT_CLOSED("C_GE_R_NOT_CLOSED"),
C_GE_S_MULTIPLE_CONNECTED_COMPONENTS("C_GE_S_MULTIPLE_CONNECTED_COMPONENTS"),
C_GE_R_DUPLICATE_POINT("C_GE_R_DUPLICATE_POINT"), C_GE_R_SELF_INTERSECTION("C_GE_R_SELF_INTERSECTION"),
C_GE_P_INTERIOR_DISCONNECTED("C_GE_P_INTERIOR_DISCONNECTED"),
C_GE_P_INTERSECTING_RINGS("C_GE_P_INTERSECTING_RINGS"), C_GE_P_NON_PLANAR("C_GE_P_NON_PLANAR"),
C_GE_S_TOO_FEW_POLYGONS("C_GE_S_TOO_FEW_POLYGONS"), NULL_AREA("C_GE_R_NULL_AREA"),
C_GE_S_NOT_CLOSED("C_GE_S_NOT_CLOSED"), C_GE_S_NON_MANIFOLD_EDGE("C_GE_S_NON_MANIFOLD_EDGE"),
C_GE_S_POLYGON_WRONG_ORIENTATION("C_GE_S_POLYGON_WRONG_ORIENTATION"),
C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION("C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION"),
C_GE_S_NON_MANIFOLD_VERTEX("C_GE_S_NON_MANIFOLD_VERTEX"), C_GE_S_SELF_INTERSECTION("C_GE_S_SELF_INTERSECTION"),
C_GE_P_HOLE_OUTSIDE("C_GE_P_HOLE_OUTSIDE"), C_GE_P_ORIENTATION_RINGS_SAME("C_GE_P_ORIENTATION_RINGS_SAME"),
C_GE_P_INNER_RINGS_NESTED("C_GE_P_INNER_RINGS_NESTED"), IS_CEILING("IS_CEILING"),
C_SEM_F_MISSING_ID("C_SEM_F_MISSING_ID"), C_SEM_BS_NOT_CEILING("C_SEM_BS_NOT_CEILING"),
C_SEM_BS_NOT_FLOOR("C_SEM_BS_NOT_FLOOR"), C_SEM_BS_NOT_GROUND("C_SEM_BS_NOT_GROUND"),
C_SEM_BS_GROUND_NOT_FRAGMENTED("C_SEM_BS_GROUND_NOT_FRAGMENTED"), C_SEM_BS_IS_WALL("C_SEM_BS_IS_WALL"),
C_SEM_SCHEMATRON("C_SEM_SCHEMATRON"), C_SEM_BS_ROOF_NOT_FRAGMENTED("C_SEM_BS_ROOF_NOT_FRAGMENTED");
private static final Map<String, CheckId> ENUM_MAP;
static {
Map<String, CheckId> map = new TreeMap<>();
for (CheckId instance : CheckId.values()) {
map.put(instance.toString().toUpperCase(), instance);
}
ENUM_MAP = Collections.unmodifiableMap(map);
}
private String id;
private CheckId(String id) {
this.id = id;
}
@Override
public String toString() {
return id;
}
/**
* Converts a String to a check id if possible.
*
* @param checkName the string representation of a check
* @return the check id or null if not found.
*/
public static CheckId getIdForName(String checkName) {
return ENUM_MAP.get(checkName.toUpperCase());
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.io.Serializable;
/**
* Container class for results of a check. It contains a status, the check which
* produced the result and optional an error object if there was one.
*
* @author Matthias Betz
*
*/
public class CheckResult implements Serializable {
private static final long serialVersionUID = -8775678793477525693L;
private final CheckId id;
private final ResultStatus status;
private final CheckError err;
/**
* Constructor for this container
*
* @param c the check which produced this result
* @param s the status of the result
* @param err an optional error object
*/
public CheckResult(CheckId id, ResultStatus s, CheckError err) {
this.id = id;
this.status = s;
this.err = err;
}
public CheckResult(Check check, ResultStatus s, CheckError err) {
this(check.getCheckId(), s, err);
}
public CheckId getCheckIdentifier() {
return id;
}
public ResultStatus getResultStatus() {
return status;
}
public CheckError getError() {
return err;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CheckResult [id=");
builder.append(id);
builder.append(", status=");
builder.append(status);
builder.append(", error=");
builder.append(err);
builder.append("]");
return builder.toString();
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
/**
* There are differences between checks. Some are for geometric checking, others
* for semantic checks. This enumeration is for differentiating between those
* two.
*
* @author Matthias Betz
*
*/
public enum CheckType {
GEOMETRY, SEMANTIC
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.io.Serializable;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
/**
* Interface to indicate that this object can be checked by Checks.
*
* @author Matthias Betz - 12bema1bif@hft-stuttgart.de
*
*/
public abstract class Checkable implements Serializable {
private static final long serialVersionUID = -1707871839265057882L;
private static Logger logger = LogManager.getLogger(Checkable.class);
private EnumMap<CheckId, CheckResult> checkResults = new EnumMap<>(CheckId.class);
private boolean isValidated = false;
protected void setValidated(boolean validated) {
isValidated = validated;
}
public boolean isValidated() {
return isValidated;
}
/**
* This object will be visited by the given check. Indirect implementers have to
* call <code>super.visit()</code> to ensure that every layer of classes is
* correctly checked. This method should call the visit method of each Checkable
* object contained in the implementing class.<br>
* <b>Note:</b> every object should only be visited once, therefore a clear
* structure has to be constructed in order to know which object is contained
* where. For example a Polygon has vertices as references but the actual
* storage location is in Geometry. Therefore only in Geometry the call to visit
* vertices is made.
*
* @param c the check from which the check method is called with the Checkable
* instance as parameter.
*/
public abstract void accept(Check c);
/**
* The GML-ID of the checkable. This is necessary so specific features can be
* excluded via the ID.
*
* @return the GML-ID
*/
public abstract GmlId getGmlId();
/**
* This method checks if the object or any object contained within this
* checkable has an error. It counts as an error if the result status if the
* given check is <code>DEPENDENCIES_NOT_MET<code>.
*
* @param checkIdentifier the name of the check for which an error is searched
* @return true if an error has been found with the given check
*/
public boolean containsError(CheckId checkIdentifier) {
CheckResult cs = getCheckResult(checkIdentifier);
if (cs == null) {
return false;
}
ResultStatus rs = cs.getResultStatus();
return rs == ResultStatus.ERROR || rs == ResultStatus.DEPENDENCIES_NOT_MET;
}
/**
* Returns the check result for the given CheckId
*
* @param id the id
* @return the check result or null if none was found
*/
public CheckResult getCheckResult(CheckId id) {
return checkResults.get(id);
}
/**
* Returns the check result for the given Check.
*
* @param c the check
* @return the check result or null if none was found
*/
public CheckResult getCheckResult(Check c) {
return getCheckResult(c.getCheckId());
}
/**
*
* @return all check results for this checkable.
*/
public Map<CheckId, CheckResult> getAllCheckResults() {
return checkResults;
}
/**
* Checks whether this checkable has a DependencyNotMetError for the given
* CheckId.
*
* @param id the CheckId for which the error is searched.
* @return true if it contains such an error, false if not or no CheckResult is
* available for the given id.
*/
public boolean hasDependencyNotMetError(CheckId id) {
CheckResult cr = checkResults.get(id);
if (cr == null) {
return false;
}
return cr.getResultStatus() == ResultStatus.DEPENDENCIES_NOT_MET;
}
/**
* Checks whether this checkable has an error. Dependency errors are not
* considered for this function. This will only check this checkable and not
* traverse any checkables contained in this instance.
*
* @return true if it has an error, otherwise false
*/
public boolean hasAnyError() {
for (CheckResult cr : checkResults.values()) {
if (cr.getResultStatus() == ResultStatus.ERROR) {
return true;
}
}
return false;
}
/**
* Checks whether any check results have been reported for this checkable
*
* @return true if any checks have reported results, false otherwise
*/
public boolean hasCheckResults() {
return !checkResults.isEmpty();
}
/**
* Adds the result of a check to this checkable.
*
* @param cr the check result
*/
public void addCheckResult(CheckResult cr) {
checkResults.put(cr.getCheckIdentifier(), cr);
if (cr.getResultStatus() == ResultStatus.ERROR) {
logger.debug("{} has found an error of type {}", cr.getCheckIdentifier(), cr.getError().getErrorId());
} else if (cr.getResultStatus() == ResultStatus.WARNING) {
logger.debug("{} has found a warning of type {}", cr.getCheckIdentifier(), cr.getError().getErrorId());
}
}
/**
* Clears all errors from this checkable
*/
public void clearCheckResults() {
setValidated(false);
checkResults.clear();
}
/**
* Removes all errors from this instance and all contained checkables.
*/
public abstract void clearAllContainedCheckResults();
/**
*
* @return false if the checkable or all checkables contained in this one don't
* have any error.
*/
public boolean containsAnyError() {
for (CheckResult cr : checkResults.values()) {
if (cr.getResultStatus() == ResultStatus.ERROR
|| cr.getResultStatus() == ResultStatus.DEPENDENCIES_NOT_MET) {
return true;
}
}
return false;
}
/**
* Collects all errors from this checkable and all contained checkables and adds
* them to the given list. DEPENDENCY_NOT_MET errors are excluded from this.
*
* @param errors the collection in which the errors are added.
*/
public void collectContainedErrors(List<CheckError> errors) {
for (CheckResult cr : checkResults.values()) {
if (cr.getResultStatus() == ResultStatus.ERROR) {
errors.add(cr.getError());
}
}
}
/**
* As which class is this object being tested. This is used when there are
* different implementations for the same object type. For example a polygon can
* be a link to another polygon as well as the polygon which contains the actual
* data. Checks declare which objects they check, which would be Polygon in this
* example. Now there are two kinds of polygons but both are treated as
* polygons.
*
* @return the class for which the object should be treated as.
*/
public Class<? extends Checkable> getCheckClass() {
return getClass();
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
/**
* Describes a parameter for a check including the default value as a String.
* All values are a String as they are passed to the check as a Map<String,
* String>.
*
* @author Matthias Betz
*
*/
public class DefaultParameter {
private String name;
private String defaultValue;
private Unit unitType;
public DefaultParameter(String name, String defaultValue, Unit unitType) {
this.name = name;
this.defaultValue = defaultValue;
this.unitType = unitType;
}
public Unit getUnitType() {
return unitType;
}
/**
* Getter method for name
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Getter method for defaultValue
*
* @return the defaultValue
*/
public String getDefaultValue() {
return defaultValue;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CheckParameter [name=");
builder.append(name);
builder.append(", defaultValue=");
builder.append(defaultValue);
builder.append("]");
return builder.toString();
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
/**
* The error ids of all checks and their respective name, which is used in
* reports and GUI
*
* @author Matthias Betz
*
*/
public enum ErrorId {
DEPENDENCIES_NOT_MET("Dependencies_not_met"), UNKNOWN_ERROR("Unknown_error"), GE_R_NOT_CLOSED("GE_R_NOT_CLOSED"),
GE_S_MULTIPLE_CONNECTED_COMPONENTS("GE_S_MULTIPLE_CONNECTED_COMPONENTS"),
GE_R_CONSECUTIVE_POINTS_SAME("GE_R_CONSECUTIVE_POINTS_SAME"), GE_R_SELF_INTERSECTION("GE_R_SELF_INTERSECTION"),
GE_S_POLYGON_WRONG_ORIENTATION("GE_S_POLYGON_WRONG_ORIENTATION"),
GE_S_ALL_POLYGONS_WRONG_ORIENTATION("GE_S_ALL_POLYGONS_WRONG_ORIENTATION"), GE_P_HOLE_OUTSIDE("GE_P_HOLE_OUTSIDE"),
GE_P_INTERIOR_DISCONNECTED("GE_P_INTERIOR_DISCONNECTED"), GE_S_NON_MANIFOLD_VERTEX("GE_S_NON_MANIFOLD_VERTEX"),
GE_P_INNER_RINGS_NESTED("GE_P_INNER_RINGS_NESTED"), GE_R_NULL_AREA("GE_R_NULL_AREA"),
GE_R_TOO_FEW_POINTS("GE_R_TOO_FEW_POINTS"), GE_S_NON_MANIFOLD_EDGE("GE_S_NON_MANIFOLD_EDGE"),
GE_P_NON_PLANAR_POLYGON_NORMALS_DEVIATION("GE_P_NON_PLANAR_POLYGON_NORMALS_DEVIATION"),
GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE("GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE"),
GE_P_ORIENTATION_RINGS_SAME("GE_P_ORIENTATION_RINGS_SAME"), GE_P_INTERSECTING_RINGS("GE_P_INTERSECTION_RINGS"),
GE_S_NOT_CLOSED("GE_S_NOT_CLOSED"), GE_S_SELF_INTERSECTION("GE_S_SELF_INTERSECTION"),
GE_S_TOO_FEW_POLYGONS("GE_S_TOO_FEW_POLYGONS"), SEM_F_MISSING_ID("SEM_F_MISSING_GML_ID"),
SEM_BS_NOT_CEILING("SEM_BS_NOT_CEILING"), SEM_BS_NOT_WALL("SEM_BS_NOT_WALL"), SEM_BS_NOT_FLOOR("SEM_BS_NOT_FLOOR"),
SEM_BS_NOT_GROUND("SEM_BS_NOT_GROUND"), SEM_SCHEMATRON_ERROR("SEM_SCHEMATRON_ERROR"), SEM_BS_UNFRAGMENTED("SEM_BS_UNFRAGMENTED"), GE_P_TINY_EDGE("GE_P_TINY_EDGE");
private String name;
private ErrorId(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.util.Collection;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
/**
* This is an interface to get information from errors. The errors will call one
* or more methods listed here and the implementation can then handle the
* information given. This is used in reports and the GUI.
*
* @author Matthias Betz
*
*/
public interface ErrorReport {
public void add(Polygon p);
public void add(LinearRing lr);
public void add(Geometry geom);
public void add(Vertex v);
public void add(String name, Vertex v);
public void add(Edge e);
public void add(BoundarySurface bs);
public void add(String name, Edge e);
public void add(String name, int value);
public void add(String name, double value);
public void add(String name, String value);
public void add(String name, Vector3d point);
public void addPolygons(String name, Collection<Polygon> polygons);
public void addEdges(String name, Collection<Edge> edges);
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
/**
* There are two error types, ERROR and WARNING.
*
* @author Matthias Betz
*
*/
public enum ErrorType {
ERROR, WARNING
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import de.hft.stuttgart.citydoctor2.check.error.AllPolygonsWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError;
import de.hft.stuttgart.citydoctor2.check.error.DependenciesNotMetError;
import de.hft.stuttgart.citydoctor2.check.error.DistanceError;
import de.hft.stuttgart.citydoctor2.check.error.DuplicatePointError;
import de.hft.stuttgart.citydoctor2.check.error.EdgeIntersectionError;
import de.hft.stuttgart.citydoctor2.check.error.HoleOutsideError;
import de.hft.stuttgart.citydoctor2.check.error.InteriorDisconnectedError;
import de.hft.stuttgart.citydoctor2.check.error.ManifoldEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.MultipleConnectedComponentsError;
import de.hft.stuttgart.citydoctor2.check.error.NestedRingError;
import de.hft.stuttgart.citydoctor2.check.error.NonManifoldVertexError;
import de.hft.stuttgart.citydoctor2.check.error.NormalDeviationError;
import de.hft.stuttgart.citydoctor2.check.error.NotCeilingError;
import de.hft.stuttgart.citydoctor2.check.error.NotFloorError;
import de.hft.stuttgart.citydoctor2.check.error.NotGroundError;
import de.hft.stuttgart.citydoctor2.check.error.NotWallError;
import de.hft.stuttgart.citydoctor2.check.error.NullAreaError;
import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.RingNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.RingSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.SameOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.check.error.SolidNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.SolidSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceUnfragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.TinyEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPointsError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
/**
* Visitor pattern interface to access errors. This is to determine the type of
* an error without resorting to endless instanceof structures.
*
* @author Matthias Betz
*
*/
public interface ErrorVisitor {
public void visit(HoleOutsideError err);
public void visit(ManifoldEdgeError err);
public void visit(MultipleConnectedComponentsError err);
public void visit(NestedRingError err);
public void visit(NonManifoldVertexError err);
public void visit(PolygonWrongOrientationError err);
public void visit(SameOrientationError err);
public void visit(SolidNotClosedError err);
public void visit(DependenciesNotMetError err);
public void visit(UnknownCheckError err);
public void visit(RingNotClosedError err);
public void visit(ConsecutivePointSameError err);
public void visit(RingSelfIntError err);
public void visit(AllPolygonsWrongOrientationError err);
public void visit(InteriorDisconnectedError err);
public void visit(NullAreaError err);
public void visit(TooFewPointsError err);
public void visit(NormalDeviationError err);
public void visit(DistanceError err);
public void visit(PolygonSelfIntError err);
public void visit(SolidSelfIntError err);
public void visit(TooFewPolygonsError err);
public void visit(DuplicatePointError err);
public void visit(EdgeIntersectionError err);
public void visit(PointTouchesEdgeError err);
public void visit(NotCeilingError err);
public void visit(NotFloorError err);
public void visit(NotWallError err);
public void visit(NotGroundError err);
public void visit(CheckError err);
public void visit(SchematronError err);
public void visit(SurfaceUnfragmentedError err);
public void visit(TinyEdgeError err);
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import java.io.Serializable;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.Triangle3d;
public class GeometrySelfIntersection implements Serializable {
private static final long serialVersionUID = -6308847898942670140L;
private Polygon p1;
private Polygon p2;
private Triangle3d t1;
private Triangle3d t2;
public GeometrySelfIntersection(Polygon p1, Polygon p2, Triangle3d t1, Triangle3d t2) {
super();
this.p1 = p1;
this.p2 = p2;
this.t1 = t1;
this.t2 = t2;
}
public Polygon getP1() {
return p1;
}
public void setP1(Polygon p1) {
this.p1 = p1;
}
public Polygon getP2() {
return p2;
}
public void setP2(Polygon p2) {
this.p2 = p2;
}
public Triangle3d getT1() {
return t1;
}
public Triangle3d getT2() {
return t2;
}
@Override
public String toString() {
return "GeometrySelfIntersection [p1=" + p1 + ", p2=" + p2 + "]";
}
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import de.hft.stuttgart.citydoctor2.check.error.AllPolygonsWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError;
import de.hft.stuttgart.citydoctor2.check.error.DependenciesNotMetError;
import de.hft.stuttgart.citydoctor2.check.error.DistanceError;
import de.hft.stuttgart.citydoctor2.check.error.DuplicatePointError;
import de.hft.stuttgart.citydoctor2.check.error.EdgeIntersectionError;
import de.hft.stuttgart.citydoctor2.check.error.HoleOutsideError;
import de.hft.stuttgart.citydoctor2.check.error.InteriorDisconnectedError;
import de.hft.stuttgart.citydoctor2.check.error.ManifoldEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.MultipleConnectedComponentsError;
import de.hft.stuttgart.citydoctor2.check.error.NestedRingError;
import de.hft.stuttgart.citydoctor2.check.error.NonManifoldVertexError;
import de.hft.stuttgart.citydoctor2.check.error.NormalDeviationError;
import de.hft.stuttgart.citydoctor2.check.error.NotCeilingError;
import de.hft.stuttgart.citydoctor2.check.error.NotFloorError;
import de.hft.stuttgart.citydoctor2.check.error.NotGroundError;
import de.hft.stuttgart.citydoctor2.check.error.NotWallError;
import de.hft.stuttgart.citydoctor2.check.error.NullAreaError;
import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.RingNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.RingSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.SameOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.check.error.SolidNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.SolidSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceUnfragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.TinyEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPointsError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
/**
* Visitor pattern interface used in the healing procedures. The modification
* listener is to report changed polygons and the returned boolean indicates
* that changes have happened.
*
* @author Matthias Betz
*
*/
public interface HealingMethod {
default boolean visit(CheckError e, ModificationListener l) {
return false;
}
default boolean visit(TinyEdgeError e, ModificationListener l) {
return false;
}
default boolean visit(EdgeIntersectionError edgeIntersectionError, ModificationListener l) {
return false;
}
default boolean visit(DuplicatePointError duplicatePointError, ModificationListener l) {
return false;
}
default boolean visit(AllPolygonsWrongOrientationError err, ModificationListener l) {
return false;
}
default boolean visit(DependenciesNotMetError err, ModificationListener l) {
return false;
}
default boolean visit(DistanceError err, ModificationListener l) {
return false;
}
default boolean visit(ConsecutivePointSameError err, ModificationListener l) {
return false;
}
default boolean visit(HoleOutsideError err, ModificationListener l) {
return false;
}
default boolean visit(InteriorDisconnectedError err, ModificationListener l) {
return false;
}
default boolean visit(ManifoldEdgeError err, ModificationListener l) {
return false;
}
default boolean visit(MultipleConnectedComponentsError err, ModificationListener l) {
return false;
}
default boolean visit(NestedRingError err, ModificationListener l) {
return false;
}
default boolean visit(NonManifoldVertexError err, ModificationListener l) {
return false;
}
default boolean visit(NormalDeviationError err, ModificationListener l) {
return false;
}
default boolean visit(NullAreaError err, ModificationListener l) {
return false;
}
default boolean visit(PolygonSelfIntError err, ModificationListener l) {
return false;
}
default boolean visit(PolygonWrongOrientationError err, ModificationListener l) {
return false;
}
default boolean visit(RingNotClosedError err, ModificationListener l) {
return false;
}
default boolean visit(RingSelfIntError err, ModificationListener l) {
return false;
}
default boolean visit(SameOrientationError err, ModificationListener l) {
return false;
}
default boolean visit(SolidNotClosedError err, ModificationListener l) {
return false;
}
default boolean visit(SolidSelfIntError err, ModificationListener l) {
return false;
}
default boolean visit(TooFewPointsError err, ModificationListener l) {
return false;
}
default boolean visit(TooFewPolygonsError err, ModificationListener l) {
return false;
}
default boolean visit(UnknownCheckError err, ModificationListener l) {
return false;
}
default boolean visit(PointTouchesEdgeError err, ModificationListener l) {
return false;
}
default boolean visit(NotCeilingError err, ModificationListener l) {
return false;
}
default boolean visit(NotFloorError err, ModificationListener l) {
return false;
}
default boolean visit(NotWallError err, ModificationListener l) {
return false;
}
default boolean visit(NotGroundError err, ModificationListener l) {
return false;
}
default boolean visit(SchematronError err, ModificationListener l) {
return false;
}
default boolean visit(SurfaceUnfragmentedError err, ModificationListener l) {
return false;
}
public HealingMethod createNew();
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
/**
* Listener used in the healing process to determine which polygons have been
* changed.
*
* @author Matthias Betz
*
*/
public interface ModificationListener {
public void polygonRemoved(Polygon p);
public void polygonAdded(Polygon p);
}
Markdown is supported
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