| /******************************************************************************* |
| * 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 |