/*- * 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 . */ 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.Building; import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; 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.parser.CityGmlParseException; import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = polygons.get(0); List 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 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 halfEdges = edgePoly1.getHalfEdges(); assertEquals(3, halfEdges.size()); List 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 coordChildren = firstHalfEdge.getChildren(Coordinate3d.class); assertEquals(2, coordChildren.size()); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 testIntersectionTwoPolygonsOneSharedEdgeIntersectionPolygonPlanar2() { 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(6, 0, 0); Vertex v3 = new Vertex(6, 6, 0); Vertex v4 = new Vertex(0, 6, 0); 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 v5 = new Vertex(10, 0, 0); Vertex v6 = new Vertex(10, 10, 0); Vertex v7 = new Vertex(-2, 10, 0); Vertex v8 = new Vertex(-2, 3, 0); ext.addVertex(v2); ext.addVertex(v5); ext.addVertex(v6); ext.addVertex(v7); ext.addVertex(v8); ext.addVertex(v3); ext.addVertex(v2); MeshSurface meshSurface = MeshSurface.of(geom); List polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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(2, start.getX(), 0.0000001); assertEquals(6, 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); DebugUtils.printGeoknechtPolygon(edgePoly1, edgePoly2); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 testIntersectionTwoPolygonsTouchingInOnePointNoIntersectionNotPlanar2() { 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 v0 = new Vertex(3514751.69, 5405877.02, 252.68); Vertex v1 = new Vertex(3514747.236, 5405875.302, 257.195); Vertex v2 = new Vertex(3514746.319, 5405873.509, 257.394); Vertex v3 = new Vertex(3514744.883, 5405872.908, 258.825); Vertex v4 = new Vertex(3514747.48, 5405866.99, 252.68); ext.addVertex(v0); ext.addVertex(v1); ext.addVertex(v2); ext.addVertex(v3); ext.addVertex(v4); ext.addVertex(v0); Polygon p2 = new ConcretePolygon(); geom.addPolygon(p2); ext = new LinearRing(LinearRingType.EXTERIOR); p2.setExteriorRing(ext); Vertex v5 = new Vertex(3514731.94, 5405873.52, 252.68); Vertex v6 = new Vertex(3514731.94, 5405873.52, 234.54); Vertex v7 = new Vertex(3514747.48, 5405866.99, 234.54); ext.addVertex(v4); ext.addVertex(v5); ext.addVertex(v6); ext.addVertex(v7); ext.addVertex(v4); MeshSurface meshSurface = MeshSurface.of(geom); List polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); DebugUtils.printGeoknechtPolygon(edgePoly1, edgePoly2); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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 polygons = meshSurface.getPolygons(); assertEquals(2, polygons.size()); CDPolygonNs edgePoly1 = meshSurface.getPolygons().get(0); CDPolygonNs edgePoly2 = meshSurface.getPolygons().get(1); List 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(timeout = 10000) public void testKaiserwallComplexBuilding() throws CityGmlParseException, InvalidGmlFileException { ParserConfiguration config = new ParserConfiguration(8, false); CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/KaiserwallComplexBuilding.gml", config); Building building = model.getBuildings().get(0); Geometry geom = building.getBuildingInstallations().get(0).getGeometries().get(0); assertNotNull(geom); MeshSurface surface = MeshSurface.of(geom); List selfIntersects = MeshSurfaceUtils.selfIntersects(surface, 0.000001, 0.001); assertTrue(selfIntersects.isEmpty()); } }