/*- * 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 java.util.ArrayList; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; 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; public class MeshSurface { private List polygons; public static MeshSurface of(Geometry geom) { List polygonList = new ArrayList<>(); Map pointMap = new IdentityHashMap<>(); for (Polygon p : geom.getPolygons()) { List> loopCoordinates = new ArrayList<>(); List edgeExtRing = createCoordinatesFromRing(pointMap, p.getExteriorRing().getVertices()); loopCoordinates.add(edgeExtRing); for (LinearRing innerRing : p.getInnerRings()) { List edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices()); loopCoordinates.add(edgeInnerRing); } List> halfEdges = new ArrayList<>(); for (List ringCoordinates : loopCoordinates) { List currHeList = createHalfEdgesFromCoordinates(ringCoordinates); halfEdges.add(currHeList); } CDPolygonNs newPolygon = new CDPolygonNs(halfEdges); polygonList.add(newPolygon); } return new MeshSurface(polygonList); } private static List createCoordinatesFromRing(Map pointMap, List vertices) { List edgeRing = new ArrayList<>(); for (int i = 0; i < vertices.size() - 1; i++) { Vertex v = vertices.get(i); Coordinate3d c = pointMap.computeIfAbsent(v, key -> new Coordinate3d(key.getX(), key.getY(), key.getZ())); edgeRing.add(c); } return edgeRing; } private static List createHalfEdgesFromCoordinates(List ringCoordinates) { List currHeList = new ArrayList<>(); HalfEdge prevHalfEdge = null; for (int currCoordIndex = 1; currCoordIndex < ringCoordinates.size(); currCoordIndex++) { int prevCoordIndex = currCoordIndex - 1; Coordinate3d currCoord = ringCoordinates.get(currCoordIndex); Coordinate3d prevCoord = ringCoordinates.get(prevCoordIndex); HalfEdge e = new HalfEdge(prevCoord, currCoord); if (prevHalfEdge != null) { prevHalfEdge.setNext(e); } currHeList.add(e); prevHalfEdge = e; } if (prevHalfEdge == null) { throw new IllegalStateException("No half edges were created"); } Coordinate3d start = ringCoordinates.get(0); Coordinate3d end = ringCoordinates.get(ringCoordinates.size() - 1); HalfEdge e = new HalfEdge(end, start); prevHalfEdge.setNext(e); e.setNext(currHeList.get(0)); currHeList.add(e); return currHeList; } public MeshSurface(List polygons) { this.polygons = polygons; } public List getPolygons() { return polygons; } }