diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java
index 31359cc2fd5d659c0b120a5c0dc0d1bef7f6d37a..91e6062f40f48a0cedd76eb59080c4d4231f40a7 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java
@@ -1,167 +1,162 @@
 package cz.fidentis.analyst.visitors.mesh;
 
-import cz.fidentis.analyst.Logger;
 import cz.fidentis.analyst.mesh.MeshVisitor;
 import cz.fidentis.analyst.mesh.core.MeshFacet;
 import cz.fidentis.analyst.mesh.core.MeshTriangle;
+import cz.fidentis.analyst.symmetry.CrossSectionCurve;
 import cz.fidentis.analyst.symmetry.Plane;
 
 import javax.vecmath.Point3d;
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
+
 
 /**
- * A visitor that calculates the cross-section of a face and a cutting plane using the triangles.
+ * A visitor that calculates the cross-section of a face and a cutting plane using the edges between triangles.
  * <p>
  * This visitor is thread-safe.
  * </p>
  *
  * @author Dominik Racek
+ * @author Radek Oslejsek
  */
 public class CrossSection extends MeshVisitor {
-    private List<Point3d> points;
-    private Set<Point3d> usedPoints;
-    private Plane plane;
-
+    private final CrossSectionCurve curve;
+    private final Set<Point3d> usedPoints;
     private Set<MeshTriangle> visited;
+    private Set<MeshTriangle> toVisit;
+
+    private final Plane plane;
 
     /**
-     * Constructor for CrossSection visitor
+     * Constructor for CrossSectionZigZag visitor
      *
      * @param plane cutting plane
      */
     public CrossSection(Plane plane) {
         this.plane = plane;
-        this.points = new ArrayList<>();
+        this.curve = new CrossSectionCurve();
         this.usedPoints = new HashSet<>();
     }
 
-    private List<MeshTriangle> getValidNeighboringTriangles(MeshFacet facet, MeshTriangle tri) {
-        List<MeshTriangle> output = facet.getNeighboringTriangles(tri);
-        output.removeIf(n -> ((visited.contains(n))
-                || (!n.checkIntersectionWithPlane(plane.getNormal(), plane.getDistance()))));
-        return output;
-    }
-
-    private List<MeshTriangle> getValidAdjacentTriangles(MeshFacet facet, MeshTriangle tri) {
-        List<MeshTriangle> output = facet.getAdjacentTriangles(tri);
-        output.removeIf(n -> ((visited.contains(n))
-                || (!n.checkIntersectionWithPlane(plane.getNormal(), plane.getDistance()))));
-        return output;
-    }
-
-    private void addPoint(MeshTriangle tri, MeshTriangle previous, boolean direction) {
-        List<Point3d> commonEdge = tri.getCommonPoints(previous);
-        if (commonEdge.size() == 2) {
-            Point3d p = plane.getIntersectionWithLine(commonEdge.get(0), commonEdge.get(1));
-            if (p == null) {
-                return;
-            }
+    private void addPoint(Point3d p, boolean direction, int segment) {
+        if (!usedPoints.contains(p)) {
+            usedPoints.add(p);
 
-            if (!usedPoints.contains(p)) {
-                usedPoints.add(p);
-
-                if (direction) {
-                    points.add(p);
-                } else {
-                    points.add(0, p);
-                }
+            if (direction) {
+                curve.addPointToSegmentEnd(segment, p);
+            } else {
+                curve.addPointToSegmentStart(segment, p);
             }
         }
     }
 
-    private void visitMeshFacetRec(MeshFacet facet, MeshTriangle tri, MeshTriangle previous, boolean direction) {
-        visited.add(tri);
-
-        // Depending on the direction, add the point to the start or to the end of points
-        addPoint(tri, previous, direction);
+    private void visitMeshFacetRec(MeshFacet facet, int p1, int p2, MeshTriangle previous, boolean direction, int segment) {
+        List<MeshTriangle> triangles = facet.getAdjacentTriangles(p1, p2);
+        triangles.remove(previous);
+        if (triangles.isEmpty()) {
+            return;
+        }
 
-        // Recursively call to the end
-        // Get all neighbors that have not been visited and are intercepted
-        List<MeshTriangle> neighbors = getValidNeighboringTriangles(facet, tri);
+        //Find the next intersected edge
+        MeshTriangle current = triangles.get(0);
+        toVisit.remove(current);
 
-        // If no valid neighbours are found, try to look further
-        if (neighbors.size() == 0) {
-            neighbors = getValidAdjacentTriangles(facet, tri);
+        if (visited.contains(current)) {
+            return;
+        }
+        visited.add(current);
+
+        //Find the index of the last vertex of current (first ones being p1 and p2)
+        int p3;
+        if (current.index1 != p1 && current.index1 != p2) {
+            p3 = current.index1;
+        } else if (current.index2 != p1 && current.index2 != p2) {
+            p3 = current.index2;
+        } else {
+            p3 = current.index3;
         }
 
-        if (neighbors.size() == 1) {
-            //Only one neighbor - go there
-            visitMeshFacetRec(facet, neighbors.get(0), tri, direction);
-        } else if (neighbors.size() == 2) {
-            //Two neighbors - they are valid to each other, but one of them has another valid neighbor.
-            //                Select the one that only has the other as a neighbor so the route is linear.
-            List<MeshTriangle> valid = getValidNeighboringTriangles(facet, neighbors.get(0));
+        //Next intersected edge will be between p1-p3 or p2-p3
+        Point3d intersection = plane.getIntersectionWithLine(facet.getVertex(p1).getPosition(),
+                facet.getVertex(p3).getPosition());
 
-            if (valid.size() == 1) {
-                visitMeshFacetRec(facet, neighbors.get(0), tri, direction);
-            } else {
-                visitMeshFacetRec(facet, neighbors.get(1), tri, direction);
-            }
+        if (intersection == null) {
+            intersection = plane.getIntersectionWithLine(facet.getVertex(p2).getPosition(),
+                    facet.getVertex(p3).getPosition());
+
+            addPoint(intersection, direction, segment);
+            visitMeshFacetRec(facet, p2, p3, current, direction, segment);
+        } else {
+            addPoint(intersection, direction, segment);
+            visitMeshFacetRec(facet, p1, p3, current, direction, segment);
         }
+
     }
 
     @Override
     public void visitMeshFacet(MeshFacet facet) {
-        Logger out = Logger.measureTime();
-
-        this.visited = new HashSet<>();
-
+        //Logger out = Logger.measureTime();
+
+        // Find all candidates
+        visited = new HashSet<>();
+        toVisit = facet.getTriangles().parallelStream()
+                .filter(t -> t.checkIntersectionWithPlane(plane.getNormal(), plane.getDistance()))
+                .collect(Collectors.toSet());
+        
         synchronized (this) {
-
-            // Find the first triangle
-            MeshTriangle first = null;
-            for (MeshTriangle tri : facet) {
-                if (tri.checkIntersectionWithPlane(plane.getNormal(), plane.getDistance())) {
-                    first = tri;
-                    break;
-                }
-            }
-
-            if (first == null) {
-                return;
-            }
-
-            // Set found and visited and add to points
-            visited.add(first);
-
-            // Find the valid neighboring triangles and act based on the amount
-            List<MeshTriangle> neighbors = getValidNeighboringTriangles(facet, first);
-
-            if (neighbors.size() == 1) {
-                //Only one neighbor - go there
-                visitMeshFacetRec(facet, neighbors.get(0), first, true);
-            } else if (neighbors.size() == 2) {
-                //Two neighbors - one on each side
-                visitMeshFacetRec(facet, neighbors.get(0), first, true);
-                visitMeshFacetRec(facet, neighbors.get(1), first, false);
-            } else if (neighbors.size() == 3) {
-                //Three neighbors - select the two with only one valid neighbor
-                List<MeshTriangle> valid = getValidNeighboringTriangles(facet, neighbors.get(0));
-                if (valid.size() == 1) {
-                    //Index 0 is one of the correct ones, find the other
-                    visitMeshFacetRec(facet, neighbors.get(0), first, true);
-                    List<MeshTriangle> valid1 = getValidNeighboringTriangles(facet, neighbors.get(1));
-
-                    if (valid1.size() == 1) {
-                        visitMeshFacetRec(facet, neighbors.get(1), first, false);
-                    } else {
-                        visitMeshFacetRec(facet, neighbors.get(2), first, false);
+            while (!toVisit.isEmpty()) {
+                MeshTriangle tri = toVisit.iterator().next();
+                toVisit.remove(tri);
+                int segment = curve.addNewSegment();
+                
+                // Figure out which lines are intersected
+                Point3d intersection1 = plane.getIntersectionWithLine(tri.getVertex1(), tri.getVertex2());
+                Point3d intersection2 = plane.getIntersectionWithLine(tri.getVertex2(), tri.getVertex3());
+                Point3d intersection3 = plane.getIntersectionWithLine(tri.getVertex3(), tri.getVertex1());
+                
+                if (intersection1 != null) {
+                    //Intersection 1
+                    addPoint(intersection1, true, segment);
+                    visitMeshFacetRec(facet, tri.index1, tri.index2, tri, true, segment);
+                    if (intersection2 != null) {
+                        //Intersection 1 and 2
+                        addPoint(intersection2, false, segment);
+                        visitMeshFacetRec(facet, tri.index2, tri.index3, tri, false, segment);
+                    } else if (intersection3 != null) {
+                        //Intersection 1 and 3
+                        addPoint(intersection3, false, segment);
+                        visitMeshFacetRec(facet, tri.index3, tri.index1, tri, false, segment);
+                    }
+                } else if (intersection2 != null) {
+                    //Intersection 2
+                    addPoint(intersection2, true, segment);
+                    visitMeshFacetRec(facet, tri.index2, tri.index3, tri, true, segment);
+                    if (intersection3 != null) {
+                        //Intersection 2 and 3
+                        addPoint(intersection3, false, segment);
+                        visitMeshFacetRec(facet, tri.index3, tri.index1, tri, false, segment);
                     }
-                } else {
-                    //Index 0 is not one of the correct ones, 1 and 2 are
-                    visitMeshFacetRec(facet, neighbors.get(1), first, true);
-                    visitMeshFacetRec(facet, neighbors.get(2), first, false);
+
+                } else if (intersection3 != null) {
+                    //Intersection 3 only
+                    addPoint(intersection3, true, segment);
+                    visitMeshFacetRec(facet, tri.index3, tri.index1, tri, true, segment);
                 }
+                //No intersection
             }
         }
 
-        out.printDuration("Cross section with triangle method");
+        //out.printDuration("Cross section with zigzag method");
     }
 
-    public List<Point3d> getPoints() {
-        return points;
+    /**
+     * Returns computed cross section curve.
+     * @return cross section curve
+     */
+    public CrossSectionCurve getCrossSectionCurve() {
+        return curve;
     }
 }
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSectionZigZag.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSectionZigZag.java
deleted file mode 100644
index befe27888118ed1a6b897713c5d1fc7c1214dc3e..0000000000000000000000000000000000000000
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSectionZigZag.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package cz.fidentis.analyst.visitors.mesh;
-
-import cz.fidentis.analyst.mesh.MeshVisitor;
-import cz.fidentis.analyst.mesh.core.MeshFacet;
-import cz.fidentis.analyst.mesh.core.MeshTriangle;
-import cz.fidentis.analyst.symmetry.CrossSectionCurve;
-import cz.fidentis.analyst.symmetry.Plane;
-
-import javax.vecmath.Point3d;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-
-/**
- * A visitor that calculates the cross-section of a face and a cutting plane using the edges between triangles.
- * <p>
- * This visitor is thread-safe.
- * </p>
- *
- * @author Dominik Racek
- * @author Radek Oslejsek
- */
-public class CrossSectionZigZag extends MeshVisitor {
-    private final CrossSectionCurve curve;
-    private final Set<Point3d> usedPoints;
-    private Set<MeshTriangle> visited;
-    private Set<MeshTriangle> toVisit;
-
-    private final Plane plane;
-
-    /**
-     * Constructor for CrossSectionZigZag visitor
-     *
-     * @param plane cutting plane
-     */
-    public CrossSectionZigZag(Plane plane) {
-        this.plane = plane;
-        this.curve = new CrossSectionCurve();
-        this.usedPoints = new HashSet<>();
-    }
-
-    private void addPoint(Point3d p, boolean direction, int segment) {
-        if (!usedPoints.contains(p)) {
-            usedPoints.add(p);
-
-            if (direction) {
-                curve.addPointToSegmentEnd(segment, p);
-            } else {
-                curve.addPointToSegmentStart(segment, p);
-            }
-        }
-    }
-
-    private void visitMeshFacetRec(MeshFacet facet, int p1, int p2, MeshTriangle previous, boolean direction, int segment) {
-        List<MeshTriangle> triangles = facet.getAdjacentTriangles(p1, p2);
-        triangles.remove(previous);
-        if (triangles.isEmpty()) {
-            return;
-        }
-
-        //Find the next intersected edge
-        MeshTriangle current = triangles.get(0);
-        toVisit.remove(current);
-
-        if (visited.contains(current)) {
-            return;
-        }
-        visited.add(current);
-
-        //Find the index of the last vertex of current (first ones being p1 and p2)
-        int p3;
-        if (current.index1 != p1 && current.index1 != p2) {
-            p3 = current.index1;
-        } else if (current.index2 != p1 && current.index2 != p2) {
-            p3 = current.index2;
-        } else {
-            p3 = current.index3;
-        }
-
-        //Next intersected edge will be between p1-p3 or p2-p3
-        Point3d intersection = plane.getIntersectionWithLine(facet.getVertex(p1).getPosition(),
-                facet.getVertex(p3).getPosition());
-
-        if (intersection == null) {
-            intersection = plane.getIntersectionWithLine(facet.getVertex(p2).getPosition(),
-                    facet.getVertex(p3).getPosition());
-
-            addPoint(intersection, direction, segment);
-            visitMeshFacetRec(facet, p2, p3, current, direction, segment);
-        } else {
-            addPoint(intersection, direction, segment);
-            visitMeshFacetRec(facet, p1, p3, current, direction, segment);
-        }
-
-    }
-
-    @Override
-    public void visitMeshFacet(MeshFacet facet) {
-        //Logger out = Logger.measureTime();
-
-        // Find all candidates
-        visited = new HashSet<>();
-        toVisit = facet.getTriangles().parallelStream()
-                .filter(t -> t.checkIntersectionWithPlane(plane.getNormal(), plane.getDistance()))
-                .collect(Collectors.toSet());
-        
-        synchronized (this) {
-            while (!toVisit.isEmpty()) {
-                MeshTriangle tri = toVisit.iterator().next();
-                toVisit.remove(tri);
-                int segment = curve.addNewSegment();
-                
-                // Figure out which lines are intersected
-                Point3d intersection1 = plane.getIntersectionWithLine(tri.getVertex1(), tri.getVertex2());
-                Point3d intersection2 = plane.getIntersectionWithLine(tri.getVertex2(), tri.getVertex3());
-                Point3d intersection3 = plane.getIntersectionWithLine(tri.getVertex3(), tri.getVertex1());
-                
-                if (intersection1 != null) {
-                    //Intersection 1
-                    addPoint(intersection1, true, segment);
-                    visitMeshFacetRec(facet, tri.index1, tri.index2, tri, true, segment);
-                    if (intersection2 != null) {
-                        //Intersection 1 and 2
-                        addPoint(intersection2, false, segment);
-                        visitMeshFacetRec(facet, tri.index2, tri.index3, tri, false, segment);
-                    } else if (intersection3 != null) {
-                        //Intersection 1 and 3
-                        addPoint(intersection3, false, segment);
-                        visitMeshFacetRec(facet, tri.index3, tri.index1, tri, false, segment);
-                    }
-                } else if (intersection2 != null) {
-                    //Intersection 2
-                    addPoint(intersection2, true, segment);
-                    visitMeshFacetRec(facet, tri.index2, tri.index3, tri, true, segment);
-                    if (intersection3 != null) {
-                        //Intersection 2 and 3
-                        addPoint(intersection3, false, segment);
-                        visitMeshFacetRec(facet, tri.index3, tri.index1, tri, false, segment);
-                    }
-
-                } else if (intersection3 != null) {
-                    //Intersection 3 only
-                    addPoint(intersection3, true, segment);
-                    visitMeshFacetRec(facet, tri.index3, tri.index1, tri, true, segment);
-                }
-                //No intersection
-            }
-        }
-
-        //out.printDuration("Cross section with zigzag method");
-    }
-
-    /**
-     * Returns computed cross section curve.
-     * @return cross section curve
-     */
-    public CrossSectionCurve getCrossSectionCurve() {
-        return curve;
-    }
-}
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/CrossSectionTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/CrossSectionTest.java
index 29d32ff33feaf376aa7bec416c95fdc14e2a2915..53851b2baeed3047e4e6b461283768d62bb1fad9 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/CrossSectionTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/CrossSectionTest.java
@@ -58,7 +58,7 @@ public class CrossSectionTest {
         Plane cuttingPlane = new Plane(new Vector3d(-1, 0, 0), -0.5);
         MeshModel model = createModel();
 
-        CrossSectionZigZag cs = new CrossSectionZigZag(cuttingPlane);
+        CrossSection cs = new CrossSection(cuttingPlane);
         model.compute(cs);
         CrossSectionCurve curve = cs.getCrossSectionCurve();
 
@@ -83,35 +83,4 @@ public class CrossSectionTest {
         }
     }
 
-    /**
-     * Unit test for CrossSection visitor
-     */
-    @Test
-    public void CrossSection() {
-        Plane cuttingPlane = new Plane(new Vector3d(-1, 0, 0), -0.5);
-        MeshModel model = createModel();
-
-        CrossSection cs = new CrossSection(cuttingPlane);
-        model.compute(cs);
-        List<Point3d> points = cs.getPoints();
-
-        //They can be ordered two ways, check both
-        //Flaw of the non-zigzag design: it can't detect first and last intersection,
-        //since it only controls edges between two triangles.
-        Assertions.assertEquals(4, points.size());
-        if (points.get(0).equals(new Point3d(0.5, 0.5, 0))) {
-            Assertions.assertEquals(points.get(0), new Point3d(0.5, 0.5, 0));
-            Assertions.assertEquals(points.get(1), new Point3d(0.5, 1, 0));
-            Assertions.assertEquals(points.get(2), new Point3d(0.5, 1.5, 0));
-            Assertions.assertEquals(points.get(3), new Point3d(0.5, 2, 0));
-        } else if (points.get(0).equals(new Point3d(0.5, 2, 0))) {
-            Assertions.assertEquals(points.get(1), new Point3d(0.5, 2, 0));
-            Assertions.assertEquals(points.get(2), new Point3d(0.5, 1.5, 0));
-            Assertions.assertEquals(points.get(3), new Point3d(0.5, 1, 0));
-            Assertions.assertEquals(points.get(4), new Point3d(0.5, 0.5, 0));
-        } else {
-            Assertions.fail();
-        }
-    }
-
 }
diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java
index 50c730c0d054d15f4021583b5dffab7ebf1a8d68..e79f9fd1eebc048ff394f0252f1f6390c3a7268c 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java
@@ -9,7 +9,7 @@ import cz.fidentis.analyst.face.events.HumanFaceListener;
 import cz.fidentis.analyst.face.events.HumanFaceTransformedEvent;
 import cz.fidentis.analyst.scene.DrawableCuttingPlane;
 import cz.fidentis.analyst.visitors.mesh.BoundingBox.BBox;
-import cz.fidentis.analyst.visitors.mesh.CrossSectionZigZag;
+import cz.fidentis.analyst.visitors.mesh.CrossSection;
 import org.openide.filesystems.FileChooserBuilder;
 
 import javax.swing.JTabbedPane;
@@ -221,24 +221,24 @@ public class ProfilesAction extends ControlPanelAction implements HumanFaceListe
     
     private void recomputePrimaryProfile() {
         //Main profile
-        CrossSectionZigZag cs = new CrossSectionZigZag(getDrawableCuttingPlane(priCuttingPlaneSlot).getPlane());
+        CrossSection cs = new CrossSection(getDrawableCuttingPlane(priCuttingPlaneSlot).getPlane());
         getPrimaryDrawableFace().getModel().compute(cs);
         this.primaryCurve = cs.getCrossSectionCurve();
 
         //Mirror profile
-        CrossSectionZigZag mcs = new CrossSectionZigZag(getDrawableCuttingPlane(priCuttingPlaneSlot).getMirrorPlane());
+        CrossSection mcs = new CrossSection(getDrawableCuttingPlane(priCuttingPlaneSlot).getMirrorPlane());
         getPrimaryDrawableFace().getModel().compute(mcs);
         this.primaryMirrorCurve = mcs.getCrossSectionCurve();
     }
 
     private void recomputeSecondaryProfile() {
         //Main profile
-        CrossSectionZigZag cs = new CrossSectionZigZag(getDrawableCuttingPlane(secCuttingPlaneSlot).getPlane());
+        CrossSection cs = new CrossSection(getDrawableCuttingPlane(secCuttingPlaneSlot).getPlane());
         getSecondaryDrawableFace().getModel().compute(cs);
         this.secondaryCurve = cs.getCrossSectionCurve();
 
         //Mirror profile
-        CrossSectionZigZag mcs = new CrossSectionZigZag(getDrawableCuttingPlane(secCuttingPlaneSlot).getMirrorPlane());
+        CrossSection mcs = new CrossSection(getDrawableCuttingPlane(secCuttingPlaneSlot).getMirrorPlane());
         getSecondaryDrawableFace().getModel().compute(mcs);
         this.secondaryMirrorCurve = mcs.getCrossSectionCurve();
     }