Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 730beb92 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

vornoi intersection computation - not finished jet.

parent ba1a7dd6
...@@ -184,7 +184,7 @@ ...@@ -184,7 +184,7 @@
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
<!-- Maven Surefire is used to execute unit tests. --> <!-- Maven Surefire is used to cup unit tests. -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version> <version>2.19</version>
......
...@@ -137,7 +137,7 @@ public class ClassFinder { ...@@ -137,7 +137,7 @@ public class ClassFinder {
* Scans all classes accessible from the context class loader which belong to the given package * Scans all classes accessible from the context class loader which belong to the given package
* and subpackages. * and subpackages.
* *
* Deprecated since this method is slow if we have to access jar file, which is the case if we execute the project via vadere.jar! * Deprecated since this method is slow if we have to access jar file, which is the case if we cup the project via vadere.jar!
* *
* @param packageName The base package * @param packageName The base package
* @return The classes * @return The classes
......
...@@ -5,7 +5,7 @@ import java.awt.event.ActionEvent; ...@@ -5,7 +5,7 @@ import java.awt.event.ActionEvent;
import org.vadere.gui.topographycreator.model.IDrawPanelModel; import org.vadere.gui.topographycreator.model.IDrawPanelModel;
/** /**
* A ActionBasic is the last action in the decorator pattern which will be execute. * A ActionBasic is the last action in the decorator pattern which will be cup.
* Action: Notify all Observers. * Action: Notify all Observers.
* *
*/ */
......
...@@ -42,7 +42,7 @@ public class ActionMergeObstacles extends TopographyAction { ...@@ -42,7 +42,7 @@ public class ActionMergeObstacles extends TopographyAction {
.collect(Collectors.toList()); .collect(Collectors.toList());
WeilerAtherton weilerAtherton = new WeilerAtherton(polygons); WeilerAtherton weilerAtherton = new WeilerAtherton(polygons);
List<VPolygon> mergedPolygons = weilerAtherton.execute(); List<VPolygon> mergedPolygons = weilerAtherton.cup();
// remove polygon obstacles // remove polygon obstacles
getScenarioPanelModel().removeObstacleIf(obstacle -> getScenarioPanelModel().removeObstacleIf(obstacle ->
......
...@@ -53,6 +53,6 @@ public class EditMergeObstacles extends AbstractUndoableEdit { ...@@ -53,6 +53,6 @@ public class EditMergeObstacles extends AbstractUndoableEdit {
@Override @Override
public String getPresentationName() { public String getPresentationName() {
return "merge obstacles"; return "cup obstacles";
} }
} }
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
<!-- Maven Surefire is used to execute unit tests. --> <!-- Maven Surefire is used to cup unit tests. -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version> <version>2.19</version>
......
...@@ -15,9 +15,11 @@ import org.vadere.util.geometry.shapes.VPolygon; ...@@ -15,9 +15,11 @@ import org.vadere.util.geometry.shapes.VPolygon;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -125,7 +127,9 @@ public class WeilerAtherton { ...@@ -125,7 +127,9 @@ public class WeilerAtherton {
// compute intersections and add those to the two faces, this implementation is rather slow! // compute intersections and add those to the two faces, this implementation is rather slow!
boolean intersectionFound = true; boolean intersectionFound = true;
int count = 0;
while (intersectionFound) { while (intersectionFound) {
List<PHalfEdge<WeilerPoint>> clippingEdges = clippingMesh.getEdges(clippingFace); List<PHalfEdge<WeilerPoint>> clippingEdges = clippingMesh.getEdges(clippingFace);
List<PHalfEdge<WeilerPoint>> subjectEdges = subjectMesh.getEdges(subjectFace); List<PHalfEdge<WeilerPoint>> subjectEdges = subjectMesh.getEdges(subjectFace);
intersectionFound = false; intersectionFound = false;
...@@ -133,7 +137,6 @@ public class WeilerAtherton { ...@@ -133,7 +137,6 @@ public class WeilerAtherton {
for(PHalfEdge<WeilerPoint> clippingEdge : clippingEdges) { for(PHalfEdge<WeilerPoint> clippingEdge : clippingEdges) {
for(PHalfEdge<WeilerPoint> subjectEdge : subjectEdges) { for(PHalfEdge<WeilerPoint> subjectEdge : subjectEdges) {
Optional<VPoint> optIntersectionPoint = equalIntersectionPoints(subjectEdge, subjectMesh, clippingEdge, clippingMesh); Optional<VPoint> optIntersectionPoint = equalIntersectionPoints(subjectEdge, subjectMesh, clippingEdge, clippingMesh);
if(!optIntersectionPoint.isPresent()) { if(!optIntersectionPoint.isPresent()) {
VLine l1 = subjectMesh.toLine(subjectEdge); VLine l1 = subjectMesh.toLine(subjectEdge);
VLine l2 = clippingMesh.toLine(clippingEdge); VLine l2 = clippingMesh.toLine(clippingEdge);
...@@ -165,6 +168,9 @@ public class WeilerAtherton { ...@@ -165,6 +168,9 @@ public class WeilerAtherton {
PVertex<WeilerPoint> ip1 = IPolyConnectivity.splitEdge(subjectEdge, wp1, subjectMesh); PVertex<WeilerPoint> ip1 = IPolyConnectivity.splitEdge(subjectEdge, wp1, subjectMesh);
PVertex<WeilerPoint> ip2 = IPolyConnectivity.splitEdge(clippingEdge, wp2, clippingMesh); PVertex<WeilerPoint> ip2 = IPolyConnectivity.splitEdge(clippingEdge, wp2, clippingMesh);
subjectMesh.getPoint(ip1).setInside(true);
clippingMesh.getPoint(ip2).setInside(true);
wp1.setTwinPoint(ip2); wp1.setTwinPoint(ip2);
wp2.setTwinPoint(ip1); wp2.setTwinPoint(ip1);
...@@ -263,7 +269,7 @@ public class WeilerAtherton { ...@@ -263,7 +269,7 @@ public class WeilerAtherton {
* *
* @return a list of merged polygons * @return a list of merged polygons
*/ */
public List<VPolygon> execute() { public List<VPolygon> cup() {
boolean merged = true; boolean merged = true;
List<VPolygon> newPolygons = new ArrayList<>(); List<VPolygon> newPolygons = new ArrayList<>();
...@@ -273,17 +279,18 @@ public class WeilerAtherton { ...@@ -273,17 +279,18 @@ public class WeilerAtherton {
int ii = -1; int ii = -1;
int jj = -1; int jj = -1;
merged = false; merged = false;
Pair<VPolygon, VPolygon> mergeResult = null; List<VPolygon> cupResult = null;
for(int i = 0; i < newPolygons.size(); i++) { for(int i = 0; i < newPolygons.size(); i++) {
VPolygon first = newPolygons.get(i); VPolygon first = newPolygons.get(i);
for(int j = i+1; j < newPolygons.size(); j++) { for(int j = i+1; j < newPolygons.size(); j++) {
VPolygon second = newPolygons.get(j); VPolygon second = newPolygons.get(j);
mergeResult = merge(first, second); cupResult = cup(first, second);
assert cupResult.size() <= 2;
// something got merged // something got merged
if(mergeResult.getSecond() == null) { if(cupResult.size() <= 1) {
merged = true; merged = true;
ii = i; ii = i;
jj = j; jj = j;
...@@ -299,7 +306,7 @@ public class WeilerAtherton { ...@@ -299,7 +306,7 @@ public class WeilerAtherton {
if(merged) { if(merged) {
newPolygons.remove(ii); newPolygons.remove(ii);
newPolygons.remove(jj-1); newPolygons.remove(jj-1);
newPolygons.add(mergeResult.getFirst()); newPolygons.add(cupResult.get(0));
} }
} }
...@@ -307,50 +314,159 @@ public class WeilerAtherton { ...@@ -307,50 +314,159 @@ public class WeilerAtherton {
} }
/** /**
* Executes the Weiler-Atherton-Algorithm for two polygons. * Executes the Weiler-Atherton-Algorithm for all of its polygons.
* *
* @param subjectCandidat the first polygon * @return a list of merged polygons
* @param clippingCandidat the second polygon
* @return a pair of polygon where the second element is null if the polygons got merged. This is not the case if there do not overlap.
*/ */
public Pair<VPolygon, VPolygon> merge(@NotNull final VPolygon subjectCandidat, @NotNull final VPolygon clippingCandidat) { public Optional<VPolygon> cap() {
List<VPolygon> newPolygons = new ArrayList<>();
newPolygons.addAll(polygons);
if(polygons.size() == 0) {
return Optional.empty();
}
else if(polygons.size() == 1) {
return Optional.of(polygons.get(0));
}
else {
LinkedList<VPolygon> toDo = new LinkedList<>();
toDo.addAll(polygons);
VPolygon subject = GeometryUtils.isCCW(subjectCandidat) ? subjectCandidat.revertOrder() : subjectCandidat; while (toDo.size() >= 2) {
VPolygon clipping = GeometryUtils.isCCW(clippingCandidat) ? clippingCandidat.revertOrder() : clippingCandidat; VPolygon poly1 = toDo.remove();
VPolygon poly2 = toDo.remove();
List<VPolygon> capResult = cap(poly1, poly2);
if(capResult.isEmpty()) {
return Optional.empty();
}
toDo.addAll(capResult);
}
assert toDo.size() == 1;
return Optional.of(toDo.remove());
}
}
private List<VPolygon> construct(
@NotNull final VPolygon subjectCandidat,
@NotNull final VPolygon clippingCandidat,
final boolean cap) {
//Predicate<WeilerPoint> startEdgeCondition = cap ? p -> p.isInside() : p -> !p.isInside();
VPolygon subject = GeometryUtils.isCCW(subjectCandidat) ? subjectCandidat : subjectCandidat.revertOrder();
VPolygon clipping = GeometryUtils.isCCW(clippingCandidat) ? clippingCandidat : clippingCandidat.revertOrder();
PMesh<WeilerPoint> subjectMesh = new PMesh<>((x,y) -> new WeilerPoint(new VPoint(x,y), false, false)); PMesh<WeilerPoint> subjectMesh = new PMesh<>((x,y) -> new WeilerPoint(new VPoint(x,y), false, false));
PMesh<WeilerPoint> clippingMesh = new PMesh<>((x,y) -> new WeilerPoint(new VPoint(x,y), false, false)); PMesh<WeilerPoint> clippingMesh = new PMesh<>((x,y) -> new WeilerPoint(new VPoint(x,y), false, false));
List<VPolygon> result = new ArrayList<>(2); //List<VPolygon> result = new ArrayList<>(2);
/**
* (1) construct the list connections
*/
Pair<PFace<WeilerPoint>, PFace<WeilerPoint>> pair = constructIntersectionFaces(subject, subjectMesh, clipping, clippingMesh); Pair<PFace<WeilerPoint>, PFace<WeilerPoint>> pair = constructIntersectionFaces(subject, subjectMesh, clipping, clippingMesh);
PFace<WeilerPoint> subjectFace = pair.getFirst(); PFace<WeilerPoint> subjectFace = pair.getFirst();
PFace<WeilerPoint> clippingFace = pair.getSecond(); PFace<WeilerPoint> clippingFace = pair.getSecond();
Set<PHalfEdge<WeilerPoint>> subjectExitingEdges = subjectMesh
.streamEdges(subjectFace)
.filter(edge -> subjectMesh.getPoint(edge).isIntersectionPoint())
.filter(edge -> !subjectMesh.getPoint(subjectMesh.getNext(edge)).isIntersectionPoint() &&
!clipping.contains(subjectMesh.getPoint(subjectMesh.getNext(edge))))
.collect(Collectors.toSet());
Set<PHalfEdge<WeilerPoint>> subjectEnteringEdges = subjectMesh
.streamEdges(subjectFace)
.filter(edge -> subjectMesh.getPoint(edge).isIntersectionPoint())
.filter(edge -> subjectMesh.getPoint(subjectMesh.getNext(edge)).isIntersectionPoint() ||
clipping.contains(subjectMesh.getPoint(subjectMesh.getNext(edge))))
.collect(Collectors.toSet());
List<VPoint> points = new ArrayList<>();
List<VPolygon> polygons = new ArrayList<>();
PMesh<WeilerPoint> mesh = subjectMesh;
Set<PHalfEdge<WeilerPoint>> intersectionSet = cap ? subjectEnteringEdges : subjectExitingEdges;
// cup will preserve the polyons.
if(!cap && intersectionSet.isEmpty()) {
polygons.add(subjectCandidat);
polygons.add(clippingCandidat);
}
while (!intersectionSet.isEmpty()) {
PHalfEdge<WeilerPoint> subjectEdge = intersectionSet.iterator().next();
PHalfEdge<WeilerPoint> next = subjectEdge;
intersectionSet.remove(subjectEdge);
do {
next = mesh.getNext(next);
// adaptPath
if(mesh.getPoint(next).isIntersectionPoint() && !intersectionSet.contains(next)) {
mesh = mesh.equals(subjectMesh) ? clippingMesh : subjectMesh;
next = mesh.getEdge(mesh.getPoint(next).getTwinPoint());
intersectionSet.remove(next);
}
points.add(new VPoint(mesh.getPoint(next)));
} while (!next.equals(subjectEdge));
polygons.add(GeometryUtils.toPolygon(GeometryUtils.filterUselessPoints(points, EPSILON)));
}
return polygons;
/*PFace<WeilerPoint> subjectFace = pair.getFirst();
PFace<WeilerPoint> clippingFace = pair.getSecond();
// phase (2) // phase (2)
Optional<PHalfEdge<WeilerPoint>> intersectionEdges = subjectMesh.findAnyEdge(p -> p.isIntersectionPoint()); Optional<PHalfEdge<WeilerPoint>> intersectionEdges = subjectMesh.findAnyEdge(p -> p.isIntersectionPoint());
Optional<PHalfEdge<WeilerPoint>> optStartPointSub = subjectMesh.findAnyEdge(p -> !p.isIntersectionPoint() && !p.isInside()); Optional<PHalfEdge<WeilerPoint>> optStartPointSub = subjectMesh.findAnyEdge(startEdgeCondition);
Optional<PHalfEdge<WeilerPoint>> optStartPointClip = clippingMesh.findAnyEdge(p -> !p.isIntersectionPoint() && !p.isInside()); Optional<PHalfEdge<WeilerPoint>> optStartPointClip = clippingMesh.findAnyEdge(startEdgeCondition);
Optional<PHalfEdge<WeilerPoint>> subInsideEdge = subjectMesh.findAnyEdge(p -> p.isInside());
Optional<PHalfEdge<WeilerPoint>> clipInsideEdge = clippingMesh.findAnyEdge(p -> p.isInside());
Optional<PHalfEdge<WeilerPoint>> subOutsideEdge = subjectMesh.findAnyEdge(p -> !p.isInside());
Optional<PHalfEdge<WeilerPoint>> clipOutsideEdge = clippingMesh.findAnyEdge(p -> !p.isInside());
// no point intersection and no point is contained in the other polygon => polygons do not overlap at all // no point intersection and no point is contained in the other polygon => polygons do not overlap at all
if(optStartPointSub.isPresent() && optStartPointClip.isPresent() && !intersectionEdges.isPresent()) { if(!subInsideEdge.isPresent() && !clipInsideEdge.isPresent() && !intersectionEdges.isPresent()) {
result.add(subject); // complete merge
result.add(clipping); if(!cap) {
return Pair.create(subject, clipping); return Pair.create(subject, clipping);
}
else {
return Pair.create(null, null);
}
} }
// no point intersections and there is a point of the subject outside of the clipping => clipping is fully contained in subject // no point intersections and there is a point of the subject outside of the clipping => clipping is fully contained in subject
if(optStartPointSub.isPresent() && !intersectionEdges.isPresent()) { if(subOutsideEdge.isPresent() && !intersectionEdges.isPresent()) {
result.add(subject); // cup is the subject
return Pair.create(subject, null); if(!cap) {
return Pair.create(subject, null);
} // cap is the clipping
else {
return Pair.create(clipping, null);
}
} }
// no point intersections and there is a point of the clipping outside of the subject => subject is fully contained in clipping // no point intersections and there is a point of the clipping outside of the subject => subject is fully contained in clipping
if(optStartPointClip.isPresent() && !intersectionEdges.isPresent()) { if(clipOutsideEdge.isPresent() && !intersectionEdges.isPresent()) {
result.add(clipping); // cup is the subject
return pair.create(clipping, null); if(!cap) {
return Pair.create(clipping, null);
} // cap is the clipping
else {
return Pair.create(subject, null);
}
} }
PHalfEdge<WeilerPoint> first = null; PHalfEdge<WeilerPoint> first = null;
...@@ -374,24 +490,61 @@ public class WeilerAtherton { ...@@ -374,24 +490,61 @@ public class WeilerAtherton {
PMesh<WeilerPoint> mesh = mesh1; PMesh<WeilerPoint> mesh = mesh1;
List<VPoint> points = new ArrayList<>(); List<VPoint> points = new ArrayList<>();
int count = 0;
boolean foundDiff = false;
do { do {
next = mesh.getNext(next); count++;
//next = mesh.getNext(next);
WeilerPoint wp = mesh.getPoint(next); WeilerPoint wp = mesh.getPoint(next);
// walk into the other mesh / polygon // walk into the other mesh / polygon
if(wp.isIntersectionPoint()) { if(wp.isIntersectionPoint()) {
// swap meshes // swap meshes
mesh = mesh == mesh1 ? mesh2 : mesh1; mesh = (mesh == mesh1 ? mesh2 : mesh1);
// swap edges // swap edges
next = mesh.getEdge(wp.twinPoint); next = mesh.getEdge(wp.twinPoint);
} }
if(count > 1000) {
System.out.println(count + " (2)");
constructIntersectionFaces(subject, subjectMesh, clipping, clippingMesh);
}
try {
next = mesh.getNext(next);
}
catch (NullPointerException e) {
System.out.println("shit");
}
points.add(new VPoint(wp)); points.add(new VPoint(wp));
if(!points.get(0).equals(mesh.getPoint(next))) {
foundDiff = true;
}
}
while (!foundDiff || !points.get(0).equals(mesh.getPoint(next)));
try{
Pair.create(GeometryUtils.toPolygon(GeometryUtils.filterUselessPoints(points, EPSILON)), null);
}
catch (Exception e) {
System.out.println("baba");
} }
while (!next.equals(first)); return Pair.create(GeometryUtils.toPolygon(GeometryUtils.filterUselessPoints(points, EPSILON)), null);*/
}
public List<VPolygon> cap(@NotNull final VPolygon subjectCandidat, @NotNull final VPolygon clippingCandidat) {
return construct(subjectCandidat, clippingCandidat, true);
}
return Pair.create(GeometryUtils.toPolygon(GeometryUtils.filterUselessPoints(points, EPSILON)), null); /**
* Executes the Weiler-Atherton-Algorithm for two polygons.
*
* @param subjectCandidat the first polygon
* @param clippingCandidat the second polygon
* @return a pair of polygon where the second element is null if the polygons got merged. This is not the case if there do not overlap.
*/
public List<VPolygon> cup(@NotNull final VPolygon subjectCandidat, @NotNull final VPolygon clippingCandidat) {
return construct(subjectCandidat, clippingCandidat, false);
} }
} }
...@@ -491,7 +491,7 @@ public class AMesh<P extends IPoint> implements IMesh<P, AVertex<P>, AHalfEdge<P ...@@ -491,7 +491,7 @@ public class AMesh<P extends IPoint> implements IMesh<P, AVertex<P>, AHalfEdge<P
// clone the old one! // clone the old one!
AMesh<P> cMesh = clone(); AMesh<P> cMesh = clone();
// merge some of them? // cup some of them?
int nullIdentifier = -2; int nullIdentifier = -2;
// rebuild // rebuild
...@@ -554,7 +554,7 @@ public class AMesh<P extends IPoint> implements IMesh<P, AVertex<P>, AHalfEdge<P ...@@ -554,7 +554,7 @@ public class AMesh<P extends IPoint> implements IMesh<P, AVertex<P>, AHalfEdge<P
} }
private void copyFace(@NotNull final AFace<P> face, @NotNull int[] vertexMap, @NotNull int[] edgeMap, @NotNull int[] faceMap, @NotNull final AMesh<P> cMesh) { private void copyFace(@NotNull final AFace<P> face, @NotNull int[] vertexMap, @NotNull int[] edgeMap, @NotNull int[] faceMap, @NotNull final AMesh<P> cMesh) {
// merge some of them? // cup some of them?
int nullIdentifier = -2; int nullIdentifier = -2;
// face not jet copied // face not jet copied
......
...@@ -160,11 +160,13 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext ...@@ -160,11 +160,13 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
*/ */
static <P extends IPoint, V extends IVertex<P>, E extends IHalfEdge<P>, F extends IFace<P>> V splitEdge( static <P extends IPoint, V extends IVertex<P>, E extends IHalfEdge<P>, F extends IFace<P>> V splitEdge(
@NotNull final E edge, @NotNull P p, @NotNull IMesh<P, V, E, F> mesh) { @NotNull final E edge, @NotNull P p, @NotNull IMesh<P, V, E, F> mesh) {
V u = mesh.createVertex(p);
E twin = mesh.getTwin(edge); E twin = mesh.getTwin(edge);
E prev = mesh.getPrev(edge); E prev = mesh.getPrev(edge);
E tNext = mesh.getNext(twin); E tNext = mesh.getNext(twin);
V u = mesh.createVertex(p);
E e = mesh.createEdge(u); E e = mesh.createEdge(u);
mesh.setFace(e, mesh.getFace(edge)); mesh.setFace(e, mesh.getFace(edge));
E t = mesh.createEdge(mesh.getVertex(twin)); E t = mesh.createEdge(mesh.getVertex(twin));
...@@ -411,10 +413,10 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext ...@@ -411,10 +413,10 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
* <p>Changes the connectivity.</p> * <p>Changes the connectivity.</p>
* *
* @param face the face * @param face the face
* @param mergeCondition the merge condition * @param mergeCondition the cup condition
* @param deleteIsolatedVertices if true, vertices with degree zero will be removed from the mesh data structure otherwise they will not. * @param deleteIsolatedVertices if true, vertices with degree zero will be removed from the mesh data structure otherwise they will not.
* *
* @return the merge result i.e. the resulting face. * @return the cup result i.e. the resulting face.
*/ */
default Optional<F> mergeFaces(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsolatedVertices) { default Optional<F> mergeFaces(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsolatedVertices) {
return mergeFaces(face, mergeCondition, deleteIsolatedVertices, -1); return mergeFaces(face, mergeCondition, deleteIsolatedVertices, -1);
...@@ -430,11 +432,11 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext ...@@ -430,11 +432,11 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
* <p>Changes the connectivity.</p> * <p>Changes the connectivity.</p>
* *
* @param face the face * @param face the face
* @param mergeCondition the merge condition * @param mergeCondition the cup condition
* @param deleteIsolatedVertices if true, vertices with degree zero will be removed from the mesh data structure otherwise they will not. * @param deleteIsolatedVertices if true, vertices with degree zero will be removed from the mesh data structure otherwise they will not.
* @param maxDept the maximum dept / neighbouring distance at which faces can be removed * @param maxDept the maximum dept / neighbouring distance at which faces can be removed
* *
* @return the merge result i.e. the resulting face. * @return the cup result i.e. the resulting face.
*/ */
default Optional<F> mergeFaces(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsolatedVertices, final int maxDept) { default Optional<F> mergeFaces(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsolatedVertices, final int maxDept) {
boolean modified = true; boolean modified = true;
...@@ -480,14 +482,14 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext ...@@ -480,14 +482,14 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
/**