| /******************************************************************************* |
| * Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Pierre Allard, |
| * Regent L'Archeveque - initial API and implementation |
| * |
| * SPDX-License-Identifier: EPL-1.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.apogy.addons.vehicle; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.apogy.common.geometry.data3d.CartesianTriangle; |
| import org.eclipse.apogy.common.geometry.data3d.CartesianTriangularMesh; |
| import org.jgrapht.DirectedGraph; |
| import org.jgrapht.alg.ConnectivityInspector; |
| import org.jgrapht.graph.DefaultDirectedGraph; |
| import org.jgrapht.graph.DefaultEdge; |
| import org.jgrapht.traverse.BreadthFirstIterator; |
| |
| public class ClosestNeighbourIteratorProvider { |
| private CartesianTriangularMesh mesh = null; |
| private DirectedGraph<CartesianTriangle, DefaultEdge> graph = null; |
| |
| public ClosestNeighbourIteratorProvider(CartesianTriangularMesh mesh) { |
| this.mesh = mesh; |
| } |
| |
| public BreadthFirstIterator<CartesianTriangle, DefaultEdge> createBreadthFirstIterator( |
| CartesianTriangle startTriangle) { |
| if (startTriangle != null) { |
| return new BreadthFirstIterator<CartesianTriangle, DefaultEdge>(getGraph(), startTriangle); |
| } else { |
| return new BreadthFirstIterator<CartesianTriangle, DefaultEdge>(getGraph()); |
| } |
| } |
| |
| private DirectedGraph<CartesianTriangle, DefaultEdge> getGraph() { |
| if (this.graph == null) { |
| this.graph = new DefaultDirectedGraph<CartesianTriangle, DefaultEdge>(DefaultEdge.class); |
| |
| // Adds all triangles to the graph |
| for (CartesianTriangle triangle : this.mesh.getPolygons()) { |
| this.graph.addVertex(triangle); |
| |
| } |
| |
| // Adds edges between triangles representing neighbours relationships. |
| for (CartesianTriangle triangle : this.mesh.getPolygons()) { |
| List<CartesianTriangle> neighbours = this.mesh.getPolygonNeighbours(triangle); |
| for (CartesianTriangle neighbour : neighbours) { |
| if (!this.graph.containsEdge(triangle, neighbour)) { |
| this.graph.addEdge(triangle, neighbour); |
| } |
| |
| if (!this.graph.containsEdge(neighbour, triangle)) { |
| this.graph.addEdge(neighbour, triangle); |
| } |
| } |
| } |
| |
| // TODO Connects isolated group of triangle in a better way ! |
| ConnectivityInspector<CartesianTriangle, DefaultEdge> ci = new ConnectivityInspector<CartesianTriangle, DefaultEdge>( |
| this.graph); |
| List<Set<CartesianTriangle>> connectedSets = ci.connectedSets(); |
| for (Set<CartesianTriangle> set : connectedSets) { |
| if (set.size() > 0) { |
| // Creates a connection between this sets and the others. |
| List<CartesianTriangle> setTriangles = new ArrayList<CartesianTriangle>(set); |
| CartesianTriangle sourceTriangle = setTriangles.get(0); |
| |
| for (Set<CartesianTriangle> otherSet : connectedSets) { |
| if (otherSet != set && otherSet.size() > 0) { |
| List<CartesianTriangle> othersetTriangles = new ArrayList<CartesianTriangle>(otherSet); |
| CartesianTriangle destinationTriangle = othersetTriangles.get(0); |
| |
| if (!this.graph.containsEdge(sourceTriangle, destinationTriangle)) { |
| this.graph.addEdge(sourceTriangle, destinationTriangle); |
| } |
| |
| if (!this.graph.containsEdge(destinationTriangle, sourceTriangle)) { |
| this.graph.addEdge(destinationTriangle, sourceTriangle); |
| } |
| } |
| } |
| } |
| } |
| } |
| return this.graph; |
| } |
| } |