Commit 3032c1f9 authored by Numanoglu's avatar Numanoglu
Browse files

Add synthetic sweep planarity test models

parent cec0e9d5
Pipeline #12402 passed with stage
in 2 minutes and 17 seconds
......@@ -36,6 +36,30 @@ import org.junit.experimental.categories.Category;
public class HealPlanarPolygonErrorTest {
@Test
public void testRaisedTopCornerCubeHasNonPlanarPolygon() {
Building building = SyntheticSweepPlanarityModelFactory.createRaisedTopCornerCube();
Geometry geom = building.getGeometries().get(0);
PlanarCheck check = new PlanarCheck();
geom.accept(check);
check.check(geom);
Assert.assertTrue(geom.containsError(CheckId.C_GE_P_NON_PLANAR));
}
@Test
public void testExistingHealerModelHasNonPlanarPolygon() {
Building building = SyntheticSweepPlanarityModelFactory.createExistingHealerTestModel();
Geometry geom = building.getGeometries().get(0);
PlanarCheck check = new PlanarCheck();
geom.accept(check);
check.check(geom);
Assert.assertTrue(geom.containsError(CheckId.C_GE_P_NON_PLANAR));
}
@Test
public void testPlanarPlaneDistance() throws CityGmlParseException, IOException, InvalidGmlFileException {
// Model with a non planar wall on the east side
......
......@@ -4,11 +4,7 @@ import java.io.File;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.core.CityModel;
import org.junit.Assert;
import org.junit.Test;
import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.checks.geometry.PlanarCheck;
import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
......@@ -24,36 +20,61 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
public class SyntheticSweepPlanarityModelTest {
public class SyntheticSweepPlanarityModelFactory {
public static void main(String[] args) throws CityDoctorWriteException {
exportBuildingForGui(createSweepPlanarityCubeWithRaisedTopCorner(), new File("sweep-planarity-raised-top-corner.gml"));
exportBuildingForGui(createNonPlanarSweepBox(), new File("sweep-planarity-existing-healer-test-model.gml"));
exportForGui(
createRaisedTopCornerCube(),
new File("sweep-planarity-raised-top-corner.gml"),
"SweepPlanarityRaisedTopCorner");
exportForGui(
createExistingHealerTestModel(),
new File("sweep-planarity-existing-healer-test-model.gml"),
"SweepPlanarityExistingHealerTestModel");
exportForGui(
createWallWithProtrudingWindowInnerRingPoint(),
new File("sweep-case1-wall-window-inner-ring-point.gml"),
"SweepCase1WallWindowInnerRingPoint");
exportForGui(
createWallWithProtrudingFacadePolygonPoint(),
new File("sweep-case1-wall-facade-polygon-point.gml"),
"SweepCase1WallFacadePolygonPoint");
exportForGui(
createSlopedRoofWithProtrudingOpeningRingPoint(),
new File("sweep-case1-sloped-roof-opening-ring-point.gml"),
"SweepCase1SlopedRoofOpeningRingPoint");
}
static Building createNonPlanarCube(double boxsize, double bottomerr, double topLift) {
Building building = new Building();
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
building.addGeometry(geom);
@Test
public void testSyntheticSweepPlanarityCubeHasNonPlanarTopFace() {
Building building = createSweepPlanarityCubeWithRaisedTopCorner();
Geometry geom = building.getGeometries().get(0);
PlanarCheck check = new PlanarCheck();
geom.accept(check);
check.check(geom);
Assert.assertTrue(geom.containsError(CheckId.C_GE_P_NON_PLANAR));
}
Vertex v0 = new Vertex(0, 0, 0);
Vertex v1 = new Vertex(boxsize, 0, 0);
Vertex v4 = new Vertex(boxsize, boxsize, bottomerr);
Vertex v6 = new Vertex(0, boxsize, 0);
Vertex v8 = new Vertex(boxsize, 0, boxsize);
Vertex v9 = new Vertex(boxsize, boxsize, boxsize);
Vertex v10 = new Vertex(0, boxsize, boxsize);
Vertex v11 = new Vertex(0, 0, boxsize + topLift);
addPolygon(geom, v0, v1, v4, v6);
addPolygon(geom, v1, v8, v9, v4);
addPolygon(geom, v8, v11, v10, v9);
addPolygon(geom, v0, v6, v10, v11);
addPolygon(geom, v4, v9, v10, v6);
addPolygon(geom, v0, v11, v8, v1);
@Test
public void exportSyntheticSweepPlanarityCubeForGui() throws CityDoctorWriteException {
exportBuildingForGui(createSweepPlanarityCubeWithRaisedTopCorner(), new File("sweep-planarity-raised-top-corner.gml"));
}
@Test
public void exportNonPlanarSweepBoxForGui() throws CityDoctorWriteException {
exportBuildingForGui(createNonPlanarSweepBox(), new File("sweep-planarity-existing-healer-test-model.gml"));
geom.updateEdgesAndVertices();
return building;
}
static Building createSweepPlanarityCubeWithRaisedTopCorner() {
static Building createRaisedTopCornerCube() {
Building building = new Building();
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
building.addGeometry(geom);
......@@ -78,7 +99,83 @@ public class SyntheticSweepPlanarityModelTest {
return building;
}
static Building createNonPlanarSweepBox() {
/**
* Fall 1 model: one point of a window-like inner ring protrudes from an otherwise
* planar wall. The intended target plane is x = 0 and the protruding ring point
* has no outgoing solid edge, so it should be orthogonally projected back.
*/
static Building createWallWithProtrudingWindowInnerRingPoint() {
Building building = new Building();
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD2, Orientation.OUTWARD);
building.addGeometry(geom);
Polygon wall = addPolygon(geom,
new Vertex(0, 0, 0),
new Vertex(0, 6, 0),
new Vertex(0, 6, 4),
new Vertex(0, 0, 4));
addInteriorRing(wall,
new Vertex(0, 2, 1),
new Vertex(0, 4, 1),
new Vertex(0.3, 4, 3),
new Vertex(0, 2, 3));
geom.updateEdgesAndVertices();
return building;
}
/**
* Fall 1 model: a separate facade/window polygon should lie on the wall plane
* x = 0, but one polygon corner sticks out. Because the facade polygon is not
* topologically connected to a solid edge, the faulty point is a pure projection
* case.
*/
static Building createWallWithProtrudingFacadePolygonPoint() {
Building building = new Building();
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD2, Orientation.OUTWARD);
building.addGeometry(geom);
addPolygon(geom,
new Vertex(0, 0, 0),
new Vertex(0, 6, 0),
new Vertex(0, 6, 4),
new Vertex(0, 0, 4));
addPolygon(geom,
new Vertex(0, 2, 1),
new Vertex(0, 4, 1),
new Vertex(0.3, 4, 3),
new Vertex(0, 2, 3));
geom.updateEdgesAndVertices();
return building;
}
/**
* Fall 1 model: an opening ring in a sloped roof has one point outside the roof
* plane. This checks projection to a general oblique target plane instead of an
* axis-aligned wall plane.
*/
static Building createSlopedRoofWithProtrudingOpeningRingPoint() {
Building building = new Building();
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD2, Orientation.OUTWARD);
building.addGeometry(geom);
Polygon roof = addPolygon(geom,
new Vertex(0, 0, 2),
new Vertex(4, 0, 4),
new Vertex(4, 4, 4),
new Vertex(0, 4, 2));
addInteriorRing(roof,
new Vertex(1, 1, 2.5),
new Vertex(3, 1, 3.5),
new Vertex(3, 3, 4.0),
new Vertex(1, 3, 2.5));
geom.updateEdgesAndVertices();
return building;
}
static Building createExistingHealerTestModel() {
Building building = new Building();
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
building.addGeometry(geom);
......@@ -103,27 +200,27 @@ public class SyntheticSweepPlanarityModelTest {
return building;
}
private static CityDoctorModel createCityDoctorModel(Building building, File sourceFile) {
private static void exportForGui(Building building, File output, String gmlId) throws CityDoctorWriteException {
CityDoctorModel model = createCityDoctorModel(building, output, gmlId);
model.saveAs(output.getAbsolutePath(), false);
System.out.println("Open in CityDoctor GUI:");
System.out.println(output.getAbsolutePath());
}
private static CityDoctorModel createCityDoctorModel(Building building, File sourceFile, String gmlId) {
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, sourceFile, new UnconnectedCache());
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
model.setCityModel(new CityModel());
org.citygml4j.core.model.building.Building gmlBuilding = new org.citygml4j.core.model.building.Building();
gmlBuilding.setId("SyntheticSweepPlanarityRaisedCorner");
gmlBuilding.setId(gmlId);
building.setGmlObject(gmlBuilding);
model.addBuilding(building);
return model;
}
private static void exportBuildingForGui(Building building, File output) throws CityDoctorWriteException {
CityDoctorModel model = createCityDoctorModel(building, output);
model.saveAs(output.getAbsolutePath(), false);
System.out.println("Open in CityDoctor GUI:");
System.out.println(output.getAbsolutePath());
}
private static Polygon addPolygon(Geometry geom, Vertex... vertices) {
Polygon polygon = new ConcretePolygon();
geom.addPolygon(polygon);
......@@ -136,4 +233,14 @@ public class SyntheticSweepPlanarityModelTest {
return polygon;
}
private static LinearRing addInteriorRing(Polygon polygon, Vertex... vertices) {
LinearRing ring = new LinearRing(LinearRingType.INTERIOR);
polygon.addInteriorRing(ring);
for (Vertex vertex : vertices) {
ring.addVertex(vertex);
}
ring.addVertex(vertices[0]);
return ring;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment