blob: 1bab8b21f3a245821f90ad9cca1f80a690e3e784 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}