blob: 9e667418ba20e05b693d7c5616e2554b9fee471e [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.common.geometry.data.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.apogy.common.geometry.data.Coordinates;
import org.eclipse.apogy.common.geometry.data.CoordinatesSamplingShape;
import org.eclipse.apogy.common.geometry.data.Mesh;
import org.eclipse.apogy.common.geometry.data.Polygon;
import org.eclipse.apogy.common.geometry.data.PolygonSamplingMode;
import org.eclipse.apogy.common.geometry.data.ShapeSamplingMode;
public abstract class MeshCoordinatesShapesSamplerCustomImpl<CoordinatesType extends Coordinates, PolygonType extends Polygon<CoordinatesType>>
extends MeshCoordinatesShapesSamplerImpl<CoordinatesType, PolygonType> {
@Override
public Mesh<CoordinatesType, PolygonType> process(Mesh<CoordinatesType, PolygonType> input) throws Exception {
if (getProgressMonitor() != null)
getProgressMonitor().beginTask(
"Sampling using " + getCoordinatesSamplingShapes().size() + " sampling shapes. ",
input.getPoints().size());
Mesh<CoordinatesType, PolygonType> sampledMesh = createMesh();
// First goes through the list of points and finds the ones that fall
// inside the sample and that should be kept.
List<CoordinatesType> pointsKept = new ArrayList<CoordinatesType>();
for (CoordinatesType point : input.getPoints()) {
if (isPointInside(point)) {
pointsKept.add(point);
}
}
// Second, goes through the list of point being kept and check
// each of the polygon they belong to should be kept.
List<PolygonType> polygonsKept = new ArrayList<PolygonType>();
for (CoordinatesType point : pointsKept) {
List<PolygonType> polygonsSharingPoint = input.getPolygonsSharingPoint(point);
for (PolygonType polygon : polygonsSharingPoint) {
// If the polygon has not yet been found to be kept.
if (!polygonsKept.contains(polygon)) {
List<CoordinatesType> vertices = polygon.getVertices();
if (getPolygonSamplingMode() == PolygonSamplingMode.AT_LEAST_ONE_VERTEX) {
polygonsKept.add(polygon);
} else if (getPolygonSamplingMode() == PolygonSamplingMode.ALL_VERTEX) {
if (pointsKept.containsAll(vertices)) {
polygonsKept.add(polygon);
}
}
}
}
}
// Populate the sampled mesh with copies of the points kept.
Map<CoordinatesType, CoordinatesType> originalToNewPointMap = new HashMap<CoordinatesType, CoordinatesType>();
for (CoordinatesType point : pointsKept) {
// Adds an entry in the original->new point map.
originalToNewPointMap.put(point, copyCoordinates(point));
}
sampledMesh.getPoints().addAll(originalToNewPointMap.values());
// Populate the sampled mesh with copies of the polygons kept.
List<PolygonType> polygonCopies = new ArrayList<PolygonType>();
for (PolygonType polygon : polygonsKept) {
// Creates a new polygon.
PolygonType newPolygon = createPolygon();
// Gets the list of vertices from the original polygon.
for (CoordinatesType originalpoint : polygon.getVertices()) {
CoordinatesType newPoint = originalToNewPointMap.get(originalpoint);
if (newPoint == null) {
// Point need to be created and added to Map.
newPoint = copyCoordinates(originalpoint);
originalToNewPointMap.put(originalpoint, newPoint);
// Adds the new point to the mesh
sampledMesh.getPoints().add(newPoint);
}
newPolygon.getVertices().add(newPoint);
}
polygonCopies.add(newPolygon);
}
sampledMesh.getPolygons().addAll(polygonCopies);
if (getProgressMonitor() != null)
getProgressMonitor().done();
return sampledMesh;
}
/**
* Return whether or not a point is inside at least one sampling shape
*
<<<<<<< HEAD
* @param point The point.
=======
* @param point
* The point.
>>>>>>> refs/heads/eclipse_pa
* @return True if the point is inside, false otherwise.
*/
private boolean isPointInside(CoordinatesType point) {
boolean inside = false;
if (getShapeSamplingMode() == ShapeSamplingMode.UNION) {
inside = false;
int j = 0;
while (j < getCoordinatesSamplingShapes().size() && !inside) {
CoordinatesSamplingShape<CoordinatesType> samplingShape = getCoordinatesSamplingShapes().get(j);
inside |= samplingShape.isInside(point);
j++;
}
} else if (getShapeSamplingMode() == ShapeSamplingMode.INTERSECTION) {
inside = true;
int j = 0;
while (j < getCoordinatesSamplingShapes().size() && inside) {
CoordinatesSamplingShape<CoordinatesType> samplingShape = getCoordinatesSamplingShapes().get(j);
inside &= samplingShape.isInside(point);
j++;
}
}
return inside;
}
} // MeshCoordinatesShapesSamplerImpl