From 1b254bc73d8c78438a0ee95a189efd1b1ed089f8 Mon Sep 17 00:00:00 2001 From: Nils Schmidt Date: Sun, 25 Sep 2016 15:33:23 +0200 Subject: [PATCH] Fixed issue #456. --- src/org/nschmidt/csg/Polygon.java | 2 +- .../nschmidt/ldparteditor/data/GData3.java | 31 +++++- .../nschmidt/ldparteditor/data/GData4.java | 48 +++++++--- .../nschmidt/ldparteditor/data/VM02Add.java | 90 ++++++++++++++---- .../ldparteditor/data/VM04Rectifier.java | 94 ++++++++++++------- .../data/VM12IntersectorAndIsecalc.java | 61 +++++++++--- .../helpers/compositetext/ErrorFixer.java | 86 +++++++++-------- .../nschmidt/ldparteditor/text/DatParser.java | 94 +++++++++++++------ .../ldparteditor/text/SyntaxFormatter.java | 85 ++++++++++++----- 9 files changed, 418 insertions(+), 173 deletions(-) diff --git a/src/org/nschmidt/csg/Polygon.java b/src/org/nschmidt/csg/Polygon.java index 6749b59df..8f0b43281 100644 --- a/src/org/nschmidt/csg/Polygon.java +++ b/src/org/nschmidt/csg/Polygon.java @@ -212,7 +212,7 @@ public HashMap toLDrawTriangles2(GData1 parent) { org.nschmidt.ldparteditor.helpers.math.Vector3d.sub(vertexB, vertexC, vertexB); boolean parseError = org.nschmidt.ldparteditor.helpers.math.Vector3d.angle(vertexA, vertexB) < Threshold.collinear_angle_minimum; - parseError = parseError ||vertexA.length().compareTo(identical_vertex_distance) < 0; + parseError = parseError || vertexA.length().compareTo(identical_vertex_distance) < 0; parseError = parseError || vertexB.length().compareTo(identical_vertex_distance) < 0; parseError = parseError || org.nschmidt.ldparteditor.helpers.math.Vector3d.sub(vertexA, vertexB).length().compareTo(identical_vertex_distance) < 0; diff --git a/src/org/nschmidt/ldparteditor/data/GData3.java b/src/org/nschmidt/ldparteditor/data/GData3.java index 645ea07fc..b2ab01d57 100644 --- a/src/org/nschmidt/ldparteditor/data/GData3.java +++ b/src/org/nschmidt/ldparteditor/data/GData3.java @@ -1484,14 +1484,35 @@ public void getVertexNormalMapNOCLIP(GDataState state, ThreadsafeTreeMap Threshold.collinear_angle_maximum) { + return true; + } + + A.negate(); + angle = Vector3d.angle(A, B); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + return true; + } + + angle = 180.0 - sumAngle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + return true; + } + return false; } public String colourReplace(String col) { diff --git a/src/org/nschmidt/ldparteditor/data/GData4.java b/src/org/nschmidt/ldparteditor/data/GData4.java index fe53e896c..6e6016568 100644 --- a/src/org/nschmidt/ldparteditor/data/GData4.java +++ b/src/org/nschmidt/ldparteditor/data/GData4.java @@ -1150,13 +1150,13 @@ public void drawGL20_BFC_Textured(Composite3D c3d) { tex.calcUVcoords4(x4, y4, z4, parent); uv = tex.getUVcoords(false, this); GL11.glTexCoord2f(uv[0], uv[1]); - c3d.getVertexManager().setVertexAndNormal(x1, y1, z1, false, this, useCubeMap); + c3d.getVertexManager().setVertexAndNormal(x1, y1, z1, true, this, useCubeMap); GL11.glTexCoord2f(uv[2], uv[3]); - c3d.getVertexManager().setVertexAndNormal(x2, y2, z2, false, this, useCubeMap); + c3d.getVertexManager().setVertexAndNormal(x2, y2, z2, true, this, useCubeMap); GL11.glTexCoord2f(uv[4], uv[5]); - c3d.getVertexManager().setVertexAndNormal(x3, y3, z3, false, this, useCubeMap); + c3d.getVertexManager().setVertexAndNormal(x3, y3, z3, true, this, useCubeMap); GL11.glTexCoord2f(uv[6], uv[7]); - c3d.getVertexManager().setVertexAndNormal(x4, y4, z4, false, this, useCubeMap); + c3d.getVertexManager().setVertexAndNormal(x4, y4, z4, true, this, useCubeMap); GL11.glEnd(); } else { GL11.glColor4f(r, g, b, a); @@ -1632,15 +1632,37 @@ public boolean isCollinear() { Vector3d vertexB = new Vector3d(X2, Y2, Z2); Vector3d vertexC = new Vector3d(X3, Y3, Z3); Vector3d vertexD = new Vector3d(X4, Y4, Z4); - Vector3d.sub(vertexA, vertexD, vertexA); - Vector3d.sub(vertexB, vertexD, vertexB); - Vector3d.sub(vertexC, vertexD, vertexC); - boolean parseError = false; - parseError = Vector3d.angle(vertexA, vertexB) < Threshold.collinear_angle_minimum; - parseError = parseError || Vector3d.angle(vertexB, vertexC) < Threshold.collinear_angle_minimum; - parseError = parseError || 180.0 - Vector3d.angle(vertexA, vertexC) < Threshold.collinear_angle_minimum; - parseError = parseError || 180.0 - Vector3d.angle(Vector3d.sub(vertexC, vertexB), Vector3d.sub(vertexA, vertexB)) < Threshold.collinear_angle_minimum; - return parseError; + Vector3d A = Vector3d.sub(vertexB, vertexA); + Vector3d B = Vector3d.sub(vertexB, vertexC); + Vector3d C = Vector3d.sub(vertexD, vertexC); + Vector3d D = Vector3d.sub(vertexD, vertexA); + + double angle = Vector3d.angle(A, D); + double sumAngle = angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + return true; + } + + angle = Vector3d.angle(B, C); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + return true; + } + + A.negate(); + B.negate(); + angle = Vector3d.angle(A, B); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + return true; + } + + angle = 360.0 - sumAngle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + return true; + } + + return false; } public int getHourglassConfiguration() { diff --git a/src/org/nschmidt/ldparteditor/data/VM02Add.java b/src/org/nschmidt/ldparteditor/data/VM02Add.java index 022a35e22..6c51d295c 100644 --- a/src/org/nschmidt/ldparteditor/data/VM02Add.java +++ b/src/org/nschmidt/ldparteditor/data/VM02Add.java @@ -406,17 +406,41 @@ public void addTriangle(Vertex v1, Vertex v2, Vertex v3, Composite3D c3d, boolea } // Resolving Collinearity - Vector3f v13f = new Vector3f(v1.x, v1.y, v1.z); - Vector3f v23f = new Vector3f(v2.x, v2.y, v2.z); - Vector3f v33f = new Vector3f(v3.x, v3.y, v3.z); - Vector3f.sub(v13f, v33f, v13f); - Vector3f.sub(v23f, v33f, v23f); - double angle = Vector3f.angle(v13f, v23f) * 180d / Math.PI;; - if (angle < Threshold.collinear_angle_minimum && !allowInvalidShapes) { + double angle; + Vector3f a = new Vector3f(); + Vector3f b = new Vector3f(); + Vector3f c = new Vector3f(); + + { + Vector3f v13f = new Vector3f(v1.x, v1.y, v1.z); + Vector3f v23f = new Vector3f(v2.x, v2.y, v2.z); + Vector3f v33f = new Vector3f(v3.x, v3.y, v3.z); + Vector3f.sub(v23f, v13f, a); + Vector3f.sub(v33f, v23f, b); + Vector3f.sub(v33f, v13f, c); + } + + angle = Vector3f.angle(a, c) * 180d / Math.PI; + double sumAngle = angle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { linkedDatFile.setObjVertex3(null); return; } - + + a.negate(); + angle = Vector3f.angle(a, b) * 180d / Math.PI; + sumAngle = sumAngle + angle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { + linkedDatFile.setObjVertex3(null); + return; + } + + angle = 180.0 - sumAngle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { + linkedDatFile.setObjVertex3(null); + return; + } + Vector4f n = new Vector4f(); n.setW(1f); n.setX((v3.y - v1.y) * (v2.z - v1.z) - (v3.z - v1.z) * (v2.y - v1.y)); @@ -610,19 +634,45 @@ public void addQuad(Vertex v1, Vertex v2, Vertex v3, Vertex v4, Composite3D c3d) double angle2 = Vector3f.angle(normals[0], normals[2]) * 180d / Math.PI; double angle; - boolean parseError = false; - Vector3f.sub(v13f, v43f, v13f); - Vector3f.sub(v23f, v43f, v23f); - Vector3f.sub(v33f, v43f, v33f); - angle = Vector3f.angle(v13f, v23f) * 180d / Math.PI;; - parseError = angle < Threshold.collinear_angle_minimum; - angle = Vector3f.angle(v23f, v33f) * 180d / Math.PI;; - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = Vector3f.angle(v33f, v13f) * 180d / Math.PI;; - parseError = parseError || angle < Threshold.collinear_angle_minimum; - // Collinearity - if (parseError && !allowInvalidShapes) { + Vector3f a = new Vector3f(); + Vector3f b = new Vector3f(); + Vector3f c = new Vector3f(); + Vector3f d = new Vector3f(); + + Vector3f.sub(v23f, v13f, a); + Vector3f.sub(v23f, v33f, b); + Vector3f.sub(v43f, v33f, c); + Vector3f.sub(v43f, v13f, d); + + angle = Vector3f.angle(a, d) * 180d / Math.PI; + double sumAngle = angle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { + linkedDatFile.setObjVertex3(null); + linkedDatFile.setObjVertex4(null); + return; + } + + angle = Vector3f.angle(b, c) * 180d / Math.PI; + sumAngle = sumAngle + angle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { + linkedDatFile.setObjVertex3(null); + linkedDatFile.setObjVertex4(null); + return; + } + + a.negate(); + b.negate(); + angle = Vector3f.angle(a, b) * 180d / Math.PI; + sumAngle = sumAngle + angle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { + linkedDatFile.setObjVertex3(null); + linkedDatFile.setObjVertex4(null); + return; + } + + angle = 360.0 - sumAngle; + if ((angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) && !allowInvalidShapes) { linkedDatFile.setObjVertex3(null); linkedDatFile.setObjVertex4(null); return; diff --git a/src/org/nschmidt/ldparteditor/data/VM04Rectifier.java b/src/org/nschmidt/ldparteditor/data/VM04Rectifier.java index 37667adbb..a325334ea 100644 --- a/src/org/nschmidt/ldparteditor/data/VM04Rectifier.java +++ b/src/org/nschmidt/ldparteditor/data/VM04Rectifier.java @@ -207,26 +207,39 @@ public void run(final IProgressMonitor monitor) throws InvocationTargetException // Concave continue; } + + angle = Vector3d.angle(normals[0], normals[2]); + if (angle > targetAngle) continue; + + Vector3d A = Vector3d.sub(vertexB, vertexA); + Vector3d B = Vector3d.sub(vertexB, vertexC); + Vector3d C = Vector3d.sub(vertexD, vertexC); + Vector3d D = Vector3d.sub(vertexD, vertexA); - Vector3d.sub(vertexA, vertexD, vertexA); - Vector3d.sub(vertexB, vertexD, vertexB); - Vector3d.sub(vertexC, vertexD, vertexC); - - boolean parseError = false; - angle = Vector3d.angle(vertexA, vertexB); // AB - parseError = angle < Threshold.collinear_angle_minimum; - angle = Vector3d.angle(vertexB, vertexC); // BC - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(vertexA, vertexC); // 180 - AC - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(Vector3d.sub(vertexC, vertexB), Vector3d.sub(vertexA, vertexB)); // 180 - (C-B)(A-B) - parseError = parseError || angle < Threshold.collinear_angle_minimum; - if (parseError) { + angle = Vector3d.angle(A, D); + double sumAngle = angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + angle = Vector3d.angle(B, C); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + A.negate(); + B.negate(); + angle = Vector3d.angle(A, B); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + angle = 360.0 - sumAngle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { continue; } - - angle = Vector3d.angle(normals[0], normals[2]); - if (angle > targetAngle) continue; BigDecimal m1 = Vector3d.distSquare(new Vector3d(first), new Vector3d(third)).add(BigDecimal.ONE); BigDecimal m2 = Vector3d.distSquare(new Vector3d(second), new Vector3d(fourth)).add(BigDecimal.ONE); @@ -685,25 +698,38 @@ public void run(final IProgressMonitor monitor) throws InvocationTargetException continue; } - Vector3d.sub(vertexA, vertexD, vertexA); - Vector3d.sub(vertexB, vertexD, vertexB); - Vector3d.sub(vertexC, vertexD, vertexC); - - boolean parseError = false; - angle = Vector3d.angle(vertexA, vertexB); // AB - parseError = angle < Threshold.collinear_angle_minimum; - angle = Vector3d.angle(vertexB, vertexC); // BC - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(vertexA, vertexC); // 180 - AC - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(Vector3d.sub(vertexC, vertexB), Vector3d.sub(vertexA, vertexB)); // 180 - (C-B)(A-B) - parseError = parseError || angle < Threshold.collinear_angle_minimum; - if (parseError) { - continue; - } - angle = Vector3d.angle(normals[0], normals[2]); if (angle > targetAngle) continue; + + Vector3d A = Vector3d.sub(vertexB, vertexA); + Vector3d B = Vector3d.sub(vertexB, vertexC); + Vector3d C = Vector3d.sub(vertexD, vertexC); + Vector3d D = Vector3d.sub(vertexD, vertexA); + + angle = Vector3d.angle(A, D); + double sumAngle = angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + angle = Vector3d.angle(B, C); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + A.negate(); + B.negate(); + angle = Vector3d.angle(A, B); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + angle = 360.0 - sumAngle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } BigDecimal m1 = Vector3d.distSquare(new Vector3d(first), new Vector3d(third)).add(BigDecimal.ONE); BigDecimal m2 = Vector3d.distSquare(new Vector3d(second), new Vector3d(fourth)).add(BigDecimal.ONE); diff --git a/src/org/nschmidt/ldparteditor/data/VM12IntersectorAndIsecalc.java b/src/org/nschmidt/ldparteditor/data/VM12IntersectorAndIsecalc.java index af7fd526a..c58b2f9bb 100644 --- a/src/org/nschmidt/ldparteditor/data/VM12IntersectorAndIsecalc.java +++ b/src/org/nschmidt/ldparteditor/data/VM12IntersectorAndIsecalc.java @@ -1287,14 +1287,34 @@ private IntersectionInfoWithColour getIntersectionInfo(GData origin, HashSet Threshold.collinear_angle_maximum) { + continue; + } + + A.negate(); + angle = Vector3d.angle(A, B); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + angle = 180.0 - sumAngle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } } if (MathHelper.directionOfVectors(normal, originalNormal) == 1) { @@ -1307,7 +1327,6 @@ private IntersectionInfoWithColour getIntersectionInfo(GData origin, HashSet Threshold.collinear_angle_maximum) { + continue; + } + + A.negate(); + angle = Vector3d.angle(A, B); + sumAngle = sumAngle + angle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } + + angle = 180.0 - sumAngle; + if (angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum) { + continue; + } } { diff --git a/src/org/nschmidt/ldparteditor/helpers/compositetext/ErrorFixer.java b/src/org/nschmidt/ldparteditor/helpers/compositetext/ErrorFixer.java index 99a152d20..4458a9306 100644 --- a/src/org/nschmidt/ldparteditor/helpers/compositetext/ErrorFixer.java +++ b/src/org/nschmidt/ldparteditor/helpers/compositetext/ErrorFixer.java @@ -272,25 +272,37 @@ public static String fix(int lineNumber, String sort, String line, String text, Vertex C = new Vertex(vertexC.X, vertexC.Y, vertexC.Z); Vertex D = new Vertex(vertexD.X, vertexD.Y, vertexD.Z); - Vector3d.sub(vertexA, vertexD, vertexA); - Vector3d.sub(vertexB, vertexD, vertexB); - Vector3d.sub(vertexC, vertexD, vertexC); - - double angle = Vector3d.angle(vertexA, vertexB); - boolean AB = angle < Threshold.collinear_angle_minimum; + Vector3d.sub(vertexB, vertexA, vertexA); + Vector3d.sub(vertexB, vertexC, vertexB); + Vector3d.sub(vertexD, vertexC, vertexC); + Vector3d.sub(vertexD, new Vector3d(A), vertexD); + + + boolean pointA, pointC, pointB, pointD; + double angle = Vector3d.angle(vertexA, vertexD); + double sumAngle = angle; + pointA = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + angle = Vector3d.angle(vertexB, vertexC); - boolean BC = angle < Threshold.collinear_angle_minimum; - boolean ACD = 180.0 - Vector3d.angle(vertexC, vertexA) < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(Vector3d.sub(vertexC, vertexB), Vector3d.sub(vertexA, vertexB)); // 180 - (C-B)(A-B) - boolean ACB = angle < Threshold.collinear_angle_minimum; - + sumAngle = sumAngle + angle; + pointC = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + vertexA.negate(); + vertexB.negate(); + angle = Vector3d.angle(vertexA, vertexB); + sumAngle = sumAngle + angle; + pointB = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + angle = 360.0 - sumAngle; + pointD = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + VertexManager vm = datFile.getVertexManager(); - if (AB && (BC || ACD || ACB) || BC && (ACD || ACB) || ACD && ACB) { + if (pointA && (pointC || pointB || pointD) || pointC && (pointB || pointD) || pointB && pointD) { text = QuickFixer.setLine(lineNumber + 1, "", text); //$NON-NLS-1$ - } else if (AB) { - NLogger.debug(ErrorFixer.class, "AB"); //$NON-NLS-1$ - if (vm.linkedCommonFaces(A, B).size() == 1 && vm.linkedCommonFaces(D, A).size() == 1) { + } else if (pointA) { + NLogger.debug(ErrorFixer.class, "Point A"); //$NON-NLS-1$ + if (vm.linkedCommonFaces(D, A).size() == 1 && vm.linkedCommonFaces(A, B).size() == 1) { text = QuickFixer.setLine(lineNumber + 1, "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ data_segments[5] + " " + data_segments[6] + " " + data_segments[7] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ data_segments[8] + " " + data_segments[9] + " " + data_segments[10] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -307,8 +319,26 @@ public static String fix(int lineNumber, String sort, String line, String text, data_segments[2] + " " + data_segments[3] + " " + data_segments[4], text); //$NON-NLS-1$ //$NON-NLS-2$ } - } else if (BC) { - NLogger.debug(ErrorFixer.class, "BC"); //$NON-NLS-1$ + } else if (pointB) { + NLogger.debug(ErrorFixer.class, "Point B"); //$NON-NLS-1$ + if (vm.linkedCommonFaces(A, B).size() == 1 && vm.linkedCommonFaces(B, C).size() == 1) { + text = QuickFixer.setLine(lineNumber + 1, "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ + data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + data_segments[8] + " " + data_segments[9] + " " + data_segments[10] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + data_segments[11] + " " + data_segments[12] + " " + data_segments[13], text); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + text = QuickFixer.setLine(lineNumber + 1, + "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ + data_segments[5] + " " + data_segments[6] + " " + data_segments[7] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + data_segments[8] + " " + data_segments[9] + " " + data_segments[10] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + data_segments[11] + " " + data_segments[12] + " " + data_segments[13] + //$NON-NLS-1$ //$NON-NLS-2$ + "
3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ + data_segments[11] + " " + data_segments[12] + " " + data_segments[13] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + data_segments[5] + " " + data_segments[6] + " " + data_segments[7], text); //$NON-NLS-1$ //$NON-NLS-2$ + } + } else if (pointC) { + NLogger.debug(ErrorFixer.class, "Point C"); //$NON-NLS-1$ if (vm.linkedCommonFaces(B, C).size() == 1 && vm.linkedCommonFaces(C, D).size() == 1) { text = QuickFixer.setLine(lineNumber + 1, "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -326,8 +356,8 @@ public static String fix(int lineNumber, String sort, String line, String text, data_segments[2] + " " + data_segments[3] + " " + data_segments[4], text); //$NON-NLS-1$ //$NON-NLS-2$ } - } else if (ACD) { - NLogger.debug(ErrorFixer.class, "ACD"); //$NON-NLS-1$ + } else if (pointD) { + NLogger.debug(ErrorFixer.class, "Point D"); //$NON-NLS-1$ if (vm.linkedCommonFaces(C, D).size() == 1 && vm.linkedCommonFaces(D, A).size() == 1) { text = QuickFixer.setLine(lineNumber + 1, "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -344,24 +374,6 @@ public static String fix(int lineNumber, String sort, String line, String text, data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ data_segments[5] + " " + data_segments[6] + " " + data_segments[7], text); //$NON-NLS-1$ //$NON-NLS-2$ } - } else if (ACB) { - NLogger.debug(ErrorFixer.class, "ACB"); //$NON-NLS-1$ - if (vm.linkedCommonFaces(A, B).size() == 1 && vm.linkedCommonFaces(B, C).size() == 1) { - text = QuickFixer.setLine(lineNumber + 1, "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ - data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - data_segments[8] + " " + data_segments[9] + " " + data_segments[10] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - data_segments[11] + " " + data_segments[12] + " " + data_segments[13], text); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - text = QuickFixer.setLine(lineNumber + 1, - "3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ - data_segments[5] + " " + data_segments[6] + " " + data_segments[7] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - data_segments[8] + " " + data_segments[9] + " " + data_segments[10] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - data_segments[11] + " " + data_segments[12] + " " + data_segments[13] + //$NON-NLS-1$ //$NON-NLS-2$ - "
3 " + data_segments[1] + " " + //$NON-NLS-1$ //$NON-NLS-2$ - data_segments[11] + " " + data_segments[12] + " " + data_segments[13] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - data_segments[2] + " " + data_segments[3] + " " + data_segments[4] + " " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - data_segments[5] + " " + data_segments[6] + " " + data_segments[7], text); //$NON-NLS-1$ //$NON-NLS-2$ - } } } break; diff --git a/src/org/nschmidt/ldparteditor/text/DatParser.java b/src/org/nschmidt/ldparteditor/text/DatParser.java index cc0f59e21..1b04f5a7b 100644 --- a/src/org/nschmidt/ldparteditor/text/DatParser.java +++ b/src/org/nschmidt/ldparteditor/text/DatParser.java @@ -953,16 +953,35 @@ private static ArrayList parse_Triangle(String[] data_segments, f } if (depth < 1) { boolean parseError = false; + double angle; + Vector3d.sub(vertexA, vertexC, vertexA2); Vector3d.sub(vertexB, vertexC, vertexB2); - double angle = Vector3d.angle(vertexA2, vertexB2); - parseError = parseError || angle < Threshold.collinear_angle_minimum; + Vector3d.sub(vertexB, vertexA, vertexC2); + + angle = Vector3d.angle(vertexA2, vertexB2); + double sumAngle = angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + if (!parseError) { + vertexA2.negate(); + angle = Vector3d.angle(vertexA2, vertexC2); + sumAngle = sumAngle + angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + + if (!parseError) { + angle = 180.0 - sumAngle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + if (parseError) { result.add(new ParsingResult(I18n.DATPARSER_CollinearVertices, "[E01] " + I18n.DATPARSER_LogicError, ResultType.ERROR)); //$NON-NLS-1$ } + parseError = vertexA2.length().compareTo(Threshold.identical_vertex_distance) < 0; parseError = parseError || vertexB2.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexA2, vertexB2).length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexC2.length().compareTo(Threshold.identical_vertex_distance) < 0; if (parseError) { result.add(new ParsingResult(I18n.DATPARSER_IdenticalVertices, "[E0D] " + I18n.DATPARSER_DataError, ResultType.ERROR)); //$NON-NLS-1$ } @@ -1101,28 +1120,9 @@ private static ArrayList parse_Quad(String[] data_segments, float // Concave result.add(new ParsingResult(I18n.DATPARSER_ConcaveQuadrilateral, "[E04] " + I18n.DATPARSER_DataError, ResultType.ERROR)); //$NON-NLS-1$ } - double angle; - - Vector3d.sub(vertexA, vertexD, vertexA); - Vector3d.sub(vertexB, vertexD, vertexB); - Vector3d.sub(vertexC, vertexD, vertexC); - - if (!parseError) { - angle = Vector3d.angle(vertexA, vertexB); // AB - parseError = angle < Threshold.collinear_angle_minimum; - angle = Vector3d.angle(vertexB, vertexC); // BC - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(vertexA, vertexC); // 180 - AC - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = 180.0 - Vector3d.angle(Vector3d.sub(vertexC, vertexB), Vector3d.sub(vertexA, vertexB)); // 180 - (C-B)(A-B) - parseError = parseError || angle < Threshold.collinear_angle_minimum; - - if (parseError) { - result.add(new ParsingResult(I18n.DATPARSER_CollinearVertices, "[E34] " + I18n.DATPARSER_DataError, ResultType.ERROR)); //$NON-NLS-1$ - } - } - + double angle; + // Coplanarity if (!parseError) { @@ -1135,13 +1135,47 @@ private static ArrayList parse_Quad(String[] data_segments, float parseWarning = false; } } + + Vector3d.sub(vertexB, vertexA, vertexA2); + Vector3d.sub(vertexB, vertexC, vertexB2); + Vector3d.sub(vertexD, vertexC, vertexC2); + Vector3d.sub(vertexD, vertexA, vertexD2); + + if (!parseError) { + + angle = Vector3d.angle(vertexA2, vertexD2); + double sumAngle = angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + if (!parseError) { + angle = Vector3d.angle(vertexB2, vertexC2); + sumAngle = sumAngle + angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + + if (!parseError) { + vertexA2.negate(); + vertexB2.negate(); + angle = Vector3d.angle(vertexA2, vertexB2); + sumAngle = sumAngle + angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + } + + if (!parseError) { + angle = 360.0 - sumAngle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } - parseError = vertexA.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || vertexB.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || vertexC.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexA, vertexB).length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexB, vertexC).length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexA, vertexC).length().compareTo(Threshold.identical_vertex_distance) < 0; + if (parseError) { + result.add(new ParsingResult(I18n.DATPARSER_CollinearVertices, "[E34] " + I18n.DATPARSER_DataError, ResultType.ERROR)); //$NON-NLS-1$ + } + } + + parseError = vertexA2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexB2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexC2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexD2.length().compareTo(Threshold.identical_vertex_distance) < 0; if (parseError) { if (!errorCheckOnly) { ParsingResult p1 = result.get(0); diff --git a/src/org/nschmidt/ldparteditor/text/SyntaxFormatter.java b/src/org/nschmidt/ldparteditor/text/SyntaxFormatter.java index c412d3386..dfb5482c0 100644 --- a/src/org/nschmidt/ldparteditor/text/SyntaxFormatter.java +++ b/src/org/nschmidt/ldparteditor/text/SyntaxFormatter.java @@ -55,6 +55,10 @@ public class SyntaxFormatter { private final Vector3d vertexB = new Vector3d(); private final Vector3d vertexC = new Vector3d(); private final Vector3d vertexD = new Vector3d(); + private final Vector3d vertexA2 = new Vector3d(); + private final Vector3d vertexB2 = new Vector3d(); + private final Vector3d vertexC2 = new Vector3d(); + private final Vector3d vertexD2 = new Vector3d(); private final Vector3d controlI = new Vector3d(); private final Vector3d controlII = new Vector3d(); @@ -927,13 +931,30 @@ private void formatTriangle(ArrayList styles, LineStyleEvent e, Stri setBorderStyle(styles.get(11)); } } - Vector3d.sub(vertexA, vertexC, vertexA); - Vector3d.sub(vertexB, vertexC, vertexB); - double angle = Vector3d.angle(vertexA, vertexB); - parseError = parseError || angle < Threshold.collinear_angle_minimum; - parseError = parseError || vertexA.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || vertexB.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexA, vertexB, null).length().compareTo(Threshold.identical_vertex_distance) < 0; + + Vector3d.sub(vertexA, vertexC, vertexA2); + Vector3d.sub(vertexB, vertexC, vertexB2); + Vector3d.sub(vertexB, vertexA, vertexC2); + + double angle = Vector3d.angle(vertexA2, vertexB2); + double sumAngle = angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + if (!parseError) { + vertexA2.negate(); + angle = Vector3d.angle(vertexA2, vertexC2); + sumAngle = sumAngle + angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + + if (!parseError) { + angle = 180.0 - sumAngle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + + parseError = parseError || vertexA2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexB2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexC2.length().compareTo(Threshold.identical_vertex_distance) < 0; break; } } @@ -1156,21 +1177,41 @@ private void formatQuad(ArrayList styles, LineStyleEvent e, String[] // Coplanarity parseWarning = angle > Threshold.coplanarity_angle_warning; parseError = parseError || angle > Threshold.coplanarity_angle_error; - Vector3d.sub(vertexA, vertexD, vertexA); - Vector3d.sub(vertexB, vertexD, vertexB); - Vector3d.sub(vertexC, vertexD, vertexC); - // Collinearity (please note that this is not a full test, but it is sufficient to detect an error) - angle = Vector3d.angle(vertexA, vertexB); - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = Vector3d.angle(vertexB, vertexC); - parseError = parseError || angle < Threshold.collinear_angle_minimum; - angle = Vector3d.angle(vertexC, vertexA); - parseError = parseError || angle < Threshold.collinear_angle_minimum; - parseError = parseError || vertexA.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || vertexB.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || vertexC.length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexA, vertexB, null).length().compareTo(Threshold.identical_vertex_distance) < 0; - parseError = parseError || Vector3d.sub(vertexB, vertexC, null).length().compareTo(Threshold.identical_vertex_distance) < 0; + + Vector3d.sub(vertexB, vertexA, vertexA2); + Vector3d.sub(vertexB, vertexC, vertexB2); + Vector3d.sub(vertexD, vertexC, vertexC2); + Vector3d.sub(vertexD, vertexA, vertexD2); + + // Collinearity + angle = Vector3d.angle(vertexA2, vertexD2); + double sumAngle = angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + if (!parseError) { + angle = Vector3d.angle(vertexB2, vertexC2); + sumAngle = sumAngle + angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + + if (!parseError) { + vertexA2.negate(); + vertexB2.negate(); + angle = Vector3d.angle(vertexA2, vertexB2); + sumAngle = sumAngle + angle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + + } + + if (!parseError) { + angle = 360.0 - sumAngle; + parseError = angle < Threshold.collinear_angle_minimum || angle > Threshold.collinear_angle_maximum; + } + + parseError = parseError || vertexA2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexB2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexC2.length().compareTo(Threshold.identical_vertex_distance) < 0; + parseError = parseError || vertexD2.length().compareTo(Threshold.identical_vertex_distance) < 0; break; } }