From 40385f4d7011b2ba94fa73da10a83e5a26b05cce Mon Sep 17 00:00:00 2001 From: Eyal Perry Date: Tue, 17 Nov 2020 23:46:35 -0500 Subject: [PATCH 01/12] fix earcut bug - check triangles for correct order corresponding to original face --- js/pattern.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/js/pattern.js b/js/pattern.js index 2d442fb..77af091 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -562,7 +562,7 @@ function initPattern(globals){ delete fold.vertices_vertices; delete fold.vertices_edges; - foldData = triangulatePolys(fold, true); + foldData = triangulatePolys(fold, false); for (var i=0;i Date: Wed, 18 Nov 2020 12:42:48 -0500 Subject: [PATCH 02/12] actually check if it's 2d or 3d before turning everything to 3d --- dependencies/fold.js | 1 + js/pattern.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dependencies/fold.js b/dependencies/fold.js index f4332ff..f90c076 100755 --- a/dependencies/fold.js +++ b/dependencies/fold.js @@ -99,6 +99,7 @@ convert.vertices_vertices_to_faces_vertices = function(fold) { if ((w != null) && geom.polygonOrientation((function() { var l, len2, results; results = []; + for (l = 0, len2 = face.length; l < len2; l++) { x = face[l]; results.push(fold.vertices_coords[x]); diff --git a/js/pattern.js b/js/pattern.js index 77af091..3c8f064 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -545,10 +545,14 @@ function initPattern(globals){ function processFold(fold, returnCreaseParams){ rawFold = JSON.parse(JSON.stringify(fold));//save pre-triangulated for for save later + + var is2d = false; + //make 3d for (var i=0;i Date: Wed, 18 Nov 2020 12:44:22 -0500 Subject: [PATCH 03/12] removed accidental newline --- dependencies/fold.js | 1 - 1 file changed, 1 deletion(-) diff --git a/dependencies/fold.js b/dependencies/fold.js index f90c076..f4332ff 100755 --- a/dependencies/fold.js +++ b/dependencies/fold.js @@ -99,7 +99,6 @@ convert.vertices_vertices_to_faces_vertices = function(fold) { if ((w != null) && geom.polygonOrientation((function() { var l, len2, results; results = []; - for (l = 0, len2 = face.length; l < len2; l++) { x = face[l]; results.push(fold.vertices_coords[x]); From 6cc39c3542bc128d42b18419db690d791e12b513 Mon Sep 17 00:00:00 2001 From: Eyal Perry Date: Wed, 18 Nov 2020 12:55:25 -0500 Subject: [PATCH 04/12] fixed! checking the edge orientation using the face instead of faceEdges --- js/pattern.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/pattern.js b/js/pattern.js index 3c8f064..2309c8e 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1029,9 +1029,9 @@ function initPattern(globals){ // we check if the first triangle contains any edge with the exact same orientation of the original face // if not, we flip all of the triangles var needsFlip = true; - for (var j=0; j Date: Sat, 21 Nov 2020 15:55:38 -0500 Subject: [PATCH 05/12] second earcut fix - since only the first two coordinates are used in triangualation (even when dim=3), it is important we give it a non degenrate face.. this commit checks which coordinates have the largest variance and rearanges the dimensions accordingly. this doesnt affect the model in anyway --- dependencies/earcut.js | 11 +++++++++- index.html | 6 +++--- js/pattern.js | 46 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/dependencies/earcut.js b/dependencies/earcut.js index 804cd94..12748b7 100755 --- a/dependencies/earcut.js +++ b/dependencies/earcut.js @@ -4,14 +4,23 @@ function earcut(data, holeIndices, dim) { + + dim = dim || 2; + console.log(dim); + var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = linkedList(data, 0, outerLen, dim, true), triangles = []; - if (!outerNode) return triangles; + if (!outerNode) { + console.log("outerNode"); + return triangles; + } + console.log("start"); + console.log(outerNode); var minX, minY, maxX, maxY, x, y, size; diff --git a/index.html b/index.html index d3a189f..fe491b4 100755 --- a/index.html +++ b/index.html @@ -1325,12 +1325,12 @@
  • edges_assignment
  • faces_vertices
  • - You may specify the target fold angle of each crease using the edges_foldAngle field. - Note that fold angle is a number in degrees lying in the range [−180, 180]. + You may specify the target fold angle of each crease using the edges_foldAngle field. + Note that fold angle is a number in degrees lying in the range [−180, 180]. The fold angle is positive for valley folds, negative for mountain folds, and zero for flat, unassigned, and border folds. Accordingly, the sign of edges_foldAngle should match edges_assignment if both are specified.

    If you are unsure whether your FOLD file is valid, you can inspect it using the - FOLD Viewer. + FOLD Viewer. If you are having trouble, please refer to the FOLD spec.

    Importing SVG:

    diff --git a/js/pattern.js b/js/pattern.js index 2309c8e..25d03e2 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1015,11 +1015,53 @@ function initPattern(globals){ } var faceVert = []; - for (var j=0;j Date: Sun, 22 Nov 2020 01:09:50 -0500 Subject: [PATCH 06/12] fix for the fix - just try all dimensions combinations until we hate a triangulation --- dependencies/earcut.js | 11 +-------- js/pattern.js | 54 ++++++++++++------------------------------ 2 files changed, 16 insertions(+), 49 deletions(-) diff --git a/dependencies/earcut.js b/dependencies/earcut.js index 12748b7..804cd94 100755 --- a/dependencies/earcut.js +++ b/dependencies/earcut.js @@ -4,23 +4,14 @@ function earcut(data, holeIndices, dim) { - - dim = dim || 2; - console.log(dim); - var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = linkedList(data, 0, outerLen, dim, true), triangles = []; - if (!outerNode) { - console.log("outerNode"); - return triangles; - } - console.log("start"); - console.log(outerNode); + if (!outerNode) return triangles; var minX, minY, maxX, maxY, x, y, size; diff --git a/js/pattern.js b/js/pattern.js index 25d03e2..9f7ea0b 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1015,57 +1015,33 @@ function initPattern(globals){ } var faceVert = []; + var triangles = []; if (is2d) { for (var j=0;j 0) { + break; } - } - for (var k=0; k<3; k++) { - ex[k] /= face.length ; - ex2[k] /= face.length; - } - var variances = []; - for (var k=0; k<3; k++) { - variances.push(Math.abs(Math.pow(ex[k], 2) - ex2[k])); - } - var a, b, c; - if (variances[2] < variances[1] && variances[2] < variances[0]) { - a = 0; - b = 1; - c = 2; - } else if (variances[1] < variances[0]) { - a = 0; - b = 2; - c = 1; - } else { - a = 2; - b = 0; - c = 1; - } - for (var j=0;j Date: Sat, 28 Nov 2020 14:22:53 -0500 Subject: [PATCH 07/12] Fix indentation to match coding style; remove unnecessary changes --- index.html | 6 +++--- js/pattern.js | 56 +++++++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/index.html b/index.html index fe491b4..d3a189f 100755 --- a/index.html +++ b/index.html @@ -1325,12 +1325,12 @@
  • edges_assignment
  • faces_vertices
  • - You may specify the target fold angle of each crease using the edges_foldAngle field. - Note that fold angle is a number in degrees lying in the range [−180, 180]. + You may specify the target fold angle of each crease using the edges_foldAngle field. + Note that fold angle is a number in degrees lying in the range [−180, 180]. The fold angle is positive for valley folds, negative for mountain folds, and zero for flat, unassigned, and border folds. Accordingly, the sign of edges_foldAngle should match edges_assignment if both are specified.

    If you are unsure whether your FOLD file is valid, you can inspect it using the - FOLD Viewer. + FOLD Viewer. If you are having trouble, please refer to the FOLD spec.

    Importing SVG:

    diff --git a/js/pattern.js b/js/pattern.js index 9f7ea0b..ce540dd 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1017,29 +1017,29 @@ function initPattern(globals){ var faceVert = []; var triangles = []; if (is2d) { - for (var j=0;j 0) { - break; + if (triangles.length > 0) { + break; + } } - } } // this fixes a bug where triangles from earcut() have backwards winding @@ -1048,21 +1048,21 @@ function initPattern(globals){ // if not, we flip all of the triangles var needsFlip = true; for (var j=0; j< face.length; j++) { - for (var k=0; k<3; k++) { - if (face[j] == face[triangles[k]] && face[(j + 1) % face.length] == face[triangles[(k + 1) % 3]]) { - needsFlip = false; - break; + for (var k=0; k<3; k++) { + if (face[j] == face[triangles[k]] && face[(j + 1) % face.length] == face[triangles[(k + 1) % 3]]) { + needsFlip = false; + break; + } } - } - if (!needsFlip) break; + if (!needsFlip) break; } for (var j=0;j Date: Sat, 28 Nov 2020 15:14:31 -0500 Subject: [PATCH 08/12] Correct is2d and needsFlip detection and y/z flipping * Correct is2d detection: 2D only if all vertices are 2D, and treat 0 the same as an absent third coordinate. * Always swap y and z coordinates when importing/exporting FOLD, independent of 2D status, for consistent behavior in all cases. (To get there, `rawFold` also has swapped coordiantes.) * To decide `needsFlip`, instead of looking for a face edge in the first triangle, which can fail if the first triangle is a fully interior triangle, look for the first edge of the face in all the triangles. --- js/pattern.js | 48 ++++++++++++++++++++++++------------------------ js/saveFOLD.js | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/js/pattern.js b/js/pattern.js index ce540dd..0ad8091 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -544,19 +544,19 @@ function initPattern(globals){ function processFold(fold, returnCreaseParams){ - rawFold = JSON.parse(JSON.stringify(fold));//save pre-triangulated for for save later - - var is2d = false; - - //make 3d - for (var i=0;i0) { fold = splitCuts(fold); @@ -1020,7 +1020,7 @@ function initPattern(globals){ for (var j=0;j 0) { - break; - } + if (triangles.length > 0) break; } } - // this fixes a bug where triangles from earcut() have backwards winding + // triangles from earcut() can have backwards winding relative to original face // [https://github.com/mapbox/earcut/issues/44] - // we check if the first triangle contains any edge with the exact same orientation of the original face - // if not, we flip all of the triangles - var needsFlip = true; - for (var j=0; j< face.length; j++) { + // we look for the first edge of the original face among the triangles; + // if it appears reversed in any triangle, we flip all triangles + var needsFlip; + for (var j=0;j Date: Sat, 28 Nov 2020 15:26:56 -0500 Subject: [PATCH 09/12] needsFlip bug fix --- js/pattern.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/pattern.js b/js/pattern.js index 0ad8091..ea120c0 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1043,7 +1043,7 @@ function initPattern(globals){ // [https://github.com/mapbox/earcut/issues/44] // we look for the first edge of the original face among the triangles; // if it appears reversed in any triangle, we flip all triangles - var needsFlip; + var needsFlip = null; for (var j=0;j Date: Sun, 29 Nov 2020 10:10:35 -0500 Subject: [PATCH 10/12] Revert 2D -> 3D mapping instead of y/z swap Swapping y/z flips the coordinate system between left- and right-handed, effectively reversing the notions of cw/ccw. This isn't an issue in 2D, because there it would be the same as mapping (x, y, z) → (x, -z, y) (because z=0) which doesn't flip handedness, but it's a problem in 3D. --- js/pattern.js | 20 ++++++++------------ js/saveFOLD.js | 2 +- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/js/pattern.js b/js/pattern.js index ea120c0..03a2e02 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -544,14 +544,17 @@ function initPattern(globals){ function processFold(fold, returnCreaseParams){ - //add missing coordinates to make 3d, and flip y and z for internal use - //FOLD spec says that, beyond two dimensions, - //"all unspecified coordinates are implicitly zero" + //add missing coordinates to make 3d, mapping (x,y) -> (x,0,z) + //This is against the FOLD spec which says that, beyond two dimensions, + //"all unspecified coordinates are implicitly zero"... var is2d = true; for (var i=0;i Date: Sun, 29 Nov 2020 16:39:01 -0500 Subject: [PATCH 11/12] earcut sometimes returns less triangles than needed to cover the face (because of it using only the first two coordinates, and possible degeneracies there). this update makes sure there are at least enough triangles before breaking --- js/pattern.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/pattern.js b/js/pattern.js index 03a2e02..2a11641 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1031,7 +1031,8 @@ function initPattern(globals){ faceVert.push(vertex[(j + 2) % 3]); } triangles = earcut(faceVert, null, 3); - if (triangles.length > 0) break; + // make sure we got *enough* triangle to cover the face + if (triangles.length >= 3 * (face.length - 2)) break; } } From 18a0313ed373c7ee9f763cdbf371c905e6a8baed Mon Sep 17 00:00:00 2001 From: Eyal Perry Date: Mon, 30 Nov 2020 00:10:16 -0500 Subject: [PATCH 12/12] check dimension combination starting from [2,0,1] to [1, 2, 0] to [0, 1, 2] --- js/pattern.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/pattern.js b/js/pattern.js index 2a11641..a82dc49 100755 --- a/js/pattern.js +++ b/js/pattern.js @@ -1022,7 +1022,7 @@ function initPattern(globals){ } else { // earcut only uses the two first coordinates for triangulation... // as a fix, we try each of the dimension combinations until we get a result - for (var j=0; j<3; j++) { + for (var j=2; j>=0; j--) { faceVert = []; for (var k=0;k