diff --git a/CADability/BSpline.cs b/CADability/BSpline.cs index c6e45e38..193b4018 100644 --- a/CADability/BSpline.cs +++ b/CADability/BSpline.cs @@ -75,7 +75,6 @@ public class BSpline : IGeoObjectImpl, IColorDef, ILineWidth, ILinePattern, ISer private GeoPoint[] interpol; // Interpolation mit einer gewissen Genauigkeit private GeoVector[] interdir; // Interpolation mit einer gewissen Genauigkeit private double[] interparam; // die Parameter zur Interpolation - private double maxInterpolError; // der größte Fehler bei der Interpolation private BoundingCube extent; private TetraederHull tetraederHull; private GeoPoint[] approximation; // Interpolation mit der Genauigkeit der Auflösung @@ -517,7 +516,6 @@ private void InvalidateSecondaryData() interdir = null; interparam = null; approximation = null; - maxInterpolError = 0.0; extent = BoundingCube.EmptyBoundingCube; tetraederHull = null; extrema = null; @@ -551,7 +549,6 @@ public Changing(BSpline bSpline, bool keepNurbs) bSpline.interpol = null; bSpline.interdir = null; bSpline.interparam = null; - bSpline.maxInterpolError = 0.0; if (!keepNurbs) { bSpline.nubs3d = null; @@ -3085,6 +3082,9 @@ CADability.Curve2D.ICurve2D ICurve.GetProjectedCurve(Plane p) if (throughPoints2d.Count < 2) { return new Line2D(p.Project((this as ICurve).StartPoint), p.Project((this as ICurve).EndPoint)); + + //Unreachable code + /* return null; double prec = this.GetExtent(Precision.eps).Size * 1e-4; ICurve approx = (this as ICurve).Approximate(false, prec); @@ -3095,7 +3095,7 @@ CADability.Curve2D.ICurve2D ICurve.GetProjectedCurve(Plane p) p2d.Reduce(prec); // vereinfacht den Pfad selbst, also res if (p2d.SubCurvesCount == 1) return p2d.SubCurves[0]; } - return res; + return res;*/ } } try diff --git a/CADability/BSpline2D.cs b/CADability/BSpline2D.cs index faa928cd..66234298 100644 --- a/CADability/BSpline2D.cs +++ b/CADability/BSpline2D.cs @@ -86,6 +86,9 @@ private void MakeFlat() knotslist.Add(knots[i]); } } + + //Unreachable code + /* if (false) // periodic ist nur eine Info, der Spline selbst ist doch immer geclampet, oder? // if (periodic) { @@ -107,10 +110,14 @@ private void MakeFlat() ++secondknotindex; } } + */ + if (weights == null) { GeoPoint2D[] npoles; - if (false) + + //Unreachable code + /* if (false) //if (periodic) { npoles = new GeoPoint2D[poles.Length + degree]; @@ -131,22 +138,25 @@ private void MakeFlat() //{ // das kommt bei STEP/piece0 z.B. vor, kommt ja nur über OpenCascade // knotslist.Insert(0, knotslist[0]); //} - } - else - { + }*/ + //else + //{ + npoles = new GeoPoint2D[poles.Length]; for (int i = 0; i < poles.Length; ++i) { npoles[i] = poles[i]; } - } + //} this.nubs = new Nurbs(degree, npoles, knotslist.ToArray()); nubs.InitDeriv1(); } else { GeoPoint2DH[] npoles; - if (false) + + //Unreachable code + /*if (false) // if (periodic) { npoles = new GeoPoint2DH[poles.Length + degree]; @@ -161,13 +171,13 @@ private void MakeFlat() // s.o. } else - { + {*/ npoles = new GeoPoint2DH[poles.Length]; for (int i = 0; i < poles.Length; ++i) { npoles[i] = new GeoPoint2DH(poles[i], weights[i]); } - } + //} this.nurbs = new Nurbs(degree, npoles, knotslist.ToArray()); nurbs.InitDeriv1(); } @@ -606,7 +616,7 @@ public BSpline2D(GeoPoint2D[] poles, double[] weights, double[] knots, int[] mul { Init(); } - catch (NurbsException ne) + catch (NurbsException) { } // sollte durch Start/Endparameter nur ein Teilbereich des Splines gelten, dann diff --git a/CADability/Block.cs b/CADability/Block.cs index cbec5a0a..dc551b84 100644 --- a/CADability/Block.cs +++ b/CADability/Block.cs @@ -751,7 +751,7 @@ protected Block(SerializationInfo info, StreamingContext context) name = (string)info.GetValue("Name", typeof(string)); // FinishDeserialization.AddToContext(context,this); } - catch (SerializationException ex) + catch (SerializationException) { SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) diff --git a/CADability/Border.cs b/CADability/Border.cs index 8fe378eb..51dc7563 100644 --- a/CADability/Border.cs +++ b/CADability/Border.cs @@ -3676,6 +3676,8 @@ internal Border[] RemoveConstrictions(double precision) List res = new List(); double len = this.Extent.Size; double leneps = len * precision; + + //TODO: This doesn't make sense. Directly returning inside the for loop for (int i = 0; i < segment.Length; i++) { ICollection cl = QuadTree.GetObjectsCloseTo(segment[i]); diff --git a/CADability/BorderOperation.cs b/CADability/BorderOperation.cs index de3b4cb5..e22cec82 100644 --- a/CADability/BorderOperation.cs +++ b/CADability/BorderOperation.cs @@ -6,22 +6,22 @@ namespace CADability.Shapes { - /* NEUES KONZEPT (noch nicht implementiert, 20.7.15) - * --- es geht um einfache Borders, nicht um SimpleShapes, d.h. es gibt keine Löcher, alles ist linksrum orientiert --- - * - * Mache einen Quadtree über beide Borders. - * Teile den Quadtree soweit auf, dass in jeder Liste nur ein Schnittpunkt liegt. Wenn Schnittpunkt näher als "recision" zusammenfallen, - * dann als nur einen Schnittpunkt betrachten. - * Jedes Quadrat (also Blatt des Quadtrees) hat bezüglich einer Border nur 2 Schnittpunkte, bzw. es ist ganz innerhalb oder ganz außerhalb. - * Diese Schnittpunkte muss man bestimmen (Parameter auf der Quadratseite und Parameter auf dem Border) - * Je nach boolscher Operation sollte es jetzt ganz einfach sein: jedes Quadrat liefert ein Interval (border1/2, von bis) oder 2 Intervalle, - * wenn ein Schnittpunkt enthalten ist. (Wenn kein Schnittpunkt enthalten ist, dann soll das Quadrat auch nur ein Border enthalten. - * (Probleme sind Selbstüberschneidungen/Berührungen: wenn alle 4 Eckpunkte innerhalb sind, dann kann man das Intervall vergessen). - * Segmente, die identisch sind, werden wie Schnittpunkte behandelt, mit einer besonderen Kennung. - * Zum Schluss werden die Intervalle aufgesammelt, zusammenhängende Stücke einer Border sind einfach zusammenfügbar. Hier können mehrere Umrandungen - * und auch Löcher entstehen. Auch die Richtungen sind klar: bei Vereinigung bleiben die Richtungen erhalten, bei Differenz dreht sich die Richtung - * der rechten Seite um. - * + /* NEW CONCEPT (not yet implemented, 20.7.15) + * --- this concerns simple borders, not SimpleShapes, i.e., there are no holes, everything is oriented counterclockwise --- + * + * Create a quadtree over both borders. + * Subdivide the quadtree so far that each list contains only one intersection point. If intersection points are closer than "precision," + * then treat them as one intersection point. + * Each square (i.e., leaf of the quadtree) has, with respect to a border, only 2 intersection points, or it is entirely inside or entirely outside. + * These intersection points must be determined (parameters on the square's side and parameters on the border). + * Depending on the boolean operation, it should now be very simple: each square yields one interval (border1/border2, from-to) or 2 intervals if an + * intersection point is contained. (If no intersection point is contained, then the square should only contain one border. + * (Problems are self-intersections/contacts: if all 4 corner points are inside, then the interval can be ignored.) + * Segments that are identical are treated like intersection points, with a special identifier. + * Finally, the intervals are collected. Connected pieces of a border are simply joinable. Here, multiple outlines and even holes can arise. + * The directions are also clear: during union operations, the directions remain preserved; during a difference, + * the direction of the right side is reversed. + * * */ internal class BorderOperation @@ -39,13 +39,13 @@ public PointPosition(double par, GeoPoint2D point, double oppositePar, int id, d this.used = false; this.cross = cross; } - public int id; // zwei mit der gleichen id gehören zum selben Schnittpunkt - public double par; // Positionsparameter auf dem Border von 0 bis Segmentanzahl, ganzzahlig bei Ecken - public GeoPoint2D point; // der Punkt selbst - public double oppositePar; // Positionsparameter auf der anderen Border (nur wenn auf dem Rand) - public int index; // der Index in der anderen Liste - public bool used; // schon verbraucht, nicht mehr verwenden - public enum Direction { Entering, Leaving, Crossing, Ambigous, Ignore, Unknown } // Crossing ist für offene Border + public int id; // two with the same ID belong to the same intersection point + public double par; // Position parameter on the border ranges from 0 to the number of segments, integer at corners + public GeoPoint2D point; // the point itself + public double oppositePar; // Position parameter on the other border (only if on the edge) + public int index; // the index in the other list + public bool used; // already used, do not use anymore + public enum Direction { Entering, Leaving, Crossing, Ambigous, Ignore, Unknown } // Crossing is for open borders public Direction direction; public double cross; public PointPosition Decremented() @@ -68,19 +68,19 @@ public int CompareTo(object obj) } #endregion } - private double precision; // kleiner Wert, Punkte mit noch kleinerem Abstand werden als identisch betrachtet - private BoundingRect extent; // gemeinsame Ausdehnung beider Borders + private double precision; // small value, points with an even smaller distance are considered identical + private BoundingRect extent; // common extent of both borders private bool intersect; - private Border border1; // erster Operand - private Border border2; // zweiter Operand - private PointPosition[] border1Points; // Liste von relevanten Punkten auf B1 - private PointPosition[] border2Points; // Liste von relevanten Punkten auf B2 + private Border border1; // first operand + private Border border2; // second operand + private PointPosition[] border1Points; // list of relevant points on B1 + private PointPosition[] border2Points; // list of relevant points on B2 private void Refine(List points, Border pointsborder, Border other) { - // doppelte entfernen. Die Frage nach der Genauigkeit erhebt sich hier - // zunächstmal fix mit 1e-6 implementiert - // zusätzlicher Aufwand, wenn Ende und Anfang übereinstimmen - // weggelassen, da vor dem Aufruf geregelt + // remove duplicates. The question of precision arises here + // initially implemented with a fixed value of 1e-6 + // additional effort if end and beginning are identical + // omitted, as it is handled before the call //for (int i=points.Count-1; i>0; --i) //{ // if (Math.Abs((points[i - 1]).par - (points[i]).par) < 1e-6 || @@ -93,7 +93,7 @@ private void Refine(List points, Border pointsborder, Border othe // } // } //} - // noch den letzten und den ersten checken + // still check the last and the first //int last = points.Count - 1; //if (last > 0) //{ @@ -108,16 +108,20 @@ private void Refine(List points, Border pointsborder, Border othe // } //} PointPosition[] pointsa = (PointPosition[])points.ToArray(); - // die Punkte auf pointsa werden hinsichtlich - // ihres Verhaltens bezüglich der anderen Kurve charakterisiert: tritt - // die jeweilige Border in die andere ein, oder verlässt sie diese. - // Problemfall: Berührung über eine Strecke: zunächst wird der Eintrittspunkt in eine Berührung auf Ignore gesetzt - // in der darauffolgenden Schleife breitet sich das ignore nach hinten aus, wenn davor und danach gleiche Wete sind. - // Vermutlich wird es ein Problem geben, wenn zwei Border ein gemeinsames Segment haben, aber dennoch eine echte Überschneidung - // stattfindet. So einen Fall muss man mal konstruieren. Denn wir lassen jeweils den Austrittspunkt gelten und die beiden - // Punktlisten werden in verschiedener Richtung durchlaufen, also die Punkte passen dann nicht zusammen. Man sollte dann den - // Mittelpunkt nehmen. - // Problemfall: Berührung mit nur einem Eckpunkt wird eliminiert + // the points in pointsa are characterized with respect to + // their behavior concerning the other curve: does the + // respective border enter the other, or leave it. + // Problem case: contact over a segment: initially, the entry point + // in a contact is set to Ignore. + // In the subsequent loop, the ignore spreads backward if there are + // the same values before and after. + // It is likely that there will be a problem if two borders + // share a common segment but still have an actual intersection. + // Such a case needs to be constructed. This is because we always + // consider the exit point, and the two point lists are traversed + // in different directions, so the points won't match. The midpoint + // should be used in such cases. + // Problem case: contact with only a single corner point is eliminated. if (pointsa.Length > 1) { double par = (pointsa[pointsa.Length - 1].par + pointsborder.Count + pointsa[0].par) / 2.0; @@ -144,7 +148,8 @@ private void Refine(List points, Border pointsborder, Border othe par = (pointsa[i].par + pointsa[i + 1].par) / 2.0; newpos = other.GetPosition(pointsborder.PointAt(par), precision); if (newpos == Border.Position.OnCurve) - { // zur Sicherheit zwei weiterePunkte profen. Wenn einer nicht auf OnCurve ist, dann das nehmen. Genau die Mitte kann ein Artefakt liefern + { // for safety, check two additional points. If one is not OnCurve, take that one. + // Exactly the midpoint can produce an artifact double par1 = pointsa[i].par + 0.324625 * (pointsa[i + 1].par - pointsa[i].par); double par2 = pointsa[i].par + 0.689382 * (pointsa[i + 1].par - pointsa[i].par); Border.Position newpos1 = other.GetPosition(pointsborder.PointAt(par1), precision); @@ -157,8 +162,8 @@ private void Refine(List points, Border pointsborder, Border othe { newpos = firstpos; } - // neu eingeführt: Positionsbestimmung anhand der Richtung des Schnittes - // epsilon noch willkürlich + // newly introduced: position determination based on the direction of the intersection + // epsilon is still arbitrary if (pointsa[i].cross > 0.01 && other.IsClosed) { pointsa[i].direction = PointPosition.Direction.Leaving; @@ -181,9 +186,9 @@ private void Refine(List points, Border pointsborder, Border othe } else if (newpos == Border.Position.OnCurve) { - // Bei Schraffur mit Inseln werden oft genau passende puzzleteile abgezogen - // die in einzelnen Abschnitten übereinstimmen. Diese dürfen nicht - // als zugehörig betrachtete werden. Siehe z.B. Schraffur2.cdb + // In hatching with islands, perfectly fitting puzzle pieces are often subtracted + // that match in individual sections. These must not be + // considered as belonging. See, for example, Schraffur2.cdb // pointsa[i].direction = PointPosition.Direction.Ignore; if (lastpos == Border.Position.Outside) pointsa[i].direction = PointPosition.Direction.Entering; @@ -207,15 +212,15 @@ private void Refine(List points, Border pointsborder, Border othe dc.Add(pointsa[i].point, System.Drawing.Color.DarkBlue, pointsa[i].direction.ToString()); } #endif - // in folgender Schleife werden zwei gleiche, die nur von ignore getrennt sind auf einen reduziert - if (pointsborder != border1) // testweise mal nur auf den 2. Durchlauf beschränkt + // in the following loop, two identical ones, separated only by ignore, are reduced to one + if (pointsborder != border1) // for testing purposes, limited to the 2nd pass only { bool ignoring; do { ignoring = false; PointPosition.Direction lastdir = PointPosition.Direction.Ignore; - // den letzten Wert als Startwert verwenden: + // use the last value as the starting value: for (int i = pointsa.Length - 1; i >= 0; --i) { if (pointsa[i].direction != PointPosition.Direction.Ignore) @@ -262,7 +267,7 @@ private void Refine(List points, Border pointsborder, Border othe { int iminus1 = i - 1; if (iminus1 < 0) iminus1 = pointsa.Length - 1; - // nur solche nehmen, wo wirklich ein Wechsel ist + // only take those where there is really a change if ((pointsa[iminus1].direction != pointsa[i].direction) || (pointsa[iminus1].direction == PointPosition.Direction.Crossing && pointsa[i].direction == PointPosition.Direction.Crossing)) { @@ -280,20 +285,20 @@ private void Refine(List points, Border pointsborder, Border othe } else { - points.Clear(); // nur ein einziger Punkt, der gilt sowieso nicht, oder - intersect = false; // jedenfalls kein Fall bekannt, wo sowas auftritt + points.Clear(); // only a single point, which doesn't count anyway, right? + intersect = false; // in any case, no known instance where something like this occurs } } private void GenerateClusterSet() { - // zuerst die beiden Listen mit den Eckpunkten füttern. wozu? abgeschafft! + // first, populate the two lists with the corner points. why? abolished! List b1p = new List(); List b2p = new List(); #if DEBUG debugb1p = b1p; debugb2p = b2p; #endif - // warum sollten wir die Eckpunkte dazunehmen??? + // why should we include the corner points??? // for (int i=0; i 0; --i) { if (Math.Abs((b1p[i - 1]).par - (b1p[i]).par) < 1e-6 || @@ -353,7 +358,7 @@ private void GenerateClusterSet() } } } - // und noch am Ende checken + // and check again at the end int last = b1p.Count - 1; if (last > 0) { @@ -378,12 +383,13 @@ private void GenerateClusterSet() } Refine(b1p, border1, border2); - // Alle, die aus b1 entfernt wurden, müssen auch aus b2 entfernt werden - // das stand früher nach Refine(b2p... aber das hatte folgenden Nachteil: - // z.B. zwei horizontal leicht versetzte horizontale Rechtecke haben 4 Schnittpunkte, wobei jeweils zweimal - // Entering und zweimal Leaving kommt. Beim ersten Refine wird nur das nebeneinanderliegende Paar Entering->Leaving belassen - // das liegt aber in der Punktliste b2p nicht aufeinanderfolgend und dann wird dort das andere Paar beibehalten, so dass - // insgesamt nicht übrig bleibt. Deshalb also gleich entfernen. + // All entries removed from b1 must also be removed from b2. + // Previously, this was done after Refine(b2p...), but that had the following drawback: + // For example, two horizontally slightly offset horizontal rectangles have 4 intersection points, + // where there are two Entering and two Leaving points each. + // During the first Refine, only the adjacent pair Entering->Leaving is retained. + // However, in the point list b2p, these do not appear consecutively, so the other pair is retained there, + // which means that, in total, nothing is left. Therefore, remove them right away. for (int i = b2p.Count - 1; i >= 0; --i) { bool ok = false; @@ -401,15 +407,15 @@ private void GenerateClusterSet() for (int i = 0; i < b1p.Count; ++i) { for (int j = 0; j < b2p.Count; ++j) - { // den folgenden Vergleich von == auf <1e-10 geändert, da offensichtlich kleinste Unterschiede auftreten - // die Unterschiede kommen, weil fast identische entfernt wurden, - // aber es wurden nicht in beiden Listen die gleichen entfernt - // hier müsste es aber jetzt genügen nach der id zu gucken, oder? + { // Changed the following comparison from == to <1e-10 because very small differences occur. + // The differences arise because nearly identical items were removed, + // but not the same ones were removed from both lists. + // Here, it should now be sufficient to check by id, right? //if ((Math.Abs((b1p[i]).par-(b2p[j]).oppositePar)<1e-10) && // (Math.Abs((b1p[i]).oppositePar-(b2p[j]).par)<1e-10)) if (b1p[i].id == b2p[j].id) { - // da PointPosition ein struct, hier umständlich: + // since PointPosition is a struct, it's cumbersome here: PointPosition pp1 = b1p[i]; PointPosition pp2 = b2p[j]; pp1.index = j; @@ -420,13 +426,14 @@ private void GenerateClusterSet() } if (b1p[i].index == -1) { - b1p.RemoveAt(i); // keinen Partner gefunden, weg damit + b1p.RemoveAt(i); // no partner found, remove it --i; } } - // noch folgenden Sonderfall berücksichtigen: - // wenn in einer Liste zweimal Entering und die dazugehörigen zweimal Leaving sind - // dann einen der beiden löschen, denn es handelt sich um ein gemeinsames Konturstück + + // Consider the following special case: + // If there are two Entering points and their corresponding two Leaving points in a list, + // then delete one of the pairs because it represents a shared contour segment. bool removed = true; while (removed) { @@ -439,14 +446,14 @@ private void GenerateClusterSet() int i2 = b1p[i].index; if (Math.Abs(i2 - i1) == 1 && b2p[i1].direction == b2p[i2].direction) { - // Bedingung erfüllt: i in List b1p löschen + // Condition met: remove i from list b1p int r1 = i; int r2 = b1p[i].index; b2p.RemoveAt(r2); b1p.RemoveAt(r1); for (int j = 0; j < b1p.Count; j++) { - if (b1p[j].index > r2) b1p[j] = b1p[j].Decremented(); // wg. blöden struct + if (b1p[j].index > r2) b1p[j] = b1p[j].Decremented(); // because of the annoying struct } for (int j = 0; j < b2p.Count; j++) { @@ -458,9 +465,10 @@ private void GenerateClusterSet() } } } - // eigentlich sollte jetzt kein Eintrag mit index == -1 mehr vorkommen - // und das rauslöschen ist ein bisschen blöd, weil die Indizes schon vergeben sind - // es würde aber gehen. Hier erstmal eine exception werfen: + + // actually, there should no longer be any entries with index == -1 + // and removing them is a bit tricky because the indices have already been assigned + // but it would be possible. For now, just throw an exception: for (int i = 0; i < b1p.Count; ++i) { if ((b1p[i]).index == -1) throw new BorderException("internal error in GenerateClusterSet", BorderException.BorderExceptionType.InternalError); @@ -479,7 +487,7 @@ public BorderOperation(Border b1, Border b2) border2 = b2; extent = border1.Extent; extent.MinMax(border2.Extent); - precision = (extent.Width + extent.Height) * 1e-6; // 1e-8 war zu scharf! + precision = (extent.Width + extent.Height) * 1e-6; // 1e-8 was too strict! try { GenerateClusterSet(); @@ -549,7 +557,7 @@ public CompoundShape Union() case BorderPosition.disjunct: return new CompoundShape(new SimpleShape(border1), new SimpleShape(border2)); case BorderPosition.intersecting: - // der schwierigste Fall, hier kann es eine Hülle und mehrere Löcher geben + // The most difficult case, here there can be a shell and multiple holes List bdrs = new List(); int startb1 = -1; int ind; @@ -573,7 +581,7 @@ public CompoundShape Union() //dc.toShow.Clear(); //dc.Add(segments.ToArray()); #endif - startb1 = border2Points[ind2].index; // index auf b1 + startb1 = border2Points[ind2].index; // index to b1 } if (segments.Count > 0) { @@ -582,7 +590,7 @@ public CompoundShape Union() if ((sp | ep) < precision) { Border bdr = new Border(segments.ToArray(), true); - // identische hin und zurücklaufende Kurven entfernen + // Remove identical forward and backward curves if (bdr.ReduceDeadEnd(precision * 10)) { bdr.RemoveSmallSegments(precision); @@ -595,15 +603,15 @@ public CompoundShape Union() } if (bdrs.Count > 0) { - // hier kann ein Ring entstehen, der nur aus einem Border besteht - // das müsste noch extra überprüft werden + // Here, a ring may emerge that consists only of a single border + // This still needs to be checked additionally bdrs.Sort(new BorderAreaComparer()); Border outline = bdrs[bdrs.Count - 1] as Border; double[] si = outline.GetSelfIntersection(precision); - if (si.Length >= 3) // zwei Schnittpunkt, wie ein "C", das sich an der Öffnung berührt, also eigentlich ein "O" ist + if (si.Length >= 3) // Two intersection points, like a "C" that touches at the opening, so it is essentially an "O" { - // zerschneide die outline in Stücke und eliminiere gegeläufige Teile + // Cut the outline into pieces and eliminate counter-oriented parts List parms = new List(); for (int i = 0; i < si.Length; i += 3) { @@ -623,7 +631,7 @@ public CompoundShape Union() dbgl1.Add(parts[i].MakeGeoObject(Plane.XYPlane)); } #endif - // parts enthält jetzt die aufgeschnipselte outline. Suche und entferne gegenläufige identische Teilabschnitte + // `parts` now contains the sliced-up outline. Search for and remove identical sections with opposing directions. bool removed = true; while (removed) { @@ -638,7 +646,8 @@ public CompoundShape Union() } Path2D part1 = parts[i].CloneReverse(true) as Path2D; if (part1.IsClosed) - { // ein in sich zurückkehrendes Stückchen? + { + // a self-returning piece? Border testEmpty = new Border(part1); if (testEmpty.Area < precision) { @@ -670,19 +679,20 @@ public CompoundShape Union() CompoundShape tmp = CompoundShape.CreateFromList(parts.ToArray(), precision); if (tmp != null && tmp.SimpleShapes.Length == 1) { - bdrs.RemoveAt(bdrs.Count - 1); // alte outline weg + bdrs.RemoveAt(bdrs.Count - 1); // old outline removed for (int i = 0; i < tmp.SimpleShapes[0].NumHoles; i++) { - bdrs.Add(tmp.SimpleShapes[0].Hole(i)); // Löcher dazu + bdrs.Add(tmp.SimpleShapes[0].Hole(i)); // Add holes } outline = tmp.SimpleShapes[0].Outline; - bdrs.Add(tmp.SimpleShapes[0].Outline); // neue outline dazu, kommt gleich wieder weg + bdrs.Add(tmp.SimpleShapes[0].Outline); // new outline added, will be removed again shortly } } else if (si.Length == 3) - { // ein einziger innerer Schnittpunkt, das kann ein "Spike" in der outline sein + { + // A single inner intersection point, this could be a "spike" in the outline } - bdrs.RemoveAt(bdrs.Count - 1); // outline weg + bdrs.RemoveAt(bdrs.Count - 1); // remove outline return new CompoundShape(new SimpleShape(outline, bdrs.ToArray())); } break; @@ -699,9 +709,9 @@ public CompoundShape Intersection() case BorderPosition.b2coversb1: return new CompoundShape(new SimpleShape(border1)); case BorderPosition.disjunct: - return new CompoundShape(); // leer! + return new CompoundShape(); // empty! case BorderPosition.intersecting: - // der schwierigste Fall, hier kann es mehrere Hüllen aber keine Löcher geben + // The most difficult case, here there can be multiple shells but no holes ArrayList bdrs = new ArrayList(); int startb1 = -1; int ind; @@ -714,7 +724,7 @@ public CompoundShape Intersection() segments.AddRange(border1.GetPart(border1Points[ind].par, border1Points[ind1].par, true)); int ind2 = FindNextPoint(false, border1Points[ind1].index, PointPosition.Direction.Leaving, true); segments.AddRange(border2.GetPart(border2Points[border1Points[ind1].index].par, border2Points[ind2].par, true)); - startb1 = border2Points[ind2].index; // index auf b1 + startb1 = border2Points[ind2].index; // index to b1 } if (segments.Count > 0) { @@ -739,7 +749,7 @@ public CompoundShape Intersection() } return new CompoundShape(ss); } - // sie überschneiden sich (vermutlich Berührung), aber der Inhalt ist leer, also leer liefern + // They overlap (presumably touch), but the content is empty, so return empty return new CompoundShape(); } throw new BorderException("unexpected error in BorderOperation.Intersection!", BorderException.BorderExceptionType.InternalError); @@ -751,15 +761,15 @@ public CompoundShape Difference() case BorderPosition.b1coversb2: return new CompoundShape(new SimpleShape(border1, border2)); case BorderPosition.b2coversb1: - // es wird alles weggenommen, also leer, warum stand hier vorher b2-b1??? - return new CompoundShape(); // leer! + // Everything is removed, so it’s empty. Why was "b2-b1" written here before??? + return new CompoundShape(); // empty! // return new CompoundShape(new SimpleShape(border2, border1)); case BorderPosition.disjunct: - // disjunkt: das muss dann doch border1 sein, oder? vorher stand hier leer + // disjoint: then it must be border1, right? previously this was left empty return new CompoundShape(new SimpleShape(border1)); - // return new CompoundShape(); // leer! + // return new CompoundShape(); // empty! case BorderPosition.intersecting: - // der schwierigste Fall, hier kann es mehrere Hüllen aber keine Löcher geben + // the most difficult case, here there can be multiple outlines but no holes ArrayList bdrs = new ArrayList(); int startb1 = -1; int ind; @@ -773,7 +783,7 @@ public CompoundShape Difference() segments.AddRange(border1.GetPart(border1Points[ind].par, border1Points[ind1].par, true)); int ind2 = FindNextPoint(false, border1Points[ind1].index, PointPosition.Direction.Entering, false); segments.AddRange(border2.GetPart(border2Points[border1Points[ind1].index].par, border2Points[ind2].par, false)); - startb1 = border2Points[ind2].index; // index auf b1 + startb1 = border2Points[ind2].index; // index to b1 } if (segments.Count > 0) { @@ -803,10 +813,12 @@ public CompoundShape Difference() } return new CompoundShape(ss); } - // sie überschneiden sich, aber der Inhalt ist leer, also border1 liefern - if (found) return new CompoundShape(); - else return new CompoundShape(new SimpleShape(border1)); - break; + // they intersect, but the content is empty, so return border1 + if (found) + return new CompoundShape(); + + return new CompoundShape(new SimpleShape(border1)); + } throw new BorderException("unexpected error in BorderOperation.Intersection!", BorderException.BorderExceptionType.InternalError); } @@ -814,23 +826,23 @@ public CompoundShape Split() { if (!intersect || border1Points.Length == 0 || border2Points.Length == 0) { - return new CompoundShape(new SimpleShape(border1)); // kein Schnitt + return new CompoundShape(new SimpleShape(border1)); // no intersection } - // die 2. Border ist offen und teilt die 1. auf + // The second border is open and splits the first one ArrayList bdrs = new ArrayList(); int startb2 = -1; int ind; ArrayList segments = new ArrayList(); - // zunächst in Richtung von border2 suchen - // auf border1 gehen wir immer nur vorwärts + // first search in the direction of border2 + // We always move forward on border1 while ((ind = FindNextPoint(false, startb2, PointPosition.Direction.Entering, true)) >= 0) { int ind1 = FindNextPoint(false, ind, PointPosition.Direction.Leaving, true); if (ind1 >= 0) { segments.AddRange(border2.GetPart(border2Points[ind].par, border2Points[ind1].par, true)); - // auf Border 1 sind eigentlich alle Punkte "Crossing", was ist mit Berührungen? - // aber der, auf den border2Points[ind1].index darf ja nicht nochmal gefunden werden, deshalb "+1" + // On Border 1, all points are actually "Crossing"; what about contacts (touch points)? + // But the point at "border2Points[ind1].index" must not be found again, hence the "+1" int nextInd = (border2Points[ind1].index + 1); if (nextInd >= border1Points.Length) nextInd = 0; int ind2 = FindNextPoint(true, nextInd, PointPosition.Direction.Crossing, true); @@ -857,8 +869,9 @@ public CompoundShape Split() } } } - // jetzt entgegen der Richtung von border2 suchen. - // zuvor aber alle Punkte wieder freigeben + + // now search in the opposite direction of border2. + // but first, release all points again for (int i = 0; i < border1Points.Length; i++) { border1Points[i].used = false; @@ -873,8 +886,8 @@ public CompoundShape Split() if (ind1 >= 0) { segments.AddRange(border2.GetPart(border2Points[ind].par, border2Points[ind1].par, false)); - // auf Border 1 sind eigentlich alle Punkte "Crossing", was ist mit Berührungen? - // aber der, auf den border2Points[ind1].index darf ja nicht nochmal gefunden werden, deshalb "+1" + // On Border 1, all points are actually "Crossing"; what about touch points? + // However, the point at border2Points[ind1].index must not be found again, hence the "+1". int nextInd = (border2Points[ind1].index + 1); if (nextInd >= border1Points.Length) nextInd = 0; int ind2 = FindNextPoint(true, nextInd, PointPosition.Direction.Crossing, true); @@ -901,7 +914,7 @@ public CompoundShape Split() } } } - if (bdrs.Count > 1) // wenn Split nur ein Border liefert, dann war was falsch (geändert am 2.11.15) + if (bdrs.Count > 1) // If Split only returns one border, something went wrong (changed on 2.11.15) { SimpleShape[] ss = new SimpleShape[bdrs.Count]; for (int i = 0; i < bdrs.Count; i++) @@ -912,7 +925,7 @@ public CompoundShape Split() } else { - return new CompoundShape(new SimpleShape(border1)); // kein Schnitt + return new CompoundShape(new SimpleShape(border1)); // no intersection } } public enum BorderPosition { disjunct, intersecting, b1coversb2, b2coversb1, identical, unknown }; @@ -921,7 +934,7 @@ public BorderPosition Position { get { - if (border1 == null) return BorderPosition.unknown; // die Initialisierung hat nicht geklappt + if (border1 == null) return BorderPosition.unknown; // The initialization did not succeed if (borderPosition == BorderPosition.unknown) { if (intersect && this.border1Points.Length > 0) @@ -934,13 +947,14 @@ public BorderPosition Position bool on2 = false; Border.Position pos = border2.GetPosition(border1.StartPoint, precision); if (pos == Border.Position.OnCurve) - { // dummer Zufall: kein Schnittpunkt und mit Berührpunkt getestet + { + // silly coincidence: no intersection point and tested with a contact point try { // pos = border2.GetPosition(border1.SomeInnerPoint); - // geändert wie folgt. Überlegung: kein Schnittpunkt und mit Berührpunkt getestet - // dann mit einem anderen Punkt auf dem Border testen. Zwei Berührpunkte - // wäre großer Zufall. deshalb die komische zahl, um Systematiken auszuweichen + // Changed as follows: Consideration - no intersection point and tested with a contact point. + // Then test with another point on the border. Two contact points would be a big coincidence. + // That's why the strange number is used, to avoid systematic patterns. pos = border2.GetPosition(border1.PointAt(0.636548264536 * border1.Segments.Length), precision); } catch (BorderException) { } @@ -1042,7 +1056,7 @@ internal void MakeUnused() } } - // als key für Dictionary + // as a key for Dictionary internal class BorderPair : IComparable { int id1, id2; diff --git a/CADability/BorderQuadTree.cs b/CADability/BorderQuadTree.cs index 7fa06637..c21386c5 100644 --- a/CADability/BorderQuadTree.cs +++ b/CADability/BorderQuadTree.cs @@ -717,7 +717,7 @@ public BorderQuadTree(Border bdr1, Border bdr2, double precision) position = BorderPosition.intersecting; break; } - catch (CriticalPosition cp) + catch (CriticalPosition) { // Korrekturwert für nächste Runde, wenn es einen Schnittpunkt genau auf einer Kante gab oder einen tangentialen Schnitt center = center + korr; width = width + korr.Length; diff --git a/CADability/BoundingRect.cs b/CADability/BoundingRect.cs index 2467e738..cfbaa36d 100644 --- a/CADability/BoundingRect.cs +++ b/CADability/BoundingRect.cs @@ -12,7 +12,7 @@ namespace CADability /// so assignements always make a copy. /// [Serializable()] - public struct BoundingRect : IQuadTreeInsertable, IComparable, ISerializable + public struct BoundingRect : IQuadTreeInsertable, IComparable, ISerializable, IEquatable { public double Left; public double Right; @@ -824,6 +824,27 @@ internal GeoPoint2D[] GetLines(double v1, double v2) } #endregion + public bool Equals(BoundingRect other) + { + return Left.Equals(other.Left) && Right.Equals(other.Right) && Bottom.Equals(other.Bottom) && Top.Equals(other.Top); + } + + public override bool Equals(object obj) + { + return obj is BoundingRect other && Equals(other); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Left.GetHashCode(); + hashCode = (hashCode * 397) ^ Right.GetHashCode(); + hashCode = (hashCode * 397) ^ Bottom.GetHashCode(); + hashCode = (hashCode * 397) ^ Top.GetHashCode(); + return hashCode; + } + } } } diff --git a/CADability/ColorDef.cs b/CADability/ColorDef.cs index 1dbd2e67..2774486f 100644 --- a/CADability/ColorDef.cs +++ b/CADability/ColorDef.cs @@ -202,7 +202,7 @@ public ColorDef(SerializationInfo info, StreamingContext context) { color = (Color)info.GetValue("Color", typeof(Color)); } - catch (Exception e) + catch (Exception) { color = Color.Black; } diff --git a/CADability/ColorSetting.cs b/CADability/ColorSetting.cs index 22410e91..51828446 100644 --- a/CADability/ColorSetting.cs +++ b/CADability/ColorSetting.cs @@ -73,7 +73,7 @@ protected ColorSetting(SerializationInfo info, StreamingContext context) color = (Color)info.GetValue("Color", typeof(Color)); object dbg = info.GetValue("Color", typeof(object)); } - catch (Exception e) + catch (Exception) { color = Color.Black; } diff --git a/CADability/ConicalSurface.cs b/CADability/ConicalSurface.cs index ef5f974e..748c5c77 100644 --- a/CADability/ConicalSurface.cs +++ b/CADability/ConicalSurface.cs @@ -1691,7 +1691,9 @@ public override ICurve2D GetProjectedCurve(ICurve curve, double precision) ep.x += 2 * Math.PI; // noch nicht getestet } return new Line2D(sp, ep); - + + //Unreachable code + /* if (!forward && (ustart < uend)) { // entweder ustart + 2*pi oder uend - 2*pi @@ -1701,6 +1703,7 @@ public override ICurve2D GetProjectedCurve(ICurve curve, double precision) { uend += 2 * Math.PI; // noch nicht getestet } + */ } // Grenzfälle: ustart oder uend liegen auf 0.0 oder 2*pi // dann weiß man nicht ob der Punkt zyklisch richtig ist diff --git a/CADability/ConstrHatchInside.cs b/CADability/ConstrHatchInside.cs index dc997134..8b309400 100644 --- a/CADability/ConstrHatchInside.cs +++ b/CADability/ConstrHatchInside.cs @@ -259,7 +259,7 @@ private void OnPoint(GeoPoint p) { findShapeThread.Abort(); } - catch (System.Threading.ThreadStateException e) + catch (System.Threading.ThreadStateException) { findShapeIsRunning = false; return; // keinen weiteren thread starten @@ -269,7 +269,7 @@ private void OnPoint(GeoPoint p) { findShapeThread.Join(); } - catch (System.Threading.ThreadStateException e) + catch (System.Threading.ThreadStateException) { findShapeIsRunning = false; return; // keinen weiteren thread starten diff --git a/CADability/CoordSys.cs b/CADability/CoordSys.cs index e7249c23..44c4d918 100644 --- a/CADability/CoordSys.cs +++ b/CADability/CoordSys.cs @@ -54,7 +54,7 @@ public CoordSys(GeoPoint Location, GeoVector DirectionX, GeoVector DirectionY) directionY.Norm(); directionZ.Norm(); } - catch (GeoVectorException e) + catch (GeoVectorException) { throw new CoordSysException(CoordSysException.tExceptionType.ConstructorFailed); } diff --git a/CADability/CopyMatrixObjects.cs b/CADability/CopyMatrixObjects.cs index 4252dccc..5baeeb29 100644 --- a/CADability/CopyMatrixObjects.cs +++ b/CADability/CopyMatrixObjects.cs @@ -149,22 +149,14 @@ private int CalcVerCountDown(GeoPoint MousePosition) private bool SetHorDist(double Length) { - // if (Length > 0) // alles erlaubt, insbesondere in PFOCAD - { - distX = Length; - return (showMatrix()); - } - return false; + distX = Length; + return (showMatrix()); } private bool SetVerDist(double Length) { - //if (Length > 0) - { - distY = Length; - return (showMatrix()); - } - return false; + distY = Length; + return (showMatrix()); } private bool SetDir(GeoVector vector) diff --git a/CADability/CurveGraph.cs b/CADability/CurveGraph.cs index 7502db16..5bf577e2 100644 --- a/CADability/CurveGraph.cs +++ b/CADability/CurveGraph.cs @@ -10,16 +10,16 @@ namespace CADability.Shapes { /// - /// Ein Verbindungspunkt. Die Kurve curve startet oder endet hier. Findet Verwendung - /// im Cluster, der i.A. aus mehreren solchen Verbindungspunkten besteht. + /// A connection point. The curve `curve` starts or ends here. + /// It is used in the cluster, which generally consists of multiple such connection points. /// internal class Joint : IComparable { - public ICurve2D curve; // die Kurve - public Cluster StartCluster; // von hier - public Cluster EndCluster; // nach da (isStartPoint wieder entfernen) - public double tmpAngle; // ein Winkel für das sortieren - public bool forwardUsed; // diese Kante wurde + public ICurve2D curve; // The curve + public Cluster StartCluster; // From here + public Cluster EndCluster; // To there (remove isStartPoint again) + public double tmpAngle; // An angle for sorting + public bool forwardUsed; // This edge was used public bool reverseUsed; public Joint() { } public override string ToString() @@ -68,14 +68,14 @@ public int CompareTo(object obj) #endregion } - /// - /// Ein oder mehrere Joints, die sehr end beisammenliegen und als identische Punkte - /// betrachtet werden. - /// - internal class Cluster : IQuadTreeInsertable - { - public GeoPoint2D center; // der Mittelpunkt aller zugehörigen Joints - public List Joints; // Liste von Joint[] +/// +/// One or more joints that are located very close together +/// and are considered identical points. +/// +internal class Cluster : IQuadTreeInsertable +{ + public GeoPoint2D center; // The center point of all associated joints + public List Joints; // List of Joint objects public Cluster() { Joints = new List(); @@ -146,25 +146,25 @@ public CurveGraphException(string msg) : base(msg) } } /// - /// INTERN: - /// Dient zum Erzeugen von Border und SimpleShape/CompoundShape aus einer Liste von - /// ICurve2D. Es werden keine Schnittpunkte betrachtet, die müssten zuvor erzeugt und - /// die ICurve2D Objekte gesplittet werden. + /// INTERNAL: + /// Used for generating a Border and SimpleShape/CompoundShape from a list of + /// ICurve2D. Intersections are not considered; they must be created beforehand, + /// and the ICurve2D objects must be split accordingly. /// internal class CurveGraph { - private double clusterSize; // maximale Cluster Größe, abhängig von der Ausdehnung alle Objekte - private double maxGap; // maximale zu schließende Lücke - private QuadTree clusterTree; // QuadTree aller Cluster - private UntypedSet clusterSet; // Menge aller Cluster (parallel zum QuadTree) + private double clusterSize; // Maximum cluster size, depending on the extent of all objects + private double maxGap; // Maximum gap to be closed + private QuadTree clusterTree; // QuadTree of all clusters + private UntypedSet clusterSet; // Set of all clusters (parallel to the QuadTree) /// - /// Liste an unbrauchbaren Objekten die bei erstellen eines CompoundShape angefallen sind + /// List of unusable objects that were generated during the creation of a CompoundShape /// public List DeadObjects { get; } = new List(); static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap) - { // alle Kurven in l werden in die Ebene plane projiziert. Das ist mal ein erster Ansatz - // Man könnte auch gemeinsame Ebenen finden u.s.w. + { // All curves in l are projected onto the plane. This is just a first approach. + // One could also find common planes and so on. ArrayList curves = new ArrayList(); BoundingRect ext = BoundingRect.EmptyBoundingRect; foreach (IGeoObject go in l) @@ -175,11 +175,11 @@ static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap ICurve2D cv2 = cv.GetProjectedCurve(plane); if (cv2 != null) { - // "3d" wird nur verwendet um hinterher aus den Originalkurven die Ebene zu bestimmen - // in die alles zurücktranformiert wird. Besser würde man vermutlich mit "plane" arbeiten - // so wie es hier reinkommt. + // "3d" is only used to determine the plane from the original curves + // into which everything will be transformed back. It would probably be better + // to work with "plane," as it is provided here. if (cv2 is Path2D && (cv2 as Path2D).GetSelfIntersections().Length > 0) - { // ein sich selbst überschneidender Pfad muss aufgelöst werden + { // A self-intersecting path must be resolved ICurve2D[] sub = (cv2 as Path2D).SubCurves; curves.AddRange(sub); for (int i = 0; i < sub.Length; ++i) @@ -205,7 +205,7 @@ static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap { qt.AddObject(curves[i] as ICurve2D); } - // jetzt alle mit allen schneiden und die Schnipsel in eine weitere Liste stecken + // Now intersect all with all and put the fragments into another list ArrayList snippet = new ArrayList(); for (int i = 0; i < curves.Count; ++i) { @@ -237,7 +237,7 @@ static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap else { intersectionPoints.Add(0.0); - intersectionPoints.Add(1.0); // damit sinds mindesten 3 + intersectionPoints.Add(1.0); // This ensures there are at least 3 double[] pps = (double[])intersectionPoints.ToArray(typeof(double)); Array.Sort(pps); for (int ii = 1; ii < pps.Length; ++ii) @@ -262,12 +262,12 @@ static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap } } } - // snippet ist jetzt die Liste aller Schnipsel + // snippet is now the list of all fragments return new CurveGraph((ICurve2D[])snippet.ToArray(typeof(ICurve2D)), maxGap); } public CurveGraph(ICurve2D[] curves, double maxGap) - { // aus den ICurve2D wird eine Clusterliste erzeugt (Start- und Endpunkte) + { // A cluster list is created from the ICurve2D (start and end points) this.maxGap = maxGap; BoundingRect ext = BoundingRect.EmptyBoundingRect; for (int i = 0; i < curves.Length; ++i) @@ -290,7 +290,7 @@ public CurveGraph(ICurve2D[] curves, double maxGap) } private void Insert(ICurve2D curve) - { // der Start- bzw. Endpunkt einer Kurve kommt in die Cluster Liste + { // The start or end point of a curve is added to the cluster list Joint lp = new Joint(); lp.curve = curve; @@ -303,7 +303,7 @@ private void Insert(ICurve2D curve) if (Geometry.Dist(cl.center, p) < clusterSize) { InsertInto = cl; - clusterTree.RemoveObject(cl); // rausnehmen, da er u.U. größer wird und unten wieder eingefügt wird + clusterTree.RemoveObject(cl); // Remove it, as it might get larger and will be reinserted below break; } } @@ -333,7 +333,7 @@ private void Insert(ICurve2D curve) InsertInto.center = new GeoPoint2D(x / InsertInto.Joints.Count, y / InsertInto.Joints.Count); clusterTree.AddObject(InsertInto); - // desgleichen mit dem Endpunkt: + // The same applies to the endpoint: p = curve.EndPoint; CheckSp = new BoundingRect(p, clusterSize, clusterSize); StartCluster = clusterTree.GetObjectsFromRect(CheckSp); @@ -343,7 +343,7 @@ private void Insert(ICurve2D curve) if (Geometry.Dist(cl.center, p) < clusterSize) { InsertInto = cl; - clusterTree.RemoveObject(cl); // rausnehmen, da er u.U. größer wird und unten wieder eingefügt wird + clusterTree.RemoveObject(cl); // Remove it, as it might get larger and will be reinserted below break; } } @@ -376,7 +376,7 @@ private void Insert(ICurve2D curve) } private Cluster FindCluster(ICurve2D curve, GeoPoint2D p, bool RemovePoint) - { // Findet einen Cluster, der den Punkt p und die Kurve curve enthält + { // Finds a cluster that contains the point p and the curve curve BoundingRect clip = new BoundingRect(p, clusterSize, clusterSize); ICollection col = clusterTree.GetObjectsFromRect(clip); foreach (Cluster cl in col) @@ -396,8 +396,8 @@ private Cluster FindCluster(ICurve2D curve, GeoPoint2D p, bool RemovePoint) return null; } private void RemoveAllDeadEnds() - { // Entfernt alle Sackgassen - ArrayList ClusterToRemove = new ArrayList(); // damit die Schleife über clusterSet laufen kann + { + ArrayList ClusterToRemove = new ArrayList(); // So that the loop can iterate over clusterSet foreach (Cluster cl in clusterSet) { if (cl.Joints.Count < 2) @@ -418,7 +418,7 @@ private void RemoveDeadEnd(Cluster cl) { DeadObjects.Add(NextCluster.Joints[0].curve.MakeGeoObject(Plane.XYPlane)); - Joint lp = NextCluster.Joints[0]; // es gibt ja genau einen + Joint lp = NextCluster.Joints[0]; // There is exactly one if (lp.StartCluster == NextCluster) NextCluster = lp.EndCluster; else NextCluster = lp.StartCluster; if (NextCluster != null) @@ -428,7 +428,7 @@ private void RemoveDeadEnd(Cluster cl) if ((NextCluster.Joints[i]) == lp) { NextCluster.Joints.RemoveAt(i); - break; // diesen Pfad rausoperiert + break; // Extracted this path } } } @@ -438,10 +438,9 @@ private void RemoveDeadEnd(Cluster cl) } // private void FindCurve(Cluster StartCluster, int PointIndex, Cluster EndCluster, Set UsedClusters, ArrayList result) // { - // // der Cluster StartHere hat mehr als zwei Anschlüsse. Gesucht sind sämtliche Pfade, die von StartHere - // // nach EndHere führen. Das Ergebnis ist in dem Parameter result zu finden. Dieser - // // enthält ein oder mehrerer ArrayLists, wovon jede einzelne eine Abfolge von Cluster und Index ist - // ArrayList SingleCurve = new ArrayList(); + // // The cluster StartHere has more than two connections. The goal is to find all paths that lead from StartHere + // // to EndHere. The result can be found in the parameter 'result', which contains one or more ArrayLists, + // // each representing a sequence of clusters and indices. // Cluster LastCluster = StartCluster; // while (PointIndex>=0) // { @@ -452,43 +451,43 @@ private void RemoveDeadEnd(Cluster cl) // Cluster cl; // if (lp.isStartPoint) cl = FindCluster(lp.curve,lp.curve.EndPoint,false); // else cl = FindCluster(lp.curve,lp.curve.StartPoint,false); - // if (cl==null) break; // nichts gefunden, kann eigentlich nicht vorkommen + // if (cl==null) break; // Nothing found; this should actually never happen // if (cl==EndCluster) // { // fertig // result.Add(SingleCurve); // break; // } - // if (UsedClusters.Contains(cl)) break; // innerer Kurzschluss, führt nicht zum Anfang + // if (UsedClusters.Contains(cl)) break; // Internal short circuit, does not lead to the start // if (cl.Points.Count==2) - // { // es geht eindeutig weiter + // { // It clearly continues // if (((Joint)cl.Points[0]).curve==lp.curve) PointIndex = 1; // else PointIndex = 0; // LastCluster = cl; - // // und weiter gehts + // // And on we go // } // else - // { // es gibt mehr als eine Fortsetzung, denn Cluster mit einem Punkt dürfen nicht vorkommen - // // hier werden also verschiedene Fortsetzungen gesucht + // { // There is more than one continuation, as clusters with a single point should not exist + // // Therefore, different continuations are being searched for here // for (int i=0; i 0) clusterTree.AddObject(cl); @@ -524,15 +523,15 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) if (foundCluster != null) break; } } - if (foundCluster == null) return null; // sollte nicht vorkommen + if (foundCluster == null) return null; // Should not occur RemoveJoint(foundJoint, foundCluster); return foundCluster; } // private Border FindNextBorder() // { - // // Alle Cluster enthalten zwei Punkte. Suche einen Joint, dessen angeschlossener - // // ICurve2D länger als maxGap ist (warum eigentlich?) - // // Gehe solange durch die Cluster, bis wieder der erste Punkt erreicht ist + // // All clusters contain two points. Search for a joint whose connected + // // ICurve2D is longer than maxGap (why actually?) + // // Iterate through the clusters until the first point is reached again // Joint StartWith = null; // foreach (Cluster cl in clusterSet) // { @@ -547,7 +546,7 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // } // if (StartWith!=null) break; // } - // if (StartWith==null) return null; // keinen Anfang gefunden + // if (StartWith==null) return null; // No beginning found // Joint LastPoint = StartWith; // Cluster goon = null; // BorderBuilder makeBorder = new BorderBuilder(); @@ -555,9 +554,9 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // while ((goon = ExtractCurve(LastPoint.curve,!LastPoint.isStartPoint))!=null) // { // makeBorder.AddSegment(LastPoint.curve.CloneReverse(!LastPoint.isStartPoint)); - // if (goon.Points.Count==0) break; // auf den letzten und ersten Punkt gestoßen - // LastPoint = (Joint)goon.Points[0]; // es sollte ja nur diesen einen geben - // RemoveJoint(LastPoint,goon); // damit müsste dieser Cluster verschwinden + // if (goon.Points.Count==0) break; // Encountered the last and first point + // LastPoint = (Joint)goon.Points[0]; // There should only be this one + // RemoveJoint(LastPoint,goon); // This should make this cluster disappear // } // return makeBorder.BuildBorder(); // } @@ -565,7 +564,7 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // { // Set tmpUsedJoints = new Set(); // tmpUsedJoints.Add(new UsedJoint(startWith,forward)); - // // Anfangskante gefunden, wie gehts weiter + // // Starting edge found, what’s next // BorderBuilder bb = new BorderBuilder(); // bb.Precision = clusterSize; // if (forward) bb.AddSegment(startWith.Clone()); @@ -574,13 +573,13 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // while (!bb.IsClosed) // { // Cluster cl = FindCluster(startWith, bb.EndPoint, false); - // if (cl==null) return false; // eine angefangene Border geht nicht weiter, sollte nicht passieren, da keine Sackgassen + // if (cl==null) return false; // A started border does not continue, this should not happen as there are no dead ends // int ind = -1; // double sa = -1.0; // for (int i=0; i sa) - // { // je mehr nach links umso größer is d + // { // The further to the left, the larger d becomes // sa = d+Math.PI; // ind = i; // } @@ -605,7 +604,7 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // } // else // { - // return false; // kein weitergehen möglich + // return false; // No further progression possible // } // } // if (bb.IsOriented) @@ -629,10 +628,10 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // } // private bool FindSimpleBorder(Set clusterSet, ArrayList AllBorders, Set UsedJoints) // { - // // es wird eine minimale Border gesucht: von irgend einem Cluster ausgehend immer - // // linksrum bis man wieder am Anfang ist. - // // UsedJoints enthält UsedJoint objekte, damit man feststellen kann, ob eine Kante bereits - // // benutzt ist oder nicht + // // A minimal border is being searched: starting from any cluster, + // // always move to the left until you are back at the start. + // // UsedJoints contains UsedJoint objects to determine + // // whether an edge has already been used or not. // ICurve2D startWith = null; // bool forward = false; // foreach (Cluster cl in clusterSet) @@ -663,13 +662,13 @@ private Cluster ExtractCurve(ICurve2D ToRemove, bool RemoveStartPoint) // return false; // } private Joint[] SortCluster() - { // sortiert die Kanten (Joints) in einem Cluster im Gegenuhrzeigersinn - // liefert alle Kanten + { // Sorts the edges (joints) in a cluster counterclockwise + // Returns all edges - // Verwerfen von identischen Kanten: - // Zwei Kanten in einem Cluster, die das selbe "Gegencluster" haben - // stehen im Verdacht identisch zu sein. Ihre Mittelpunkte werden auf - // identität überprüft und die Kanten werden ggf. entfernt. + // Discarding identical edges: + // Two edges in a cluster that share the same "opposite cluster" + // are suspected to be identical. Their center points are checked + // for identity, and the edges are removed if necessary. foreach (Cluster cl in clusterSet) { for (int i = 0; i < cl.Joints.Count - 1; ++i) @@ -686,10 +685,10 @@ private Joint[] SortCluster() if (j2.StartCluster == cl) cl2 = j2.EndCluster; else cl2 = j2.StartCluster; if (cl1 == cl2) - { // zwei Kanten verbinden dieselben Cluster. Sie könnten identisch sein + { // Two edges connect the same clusters. They might be identical. ICurve2D curve1 = j1.curve.CloneReverse(j1.StartCluster != cl); ICurve2D curve2 = j2.curve.CloneReverse(j2.StartCluster != cl); - // curve1 und curve2 haben jetzt die selbe Richtung + // curve1 and curve2 now have the same direction GeoPoint2D p1 = curve1.PointAt(0.5); GeoPoint2D p2 = curve2.PointAt(0.5); if (Geometry.Dist(p1, p2) < clusterSize) @@ -705,7 +704,7 @@ private Joint[] SortCluster() } } } - // zu kurze Joints werden entfern + // Joints that are too short will be removed foreach (Cluster cl in clusterSet) { for (int i = cl.Joints.Count - 1; i >= 0; --i) @@ -729,7 +728,7 @@ private Joint[] SortCluster() } continue; } - // zwei Punkte im cluster muss man nicht sortieren + // Two points in the cluster do not need to be sorted double minDist = double.MaxValue; foreach (Joint j in cl.Joints) { @@ -771,13 +770,13 @@ private Joint[] SortCluster() } else { - // darf nicht vorkommen, eine Kante schneidet nicht den Kreis um - // den Knoten mit halbem Radius zum nächsten knoten - // der Sortierwert bleibt halt 0.0, aber man sollte solche Kanten - // entfernen ... - // kommt vor, das Problem liegt bei regle4!!! + // Should not occur: an edge does not intersect the circle around + // the node with half the radius to the next node. + // The sorting value remains 0.0, but such edges + // should be removed... + // It happens; the problem lies with rule4!!! if (j.StartCluster == cl) - { // curve startet hier + { // Curve starts here j.tmpAngle = j.curve.StartDirection.Angle; } else @@ -786,18 +785,18 @@ private Joint[] SortCluster() } } } - cl.Joints.Sort(); // es wird nach tmpAngle sortiert + cl.Joints.Sort(); // Sorting is done based on tmpAngle } Joint[] res = new Joint[allJoints.Count]; int ii = 0; foreach (Joint j in allJoints) - { // die Kurve exakt ausrichten + { // Precisely align the curve try { j.curve.StartPoint = j.StartCluster.center; j.curve.EndPoint = j.EndCluster.center; } - catch (Curve2DException) { } // z.B. Kreise endpunkt setzen + catch (Curve2DException) { } // For example, set the endpoint of circles res[ii] = j; ++ii; } @@ -807,7 +806,7 @@ private BorderBuilder FindBorder(Joint startWith, bool forward) { BorderBuilder bb = new BorderBuilder(); bb.Precision = clusterSize; - if (startWith.curve.Length == 0.0) return null; // sollte nicht vorkommen, kommt aber vor + if (startWith.curve.Length == 0.0) return null; // Should not occur, but it does bb.AddSegment(startWith.curve.CloneReverse(!forward)); Cluster cl; Cluster startCluster; @@ -815,15 +814,15 @@ private BorderBuilder FindBorder(Joint startWith, bool forward) { cl = startWith.EndCluster; startCluster = startWith.StartCluster; - // hier sollte eine Exception geworfen werden wenn schon benutzt!! - if (startWith.forwardUsed) return null; // schon benutzt, sollte nicht vorkommen + // An exception should be thrown here if already used!! + if (startWith.forwardUsed) return null; // Already used, should not occur startWith.forwardUsed = true; } else { cl = startWith.StartCluster; startCluster = startWith.EndCluster; - if (startWith.reverseUsed) return null; // schon benutzt, sollte nicht vorkommen + if (startWith.reverseUsed) return null; // Already used, should not occur startWith.reverseUsed = true; } while (cl != startCluster) @@ -840,19 +839,19 @@ private BorderBuilder FindBorder(Joint startWith, bool forward) } startWith = cl.Joints[ind] as Joint; forward = (startWith.StartCluster == cl); - if (startWith.curve.Length == 0.0) return null; // sollte nicht vorkommen, kommt aber vor + if (startWith.curve.Length == 0.0) return null; // Should not happen, but it does bb.AddSegment(startWith.curve.CloneReverse(!forward)); if (forward) { cl = startWith.EndCluster; - if (startWith.forwardUsed) return null; // schon benutzt, innere Schleife + if (startWith.forwardUsed) return null; // Already used, inner loop startWith.forwardUsed = true; } else { cl = startWith.StartCluster; - if (startWith.reverseUsed) return null; // schon benutzt, innere Schleife - startWith.reverseUsed = true; // auch hier Exception, wenn es schon benutzt war!! + if (startWith.reverseUsed) return null; // Already used, inner loop + startWith.reverseUsed = true; // Here too, throw an exception if it was already used!! } } return bb; @@ -936,19 +935,17 @@ GeoObjectList Joints #endif public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoint, ConstrHatchInside.HatchMode mode, bool partInPart) { - // 1. Die offenen Enden mit anderen offenen Enden verbinden, wenn Abstand kleiner maxGap. - // 2. Alle verbleibenden Sackgassen entfernen (alle einzelpunkte sammeln und von dort aus "aufessen".) - // 3. Es entstehen jetzt zusammenhängende Punktmengen. - // 4. die Kanten bestimmen und Verweise auf die Cluster setzen (das lässt sich vielleicht - // in einen der vorhergehenden Schritte integrieren) - // 5. In den Clustern die Kanten linksherum sortieren - // jetzt haben wir einen (oder mehrere) überschneidungsfreien Graphen, in denen man leicht - // durch linksrumgehen die Border findet. Zusätzlich findet man auch noch für jeden - // Graphen die Hülle. Die erkennt man daran, dass sie rechtrum geht. - // 6. Wenn useInnerPoint == false && partInPart == true dann werden auch verschachtelte Teile gesucht und zurückgegeben + // 1. Connect open ends with other open ends if the distance is less than maxGap. + // 2. Remove all remaining dead ends (collect all single points and "consume" them from there). + // 3. This results in connected point sets. + // 4. Determine the edges and set references to their clusters (this step might be integrated into one of the previous steps). + // 5. Sort the edges counterclockwise within each cluster: + // At this point, we have one or more non-overlapping graphs, where finding the border is easy by walking counterclockwise. + // Additionally, for each graph, the hull can be found. It can be identified as it follows a clockwise direction. + // 6. If useInnerPoint == false && partInPart == true, then nested parts are also searched for and returned. - // Lückenschließer einfügen, und zwar die kürzestmöglichen - // und nur an offenen Enden + // Insert gap fillers, specifically the shortest possible ones, + // and only at open ends. ArrayList CurvesToInsert = new ArrayList(); foreach (Cluster cl in clusterSet) { @@ -975,11 +972,11 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi Insert(curve); } - // hier könnten nun noch auf Wunsch mit ICurve2D.MinDistance zusätzliche Joints - // eingefügt werden, die als echte Lückenschließer dienen könnten und z.B. - // auch einen Flaschenhals aus zwei Kreisbögen schließen würden + // Here, additional joints could optionally be added using ICurve2D.MinDistance, + // which could serve as true gap closers, e.g., closing a bottleneck formed + // by two circular arcs. - // alle Sackgassen entfernen + // Remove all dead ends RemoveAllDeadEnds(); Joint[] AllJoints = SortCluster(); @@ -990,13 +987,13 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi bool inner = (mode != ConstrHatchInside.HatchMode.hull); Border[] AllBorders = FindAllBorders(AllJoints, inner); Array.Sort(AllBorders, new BorderAreaComparer()); - // der größe nach sortieren, zuerst kommt das kleinste + // Sort by size, starting with the smallest if (useInnerPoint) { int bestBorder = -1; if (inner) - { // suche die kleinste umgebende Umrandung: + { // Find the smallest surrounding boundary: for (int i = 0; i < AllBorders.Length; ++i) { if (AllBorders[i].GetPosition(innerPoint) == Border.Position.Inside) @@ -1007,8 +1004,8 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi } } else - { // suche die größte umgebende Umrandung: - // also rückwärts durch das array + { // Find the largest surrounding boundary: + // Iterate backwards through the array for (int i = AllBorders.Length - 1; i >= 0; --i) { if (AllBorders[i].GetPosition(innerPoint) == Border.Position.Inside) @@ -1022,7 +1019,7 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi { if (mode == ConstrHatchInside.HatchMode.excludeHoles) { - // nur die kleineren Borders betrachten, die größeren können ja keine Löcher sein + // Only consider the smaller borders, as the larger ones cannot be holes SimpleShape ss = new SimpleShape(AllBorders[bestBorder]); CompoundShape cs = new CompoundShape(ss); for (int j = 0; j < bestBorder; ++j) @@ -1046,7 +1043,7 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi } else { - // wenn nicht "useInnerPoint", dann die erste (größte) Border liefern + // If "useInnerPoint" is not enabled, return the first (largest) border if (AllBorders.Length == 0) return null; @@ -1054,18 +1051,18 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi if (AllBorders.Length == 1) return new CompoundShape(new SimpleShape(AllBorders[0])); - //Bei mehr als einer Border - Array.Reverse(AllBorders); // das größte zuerst + // If there is more than one border + Array.Reverse(AllBorders); // The largest one first List toIterate = new List(AllBorders); - if (!partInPart) //Hier werden Teile die in Teilen liegen entfernt + if (!partInPart) // Here, parts that lie within other parts are removed { CompoundShape res = new CompoundShape(); while (toIterate.Count > 0) { SimpleShape ss = new SimpleShape(toIterate[0]); CompoundShape cs = new CompoundShape(ss); - // das erste ist der Rand, die folgenden die Löcher + // The first is the edge, the following are the holes for (int i = toIterate.Count - 1; i > 0; --i) { SimpleShape ss1 = new SimpleShape(toIterate[i]); @@ -1080,32 +1077,32 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi } return res; } - else //Hier werden Teile in Teilen als neues SimpleShape zurückgegeben + else // Here, parts within other parts are returned as a new SimpleShape { CompoundShape cs = new CompoundShape(new SimpleShape(toIterate[0])); - //Von groß nach klein + // From large to small for (int i = 1; i < toIterate.Count; i++) { SimpleShape innerShape = new SimpleShape(toIterate[i]); - //Position des innerShape bestimmen + // Determine the position of the innerShape var shapePos = SimpleShape.GetPosition(cs.SimpleShapes[0], innerShape); switch (shapePos) { case SimpleShape.Position.firstcontainscecond: - //innerShape aus outerShape ausschneiden weil dieses vollständig innerhalb liegt + // Cut innerShape from outerShape because it is completely inside cs.Subtract(innerShape); break; case SimpleShape.Position.intersecting: - //sollten sich Teile überschneiden werden diese zusammengefügt + // If parts overlap, they are merged cs = CompoundShape.Union(cs, new CompoundShape(innerShape)); break; case SimpleShape.Position.disjunct: - //die Teile liegen vollständig unabhängig + // The parts are completely independent bool shapeHandled = false; - //aber vielleicht liegt das Teil innerhalb eines der anderen SimpleShapes? + // But maybe the part is inside one of the other SimpleShapes? for (int j = 1; j < cs.SimpleShapes.Length; j++) { var shapePos2 = SimpleShape.GetPosition(cs.SimpleShapes[j], innerShape); @@ -1130,7 +1127,7 @@ public CompoundShape CreateCompoundShape(bool useInnerPoint, GeoPoint2D innerPoi return cs; } } - // was sollen wir liefern, wenn nicht useInnerPoint gegeben ist und mehrere Borders gefunden wurden? + // What should we return if useInnerPoint is not provided and multiple borders were found? return null; } } diff --git a/CADability/Curves2D.cs b/CADability/Curves2D.cs index 84b04333..b1f533a1 100644 --- a/CADability/Curves2D.cs +++ b/CADability/Curves2D.cs @@ -298,38 +298,30 @@ public static GeoPoint2D[] TangentCircle(ICurve2D c1, ICurve2D c2, ICurve2D c3, { case 0: return TangentCircleLLL(c1 as Line2D, c2 as Line2D, c3 as Line2D); - break; case 1: points = TangentCircleLLC(c2 as Line2D, c3 as Line2D, c1 as Circle2D); Exchange(points, 2, 0); Exchange(points, 2, 1); return points; - break; case 2: points = TangentCircleLLC(c1 as Line2D, c3 as Line2D, c2 as Circle2D); Exchange(points, 2, 1); return points; - break; case 3: points = TangentCircleLCC(c3 as Line2D, c1 as Circle2D, c2 as Circle2D); Exchange(points, 0, 2); Exchange(points, 0, 1); return points; - break; case 4: return TangentCircleLLC(c1 as Line2D, c2 as Line2D, c3 as Circle2D); - break; case 5: points = TangentCircleLCC(c2 as Line2D, c1 as Circle2D, c3 as Circle2D); Exchange(points, 1, 0); return points; - break; case 6: return TangentCircleLCC(c1 as Line2D, c2 as Circle2D, c3 as Circle2D); - break; case 7: return TangentCircleCCC(c1 as Circle2D, c2 as Circle2D, c3 as Circle2D); - break; } diff --git a/CADability/CylindricalSurface.cs b/CADability/CylindricalSurface.cs index 130ea0ec..5a8634ee 100644 --- a/CADability/CylindricalSurface.cs +++ b/CADability/CylindricalSurface.cs @@ -342,18 +342,20 @@ public override ICurve[] Intersect(BoundingRect thisBounds, ISurface other, Boun } else { // ein paar spezielle Lösungen (mit Ellipsen als Ergebnis) abfangen. BoxedSurfaceEx.Intersect ist aber auch gut! + + double dpar1, dpar2; + double adist = Geometry.DistLL(this.Location, this.Axis, cyl2.Location, cyl2.Axis, out dpar1, out dpar2); + if (adist < Precision.eps) { - double dpar1, dpar2; - double adist = Geometry.DistLL(this.Location, this.Axis, cyl2.Location, cyl2.Axis, out dpar1, out dpar2); - if (adist < Precision.eps) - { - } - GetExtremePositions(thisBounds, other, otherBounds, out List> extremePositions); - if (usedArea.IsInfinite || double.IsInfinity(usedArea.Size)) { usedArea = thisBounds; } - ICurve[] res = BoxedSurfaceEx.Intersect(thisBounds, other, otherBounds, null, extremePositions); - return res; } + GetExtremePositions(thisBounds, other, otherBounds, out List> extremePositions); + if (usedArea.IsInfinite || double.IsInfinity(usedArea.Size)) { usedArea = thisBounds; } + ICurve[] res = BoxedSurfaceEx.Intersect(thisBounds, other, otherBounds, null, extremePositions); + return res; + + //Unreachable code + /* InterpolatedDualSurfaceCurve.SurfacePoint[] basePoints = new InterpolatedDualSurfaceCurve.SurfacePoint[5]; // wir brauchen 4 Punkte (der 5. ist der 1.) // zwei Ebenen sind gegeben durch die Achse eines Zylinder und der Senkrechten auf beide Achsen, dgl. mit dem anderen Zylinder @@ -386,6 +388,7 @@ public override ICurve[] Intersect(BoundingRect thisBounds, ISurface other, Boun } } } + */ } } if (other is SphericalSurface) diff --git a/CADability/DualSurfaceCurve.cs b/CADability/DualSurfaceCurve.cs index 9ba87a69..1de7997e 100644 --- a/CADability/DualSurfaceCurve.cs +++ b/CADability/DualSurfaceCurve.cs @@ -615,7 +615,6 @@ public class ProjectedCurve : GeneralCurve2D, ISerializable BoundingRect periodicDomain; // only for periodic domains: to which period the 3d points should be mapped GeoPoint2D startPoint2d, endPoint2d; bool startPointIsPole, endPointIsPole; - bool spu, epu; // starting or ending pole in u #if DEBUG static int debugCounter = 0; private int debugCount; // to identify instance when debugging @@ -704,14 +703,12 @@ public ProjectedCurve(ICurve curve3D, ISurface surface, bool forward, BoundingRe GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.1)); startPoint2d = new GeoPoint2D(us[i], tmp.y); startPointIsPole = true; - spu = true; } if ((pl | ep) < prec) { GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.9)); endPoint2d = new GeoPoint2D(us[i], tmp.y); endPointIsPole = true; - epu = true; } } double[] vs = surface.GetVSingularities(); @@ -723,14 +720,12 @@ public ProjectedCurve(ICurve curve3D, ISurface surface, bool forward, BoundingRe GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.1)); startPoint2d = new GeoPoint2D(tmp.x, vs[i]); startPointIsPole = true; - spu = false; } if ((pl | ep) < prec*10) { GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.9)); endPoint2d = new GeoPoint2D(tmp.x, vs[i]); endPointIsPole = true; - epu = false; } } if (forward) diff --git a/CADability/Edge.cs b/CADability/Edge.cs index 190a4587..742daa43 100644 --- a/CADability/Edge.cs +++ b/CADability/Edge.cs @@ -1823,7 +1823,8 @@ internal void UpdateInterpolatedDualSurfaceCurve() #endif return; - + //Unreachable code + /* //BoundingRect bounds1 = curveOnPrimaryFace.GetExtent(); //BoundingRect bounds2 = curveOnSecondaryFace.GetExtent(); // sicher ist hier, dass StartVertex und EndVertex stimmen @@ -1912,6 +1913,7 @@ internal void UpdateInterpolatedDualSurfaceCurve() #if DEBUG dsc.CheckSurfaceParameters(); #endif + */ } } else @@ -2713,7 +2715,7 @@ private void Approximate(SortedDictionary parpoint, ICurve2D Polyline pdbg = Polyline.Construct(); pdbg.SetPoints(pnts, false); } - catch (PolylineException ex) { }; + catch (PolylineException) { }; } #endif if (curve3d != null) dist = Math.Max(dist, curve3d.DistanceTo(mp)); diff --git a/CADability/Ellipse.cs b/CADability/Ellipse.cs index f29c17b5..b3e84637 100644 --- a/CADability/Ellipse.cs +++ b/CADability/Ellipse.cs @@ -279,59 +279,52 @@ internal virtual EllipseData2D CalculateProjectionData(Plane pr) if (ccw) res.sweepAng = SweepAngle.Full; else res.sweepAng = SweepAngle.FullReverse; } - //if (IsArc || this.startParameter != 0.0) - if (true) // auch bei einem Vollkreis ist es wichtig, Start-und Endpunkt zu erhalten (geändert: 15.9.15) - { - // für andere Zwecke braucht man Start- und Endparameter: - double[,] a = new double[2, 2]; - double[] b = new double[2]; - a[0, 0] = res.majax.x; - a[0, 1] = res.minax.x; - a[1, 0] = res.majax.y; - a[1, 1] = res.minax.y; - b[0] = StartDir.x; - b[1] = StartDir.y; - Vector x = (Vector)DenseMatrix.OfArray(a).Solve(new DenseVector(b)); - if (x.IsValid()) - { - res.startParameter = Math.Atan2(x[1], x[0]); - } - a[0, 0] = res.majax.x; - a[0, 1] = res.minax.x; - a[1, 0] = res.majax.y; - a[1, 1] = res.minax.y; - b[0] = EndDir.x; - b[1] = EndDir.y; - x = (Vector)DenseMatrix.OfArray(a).Solve(new DenseVector(b)); - if (x.IsValid()) + + // für andere Zwecke braucht man Start- und Endparameter: + double[,] a = new double[2, 2]; + double[] b = new double[2]; + a[0, 0] = res.majax.x; + a[0, 1] = res.minax.x; + a[1, 0] = res.majax.y; + a[1, 1] = res.minax.y; + b[0] = StartDir.x; + b[1] = StartDir.y; + Vector x = (Vector)DenseMatrix.OfArray(a).Solve(new DenseVector(b)); + if (x.IsValid()) + { + res.startParameter = Math.Atan2(x[1], x[0]); + } + a[0, 0] = res.majax.x; + a[0, 1] = res.minax.x; + a[1, 0] = res.majax.y; + a[1, 1] = res.minax.y; + b[0] = EndDir.x; + b[1] = EndDir.y; + x = (Vector)DenseMatrix.OfArray(a).Solve(new DenseVector(b)); + if (x.IsValid()) + { + double endpar = Math.Atan2(x[1], x[0]); + SweepAngle sw; + // ccw ist doch schon umgedreht, wenn n.z<0 ist. Deshalb hier nicht nochmal umdrehen + // siehe z.B. CylCoord.cdb, dort ist die aufgeteilte Ellipse sonst nicht mehr pickbar + //if (n.z < 0) + //{ + // sw = new SweepAngle(new Angle(endpar), new Angle(res.startParameter), ccw); + // res.startParameter = endpar; + //} + //else + //{ + sw = new SweepAngle(new Angle(res.startParameter), new Angle(endpar), ccw); + //} + res.sweepParameter = sw.Radian; + if (Math.Abs(res.sweepParameter) < 1e-6 && Math.Abs(res.sweepAng) > Math.PI) { - double endpar = Math.Atan2(x[1], x[0]); - SweepAngle sw; - // ccw ist doch schon umgedreht, wenn n.z<0 ist. Deshalb hier nicht nochmal umdrehen - // siehe z.B. CylCoord.cdb, dort ist die aufgeteilte Ellipse sonst nicht mehr pickbar - //if (n.z < 0) - //{ - // sw = new SweepAngle(new Angle(endpar), new Angle(res.startParameter), ccw); - // res.startParameter = endpar; - //} - //else - //{ - sw = new SweepAngle(new Angle(res.startParameter), new Angle(endpar), ccw); - //} - res.sweepParameter = sw.Radian; - if (Math.Abs(res.sweepParameter) < 1e-6 && Math.Abs(res.sweepAng) > Math.PI) - { - // Sonderfall: ein fast Vollkreis wird nicht als solcher erkannt und liefert - // allerdings exakt 0.0 für sweepAng - if (ccw) res.sweepParameter = Math.Abs(res.sweepAng); - else res.sweepParameter = -Math.Abs(res.sweepAng); - } + // Sonderfall: ein fast Vollkreis wird nicht als solcher erkannt und liefert + // allerdings exakt 0.0 für sweepAng + if (ccw) res.sweepParameter = Math.Abs(res.sweepAng); + else res.sweepParameter = -Math.Abs(res.sweepAng); } } - else - { - res.sweepParameter = res.sweepAng; // 2pi oder -2pi, Richtung stimmt schon - } } return res; } diff --git a/CADability/Ellipse2D.cs b/CADability/Ellipse2D.cs index 32691914..c09dd0b9 100644 --- a/CADability/Ellipse2D.cs +++ b/CADability/Ellipse2D.cs @@ -756,7 +756,7 @@ public double NewtonPerpendicular(GeoPoint2D fromHere, double position) MinimizationResult mres = nm.FindMinimum(iof, new DenseVector(new double[] { position })); return mres.MinimizingPoint[0]; } - catch (Exception ex) + catch (Exception) { return iof.Point[0]; } diff --git a/CADability/EllipseArc2D.cs b/CADability/EllipseArc2D.cs index c374db6a..46bb530b 100644 --- a/CADability/EllipseArc2D.cs +++ b/CADability/EllipseArc2D.cs @@ -809,6 +809,9 @@ private double areaHelper(double a, double b, double phi) public override double GetArea() { // Area from origin, source: https://www.geometrictools.com/Documentation/AreaIntersectingEllipses.pdf double a = majorAxis.Length, b = minorAxis.Length; + + //Unreachable Code + /* if (false) // nonsense, works the same for ellipses >180°, was: (sweepPar > Math.PI) { // make two sections, because the formula works only for angles less than 180° @@ -835,23 +838,24 @@ public override double GetArea() } else { - GeoPoint2D startPoint = StartPoint; - GeoPoint2D endPoint = EndPoint; - double triangle = startPoint.x * endPoint.y - startPoint.y * endPoint.x; - double phi1 = (startPoint - center).Angle - majorAxis.Angle; - double phi2 = (endPoint - center).Angle - majorAxis.Angle; - if (Sweep > 0) // chenged to "Sweep" because "sweep" was positiv when it should have been negative - { - if (phi2 <= phi1) phi2 += Math.PI * 2; - } - else - { - if (phi2 >= phi1) phi2 -= Math.PI * 2; - } - double segment = a * b * (areaHelper(a, b, phi2) - areaHelper(a, b, phi1)); // this is the double value - double segtriangle = GeoVector2D.Area(startPoint - center, endPoint - center); // area of the parallelogram - return (triangle + segment - segtriangle) / 2.0; // all values are double size, hence /2.0 + */ + GeoPoint2D startPoint = StartPoint; + GeoPoint2D endPoint = EndPoint; + double triangle = startPoint.x * endPoint.y - startPoint.y * endPoint.x; + double phi1 = (startPoint - center).Angle - majorAxis.Angle; + double phi2 = (endPoint - center).Angle - majorAxis.Angle; + if (Sweep > 0) // chenged to "Sweep" because "sweep" was positiv when it should have been negative + { + if (phi2 <= phi1) phi2 += Math.PI * 2; + } + else + { + if (phi2 >= phi1) phi2 -= Math.PI * 2; } + double segment = a * b * (areaHelper(a, b, phi2) - areaHelper(a, b, phi1)); // this is the double value + double segtriangle = GeoVector2D.Area(startPoint - center, endPoint - center); // area of the parallelogram + return (triangle + segment - segtriangle) / 2.0; // all values are double size, hence /2.0 + //} } public EllipseArc2D GetComplement() { diff --git a/CADability/ExportDxf.cs b/CADability/ExportDxf.cs index c8cadf36..a2279d9f 100644 --- a/CADability/ExportDxf.cs +++ b/CADability/ExportDxf.cs @@ -81,7 +81,16 @@ private EntityObject[] GeoObjectToEntity(IGeoObject geoObject) case GeoObject.Ellipse elli: entity = ExportEllipse(elli); break; case GeoObject.Polyline polyline: entity = ExportPolyline(polyline); break; case GeoObject.BSpline bspline: entity = ExportBSpline(bspline); break; - case GeoObject.Path path: entity = ExportPath(path); break; + case GeoObject.Path path: + if (Settings.GlobalSettings.GetBoolValue("DxfExport.ExportPathsAsBlocks", true)) + { + entity = ExportPath(path); + } + else + { + entities = ExportPathWithoutBlock(path); + } + break; case GeoObject.Text text: entity = ExportText(text); break; case GeoObject.Block block: entity = ExportBlock(block); break; case GeoObject.Face face: entity = ExportFace(face); break; @@ -98,18 +107,18 @@ private EntityObject[] GeoObjectToEntity(IGeoObject geoObject) { for (int i = 0; i < entities.Length; i++) { - if (geoObject.Layer != null && !createdLayers.TryGetValue(geoObject.Layer, out netDxf.Tables.Layer layer)) + if (geoObject.Layer == null) + { + entities[i].Layer = netDxf.Tables.Layer.Default; + continue; + } + if (!createdLayers.TryGetValue(geoObject.Layer, out netDxf.Tables.Layer layer)) { layer = new netDxf.Tables.Layer(geoObject.Layer.Name); doc.Layers.Add(layer); createdLayers[geoObject.Layer] = layer; } - else - { - layer = netDxf.Tables.Layer.Default; - } entities[i].Layer = layer; - } return entities; } @@ -358,6 +367,17 @@ private netDxf.Entities.Insert ExportPath(Path path) return new netDxf.Entities.Insert(block); } + private EntityObject[] ExportPathWithoutBlock(Path path) + { + List entities = new List(); + for (int i = 0; i < path.Curves.Length; i++) + { + EntityObject[] curve = GeoObjectToEntity(path.Curves[i] as IGeoObject); + if (curve != null) entities.AddRange(curve); + } + return entities.ToArray(); + } + private netDxf.Entities.Spline ExportBSpline(BSpline bspline) { List poles = new List(bspline.Poles.Length); diff --git a/CADability/ExportToWebGl.cs b/CADability/ExportToWebGl.cs index 95f5597c..caf9b211 100644 --- a/CADability/ExportToWebGl.cs +++ b/CADability/ExportToWebGl.cs @@ -1231,7 +1231,7 @@ public bool WriteToFile(string outPath) outfile.Close(); } } - catch (IOException e) + catch (IOException) { return false; } diff --git a/CADability/Face.cs b/CADability/Face.cs index 80edc21c..007ca876 100644 --- a/CADability/Face.cs +++ b/CADability/Face.cs @@ -5898,7 +5898,11 @@ private void Triangulate(double precision) { SimpleShape ss = Area; // damit es sicher bestimmt ist // wenn die Fläche Knicke hat, dann entlang der Knicke aufteilen + + //Code unreachable + /* ICurve2D[] discontinuities; + if (false) // if (surface.HasDiscontinuousDerivative(out discontinuities)) { @@ -5947,10 +5951,11 @@ private void Triangulate(double precision) triangleIndex = lsttriangleIndex.ToArray(); } return; - } - } - + } + } } + */ + #if DEBUG // System.Diagnostics.Trace.WriteLine("Triangulate: " + hashCode.ToString() + ", prec: " + precision.ToString() + ", " + (System.Environment.TickCount / 100).ToString()); #endif @@ -6305,7 +6310,7 @@ private void Triangulate(double precision) } } } - catch (ApplicationException e) + catch (ApplicationException) { // something went wrong with the triangulation. This should not happen and needs to be debugged and fixed } triangleExtent = BoundingCube.EmptyBoundingCube; // needs to be recalculated @@ -6606,7 +6611,7 @@ public void GetSimpleTriangulation(double precision, bool noInnerPoints, out Geo } #endif } - catch (ApplicationException e) + catch (ApplicationException) { // Selbstüberschneidungen von Löchern und Rand oder in den Rändern selbst List sumTriUv = new List(); List sumTriPoint = new List(); @@ -7958,7 +7963,6 @@ internal static bool CheckOutlineDirection(Face fc, Edge[] outline, double uperi selections[segments.Length - 2].Remove(selections[segments.Length - 2].FirstItem.Key, selections[segments.Length - 2].FirstItem.Value); } } - return false; } catch (Exception) { @@ -9030,6 +9034,9 @@ internal void MakeInverseOrientation() { ReverseOrientation(); // das ist identisch mit diesem hier!! return; + + //Unreachable code + /* SimpleShape ss = Area; BoundingRect ext = ss.GetExtent(); GeoPoint2D c = ss.GetExtent().GetCenter(); @@ -9105,6 +9112,8 @@ internal void MakeInverseOrientation() ss = Area; // DEBUG orientedOutward = false; + + */ } else { diff --git a/CADability/Filter.cs b/CADability/Filter.cs index 4e9cb639..877ee9ca 100644 --- a/CADability/Filter.cs +++ b/CADability/Filter.cs @@ -468,7 +468,7 @@ private static Dictionary FindAllGeoObjects() } return res; } - catch (System.Reflection.ReflectionTypeLoadException e) + catch (System.Reflection.ReflectionTypeLoadException) { // MessageBox.Show(e.Message); return new Dictionary(); @@ -770,7 +770,7 @@ public override void EndEdit(bool aborted, bool modified, string newValue) { Name = newValue; } - catch (NameAlreadyExistsException e) { } + catch (NameAlreadyExistsException) { } } } public override string LabelText { get => Name; set => Name = value; } diff --git a/CADability/GeneralCurve.cs b/CADability/GeneralCurve.cs index 1a6d4e6f..8067aa5d 100644 --- a/CADability/GeneralCurve.cs +++ b/CADability/GeneralCurve.cs @@ -1096,6 +1096,9 @@ private void MakeTetraeder(double from, double to, List points, List d12 || (p1 | p3) > d12 || (p1 | p4) > d12 || (p2 | p3) > d12 || (p2 | p4) > d12) + + //Unreachable code + /* if (false) { // die Sehne p1->p2 muss die längste Seite des Tatraeders sein double m = (from + to) / 2.0; @@ -1104,25 +1107,27 @@ private void MakeTetraeder(double from, double to, List points, List 0) // war vorher anders so sind die Ebenen alle so orientiert, dass sie nach außen zeigen - // aber die Orientierung ist immer noch nicht gut - // if ((((p2 - p1) ^ (p3 - p1)) * (p4 - p1)) < 0) - { - vertices.Add(p4); - vertices.Add(p3); - } - else - { - vertices.Add(p3); - vertices.Add(p4); - } + */ + + // Orientierung überprüfen + Plane plt = new Plane(p1, p3, p2); // geht ggf. nach PlaneException + pars.Add(from); + points.Add(p1); + GeoPoint pm = new GeoPoint(p1, p2, p3, p4); + GeoPoint p11 = plt.ToLocal(pm); + if (p11.z > 0) // war vorher anders so sind die Ebenen alle so orientiert, dass sie nach außen zeigen + // aber die Orientierung ist immer noch nicht gut + // if ((((p2 - p1) ^ (p3 - p1)) * (p4 - p1)) < 0) + { + vertices.Add(p4); + vertices.Add(p3); + } + else + { + vertices.Add(p3); + vertices.Add(p4); } + //} } else { // es geht völlig gerade weiter diff --git a/CADability/GeneralCurve2D.cs b/CADability/GeneralCurve2D.cs index 8e1df221..b33da9e4 100644 --- a/CADability/GeneralCurve2D.cs +++ b/CADability/GeneralCurve2D.cs @@ -1446,6 +1446,8 @@ GeoPoint2D[] I2DIntersectable.IntersectWith(I2DIntersectable other) { GeoPoint2DWithParameter[] ips = Intersect(other as ICurve2D); GeoPoint2D[] res = new GeoPoint2D[ips.Length]; + + //TODO: This does not make sense. Returning directly in a for loop for (int i = 0; i < ips.Length; i++) { res[i] = ips[i].p; @@ -1627,7 +1629,7 @@ protected void MakeTriangulation() if (directions[0].IsNullVector()) linterdir.Add((points[1] - points[0]).Normalized); else linterdir.Add(directions[0].Normalized); } - catch (GeoVectorException ex) + catch (GeoVectorException) { linterdir.Add(GeoVector2D.XAxis); } @@ -3562,6 +3564,9 @@ private bool BisectPerpendicular(double p1, double p2, GeoVector2D dir, out doub } par = p1 + Math.Abs(d1) / (Math.Abs(d1) + Math.Abs(d2)) * (p2 - p1); return true; // this is a good value without much iteration. This method is only used to find the extend and may be somewhat imprecise + + //Unreachable code + /* while (p2 - p1 > 1e-6) { double p = (p1 + p2) / 2.0; @@ -3582,6 +3587,7 @@ private bool BisectPerpendicular(double p1, double p2, GeoVector2D dir, out doub } par = (p1 + p2) / 2.0; return true; + */ } private bool TriangleHitTest(ref ClipRect rect, GeoPoint2D sp, GeoPoint2D ep, GeoPoint2D tr, double spar, double epar, GeoVector2D sdir, GeoVector2D edir) diff --git a/CADability/GeneralSweptCurve.cs b/CADability/GeneralSweptCurve.cs index d7a4d056..46ad0ee5 100644 --- a/CADability/GeneralSweptCurve.cs +++ b/CADability/GeneralSweptCurve.cs @@ -679,6 +679,8 @@ public override GeoVector VDirection(GeoPoint2D uv) return f * (PointAt(p2) - PointAt(p1)); // das ist einfach ein kleines umgebendes Intervall diskret abgeleitet (bis ich eine bessere Lösung habe) // forDerivation wird nicht benötigt + //Unreachable code + /* GeoPoint loc; GeoVector deriv1, deriv2; if (along.TryPointDeriv2At(uv.y, out loc, out deriv1, out deriv2)) @@ -713,6 +715,7 @@ public override GeoVector VDirection(GeoPoint2D uv) return res; } return GeoVector.NullVector; // da muss nocht die NURBS Hilsfläche gemacht werden + */ } private ModOp modOpAt(double v) { diff --git a/CADability/ImportDxf.cs b/CADability/ImportDxf.cs index c623df28..29e24e9c 100644 --- a/CADability/ImportDxf.cs +++ b/CADability/ImportDxf.cs @@ -530,7 +530,7 @@ private IGeoObject CreateSpline(netDxf.Entities.Spline spline) ICurve curve = (ICurve)bsp; //Use approximate to get the count of lines that will be needed to convert the spline into a Polyline2D - double maxError = project.Frame.GetDoubleSetting("Approximate.Precision", 0.01); + double maxError = Settings.GlobalSettings.GetDoubleValue("Approximate.Precision", 0.01); ICurve approxCurve = curve.Approximate(true, maxError); int usedCurves = 0; @@ -881,8 +881,10 @@ private IGeoObject CreateMLine(netDxf.Entities.MLine mLine) blk.Set(res); return blk; } - else if (res.Count == 1) return res[0]; - else return null; + + if (res.Count == 1) + return res[0]; + return null; } private string processAcadString(string acstr) diff --git a/CADability/ImportStep.cs b/CADability/ImportStep.cs index f97f3da1..46e952ab 100644 --- a/CADability/ImportStep.cs +++ b/CADability/ImportStep.cs @@ -4563,7 +4563,6 @@ private object CreateEntity(Item item) importProblems[item.definingIndex] = "item not imported: " + item.type.ToString(); break; } - break; } #if DEBUG lock (definitionStack) definitionStack.Pop(); @@ -4695,6 +4694,9 @@ private ModOp GetTransformation(Item origin, Item target, Item origContext, Item //System.Diagnostics.Trace.WriteLine(" (" + res.Item(1, 0).ToString("F3", c) + ", " + res.Item(1, 1).ToString("F3", c) + ", " + res.Item(1, 2).ToString("F3", c) + ", " + res.Item(1, 3).ToString("F3", c) + ")"); //System.Diagnostics.Trace.WriteLine(" (" + res.Item(2, 0).ToString("F3", c) + ", " + res.Item(2, 1).ToString("F3", c) + ", " + res.Item(2, 2).ToString("F3", c) + ", " + res.Item(2, 3).ToString("F3", c) + ")"); return res; + + //Unreachable code + /* // according to pdmug_release4_3.pdf, page 52, but not used GeoVector zo = (GeoVector)origin.parameter["axis"].val; GeoVector ao = (GeoVector)origin.parameter["ref_direction"].val; @@ -4759,6 +4761,7 @@ private ModOp GetTransformation(Item origin, Item target, Item origContext, Item ModOp rot = ModOp.Fit(new GeoVector[] { org.DirectionZ, cross, -orgperp }, new GeoVector[] { trg.DirectionZ, cross, trgperp }); ModOp trans = ModOp.Translate(org.Location - trg.Location); return trans * rot; + */ } private double GetContextLengthFactor(Item item) diff --git a/CADability/InterpolatedDualSurfaceCurve.cs b/CADability/InterpolatedDualSurfaceCurve.cs index dfb81eb3..8e09575d 100644 --- a/CADability/InterpolatedDualSurfaceCurve.cs +++ b/CADability/InterpolatedDualSurfaceCurve.cs @@ -1799,7 +1799,8 @@ private void ApproximatePosition(double position, out GeoPoint2D uv1, out GeoPoi other = surface1; } //if (pls != null) // noch untersuchen, warum das am Ende manchmal fehlschlägt - if (false) + //Unreachable code + /*if (false) { GeoPoint loc; GeoVector dir; @@ -1907,6 +1908,8 @@ private void ApproximatePosition(double position, out GeoPoint2D uv1, out GeoPoi } } } + */ + if (surface1 is ISurfacePlaneIntersection && surface2 is ISurfacePlaneIntersection) { // Schnittpunkt der beiden einfachen Kurven, die die Ebene mit den surfaces schneidet // geht schneller als die Iteration @@ -2319,9 +2322,14 @@ public override double PositionOf(GeoPoint p) double ppos = TetraederHull.PositionOf(p); if (approxPolynom == null) InitApproxPolynom(); double pos1 = approxPolynom.PositionOf(p, out double md); - if ((PointAt(pos1) | p) < (PointAt(ppos) | p)) return pos1; - else return ppos; - if (Math.Abs(pos1 - ppos) > 0.1 && md < Precision.eps) + + if ((PointAt(pos1) | p) < (PointAt(ppos) | p)) + return pos1; + + return ppos; + + //Unreachable code + /* if (Math.Abs(pos1 - ppos) > 0.1 && md < Precision.eps) { } return ppos; double res = -1.0; @@ -2361,7 +2369,7 @@ public override double PositionOf(GeoPoint p) } } } - return res / (basePoints.Length - 1); + return res / (basePoints.Length - 1);*/ } public override double PositionOf(GeoPoint p, double prefer) { diff --git a/CADability/LayerList.cs b/CADability/LayerList.cs index 67774287..494673f3 100644 --- a/CADability/LayerList.cs +++ b/CADability/LayerList.cs @@ -544,7 +544,7 @@ private void OnRemoveUnused() } } while (found); } - catch (InvalidOperationException e) + catch (InvalidOperationException) { // soll mal bei der Iteration vorgekommen sein (Mail vom 21.10 13, Nürnberger) kann ich mir aber nicht erklären } } diff --git a/CADability/LayoutView.cs b/CADability/LayoutView.cs index b1912133..1cb61479 100644 --- a/CADability/LayoutView.cs +++ b/CADability/LayoutView.cs @@ -129,7 +129,7 @@ public void Print(PrintDocument pd) { pd.Print(); } - catch (Exception e) + catch (Exception) { } pd.PrintPage -= new PrintPageEventHandler(pdg.OnPrintPage); @@ -141,7 +141,7 @@ public void Print(PrintDocument pd) { pd.Print(); } - catch (Exception e) + catch (Exception) { } pd.PrintPage -= new PrintPageEventHandler(OnPrintPage); diff --git a/CADability/Line2D.cs b/CADability/Line2D.cs index b2007fd2..49f7c5c3 100644 --- a/CADability/Line2D.cs +++ b/CADability/Line2D.cs @@ -838,21 +838,18 @@ public bool HitTest(ref BoundingRect Rect, bool IncludeControlPoints) case Direction.toLeft: if (Rect.Left > startPoint.x) return false; return Rect.Bottom <= startPoint.y && Rect.Top >= startPoint.y; - break; case Direction.toRight: if (Rect.Right < startPoint.x) return false; return Rect.Bottom <= startPoint.y && Rect.Top >= startPoint.y; - break; case Direction.toBottom: if (Rect.Bottom > startPoint.y) return false; return Rect.Left <= startPoint.x && Rect.Right >= startPoint.x; - break; case Direction.toTop: if (Rect.Top < startPoint.y) return false; return Rect.Left <= startPoint.x && Rect.Right >= startPoint.x; - break; + default: + return false; } - return false; // damit der Compiler zufrieden ist } public object ReferencedObject { diff --git a/CADability/Make3D.cs b/CADability/Make3D.cs index 85685872..1e24e2ba 100644 --- a/CADability/Make3D.cs +++ b/CADability/Make3D.cs @@ -403,9 +403,8 @@ public static IGeoObject MakePrism(IGeoObject faceShellOrPath, GeoVector extrusi } } } - else if (faceShellOrPath is Face) + else if (faceShellOrPath is Face fc) { - Face fc = faceShellOrPath as Face; if (fc.Area.HasSingleSegmentBorder()) { // nur eine geschlossene Kante. Besser zwei Kanten machen @@ -420,7 +419,11 @@ public static IGeoObject MakePrism(IGeoObject faceShellOrPath, GeoVector extrusi if (edg.SecondaryFace != null) mustBeCloned = true; } if (mustBeCloned) fc = fc.Clone() as Face; // neue Edges + return Solid.MakeSolid(MakeBrutePrism(fc, extrusion)); + + //Unreachable code + /* GeoVector normal = fc.Surface.GetNormal(fc.Area.GetExtent().GetCenter()); if (normal * extrusion > 0) { @@ -582,6 +585,7 @@ public static IGeoObject MakePrism(IGeoObject faceShellOrPath, GeoVector extrusi sld.SetShell(sh); if (project != null) project.SetDefaults(sld); return sld; // Testweise wieder mit OCAS, da ein Problem bei ??? + */ } return null; } @@ -1273,7 +1277,6 @@ internal static Shell MakePipe(ICurve along, double radius, GeoVector seam) res.SetFaces(new Face[] { fc }); return res; } - return null; } public static Face MakeFace(Path path, Project project) { diff --git a/CADability/MultiGeoPointProperty.cs b/CADability/MultiGeoPointProperty.cs index 0aa6e33d..4865274a 100644 --- a/CADability/MultiGeoPointProperty.cs +++ b/CADability/MultiGeoPointProperty.cs @@ -376,7 +376,7 @@ private void OnFilterSinglePointCommand(GeoPointProperty sender, string menuId, break; } } - catch (IndexOutOfRangeException e) + catch (IndexOutOfRangeException) { } } diff --git a/CADability/NDimTree.cs b/CADability/NDimTree.cs index d1dbd8f9..591f18b2 100644 --- a/CADability/NDimTree.cs +++ b/CADability/NDimTree.cs @@ -466,6 +466,8 @@ protected override bool HitTest(Edge e, double[] min, double[] max) } return false; + //Unreachable code + /* // min and max describe a family of planes defined by x*n=d, where min[] or max[] are {nx, ny, nz, d} // now ther is a cube spanned by the min-nx,ny,nz and max-nx,ny,nz // if this cube interferes with the plane normal to edgedir (and origin) @@ -551,6 +553,7 @@ protected override bool HitTest(Edge e, double[] min, double[] max) else if (s0 != s) return true; // different signs of distance to vertex from two extreme planes } return false; // all planes have the vertex on the same side. There is no plane in the family which contains the point. + */ } protected override Node[] MakeSubNodes(Node node) { diff --git a/CADability/NurbsSurface.cs b/CADability/NurbsSurface.cs index 15c1db61..9b611ca9 100644 --- a/CADability/NurbsSurface.cs +++ b/CADability/NurbsSurface.cs @@ -1976,7 +1976,7 @@ bool GetSimpleSurfaceX(double precision, out ISurface simpleSurface, out ModOp2D { reparametrisation = ModOp2D.Fit(srcf, dstf, true); } - catch (ModOpException mex) + catch (ModOpException) { return false; } @@ -2825,7 +2825,7 @@ private bool isPlanarSurface(double precision, out ISurface simpleSurface, out M if (!isPlane) break; } } - catch (ModOpException mex) + catch (ModOpException) { isPlane = false; } @@ -4850,6 +4850,8 @@ public override void Intersect(ICurve curve, BoundingRect uvExtent, out GeoPoint // List sol = Polynom.Solve(equations, new(double min, double max)[] { (UKnots[0], UKnots[UKnots.Length - 1]), (VKnots[0], VKnots[VKnots.Length - 1]), (0.0, 1.0) }); //} #endif + //Unreachable code + /* if (false) // if (curve is IExplicitPCurve3D) // keine guten Ergebnisse! { @@ -4913,6 +4915,7 @@ public override void Intersect(ICurve curve, BoundingRect uvExtent, out GeoPoint return; } } + */ base.Intersect(curve, uvExtent, out ips, out uvOnFaces, out uOnCurve3Ds); } /// diff --git a/CADability/Parametric.cs b/CADability/Parametric.cs index ebdee19a..fa7c7cbe 100644 --- a/CADability/Parametric.cs +++ b/CADability/Parametric.cs @@ -301,7 +301,7 @@ public bool ModifyRadius(IEnumerable toModify, double newRadius) // } // } //} - return false; + //return false; } private void followCrosswayTangential(Edge edge, ICurve axis, double newRadius) diff --git a/CADability/Plane.cs b/CADability/Plane.cs index 23082b90..1e3f5235 100644 --- a/CADability/Plane.cs +++ b/CADability/Plane.cs @@ -123,7 +123,7 @@ public Plane(GeoPoint Location, GeoVector DirectionX, GeoVector DirectionY) { coordSys = new CoordSys(Location, DirectionX, DirectionY); } - catch (CoordSysException e) + catch (CoordSysException) { throw new PlaneException(PlaneException.tExceptionType.ConstructorFailed); } diff --git a/CADability/PrintToGDI.cs b/CADability/PrintToGDI.cs index 130716e9..54494be6 100644 --- a/CADability/PrintToGDI.cs +++ b/CADability/PrintToGDI.cs @@ -663,7 +663,7 @@ public override void Print(Graphics gr, bool doShading) { ff = new FontFamily(fontName); } - catch (System.ArgumentException ae) + catch (System.ArgumentException) { ff = new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif); } @@ -826,7 +826,6 @@ public override BoundingRect GetExtent() public override bool HitTest(ref BoundingRect rect, bool includeControlPoints) { return true; - return false; } #endregion } @@ -909,7 +908,7 @@ public override int CompareCommonPointZ(BoundingRect rect, IPrintItemImpl other) GeoPoint2D ip = cs.SimpleShapes[0].Outline.SomeInnerPoint; return ZPositionAt(ip).CompareTo((other as PrintTriangle).ZPositionAt(ip)); } - catch (BorderException ex) + catch (BorderException) { return 0; } @@ -1230,7 +1229,7 @@ public override void Print(Graphics gr, bool doShading) br.Dispose(); } } - catch (Exception ex) + catch (Exception) { } @@ -1535,7 +1534,7 @@ public static void PrintSinglePage(Project pr, string nameOfView, bool print2D, pd.PrintPage -= new PrintPageEventHandler(ptg.OnPrintPage); (found as IView).Projection.ShowFaces = sf; } - } catch (Exception ex) + } catch (Exception) { // MessageBox.Show(ex.StackTrace, "Exception in PrintSinglePage"); } @@ -1844,7 +1843,7 @@ public void OnPrintPage(object sender, PrintPageEventArgs e) e.Graphics.DrawImage(bmp, dest, src, GraphicsUnit.Pixel); } } - catch (Exception ex) + catch (Exception) { // MessageBox.Show(ex.StackTrace, "Exception in OnPrintPage"); } @@ -2488,7 +2487,7 @@ void IPaintTo3D.Text(GeoVector lineDirection, GeoVector glyphDirection, GeoPoint { ff = new FontFamily(fontName); } - catch (System.ArgumentException ae) + catch (System.ArgumentException) { ff = new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif); } diff --git a/CADability/Project.cs b/CADability/Project.cs index 3d54bab0..ba2db56d 100644 --- a/CADability/Project.cs +++ b/CADability/Project.cs @@ -1472,7 +1472,7 @@ public static Project ReadFromStream(Stream stream) } return null; } - catch (Exception e) + catch (Exception) { formatter = new BinaryFormatter(); // (null, new StreamingContext(StreamingContextStates.File, finishDeserialization)); formatter.Binder = new CondorSerializationBinder(); @@ -1603,7 +1603,7 @@ internal static Project ReadFromFile(string FileName, bool useProgress) } res.fileName = FileName; } - catch (ProjectOldVersionException ex) + catch (ProjectOldVersionException) { stream.Close(); stream.Dispose(); diff --git a/CADability/Projection.cs b/CADability/Projection.cs index 943de3e8..601c8391 100644 --- a/CADability/Projection.cs +++ b/CADability/Projection.cs @@ -1247,7 +1247,9 @@ public int Height // CalcOpenGlMatrix(); //} return (double[,])openGlMatrix; - + + //Unreachable code + /* // Liefert die OpenGl Projektion unter der Annahme, dass dort Gl.glViewport(0, 0, width, height); // gesetzt wurde. Da diese Projektion die Y-Achse umklappt sehen die UnProject Punkte so // merkwürdig aus. @@ -1400,6 +1402,7 @@ public int Height { return new double[,] { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; } + */ } #region Funktionen im Zusammenhang mit DrawingPlane public Plane DrawingPlane @@ -1549,7 +1552,7 @@ public GeoObjectList MakeArrow(GeoPoint p1, GeoPoint p2, Plane plane, ArrowMode res.Add(Face.MakeFace(new PlaneSurface(arrowPlane), new SimpleShape(Border.MakeCircle(GeoPoint2D.Origin, arrowSize)))); res.Add(Face.MakeFace(new PlaneSurface(arrowPlane), new SimpleShape(Border.MakePolygon(new GeoPoint2D[] { new GeoPoint2D(headx, 0), new GeoPoint2D(headx - arrowSize, arrowSize), new GeoPoint2D(headx - arrowSize, -arrowSize) })))); } - catch (PlaneException _) { } + catch (PlaneException) { } } return res; } diff --git a/CADability/SelectObjectsAction.cs b/CADability/SelectObjectsAction.cs index f6681102..9e515abb 100644 --- a/CADability/SelectObjectsAction.cs +++ b/CADability/SelectObjectsAction.cs @@ -2012,7 +2012,6 @@ public override bool OnCommand(string MenuId) { throw new ApplicationException("not implemented"); } - return true; case "MenuId.Constr.Face.FromSelectedObject": { GeoObjectList select = new GeoObjectList(selectedObjects); diff --git a/CADability/Settings.cs b/CADability/Settings.cs index 95f13217..3ca5d5ce 100644 --- a/CADability/Settings.cs +++ b/CADability/Settings.cs @@ -1021,6 +1021,10 @@ private void SetValue(string Name, object NewValue, bool notify) { ((IntegerProperty)(entries[Name])).SetInt((int)NewValue); } + else if (entries[Name].GetType() == typeof(DoubleProperty) && NewValue is double) + { + ((DoubleProperty)(entries[Name])).SetDouble((double)NewValue); + } else if (entries[Name].GetType() == typeof(ColorSetting)) { ((ColorSetting)(entries[Name])).Color = (Color)NewValue; diff --git a/CADability/Shape.cs b/CADability/Shape.cs index 6008668e..2d25a4cc 100644 --- a/CADability/Shape.cs +++ b/CADability/Shape.cs @@ -165,15 +165,8 @@ public double Area /// /// Returns true, if the Area of this shape is 0.0 /// - public bool Empty - { - get - { - return outline.IsEmpty; - if (Area == 0.0) return true; - return false; - } - } + public bool Empty => outline.IsEmpty; + /// /// Tests whether the provided point is contained in this simple shape. /// diff --git a/CADability/Shell.cs b/CADability/Shell.cs index 137a1b76..f6fa2dda 100644 --- a/CADability/Shell.cs +++ b/CADability/Shell.cs @@ -312,7 +312,7 @@ public double Volume(double precision) double a = cp.Length / 2.0; // area of the triangle corr += a * d * 3 / 4; // 3/4 is a good value for spheres and cylinders } - catch (PlaneException pe) { } + catch (PlaneException) { } } } return sum / 6 + corr; @@ -700,7 +700,7 @@ internal double GetGauge(Face startHere, out HashSet frontSide, out HashSe } } } - catch (Exception ex) { } + catch (Exception) { } } backSide.Clear(); if (bestFace != null) backSide.Add(bestFace); @@ -1428,11 +1428,15 @@ public override BoundingCube GetBoundingCube() } return res; } + private static double findCylinder(GeoPoint[] points, GeoVector[] normals, out GeoPoint axisPoint, out GeoVector axisDir, out double radius) { // points must be a multipe of 3, each triple describes a triangle, for each triangle there is a normal // typically there is one side of the triangles, which is parallel to the axis. So let us try to find parallel triengla edges throw new NotImplementedException(); + + //Unreachable code + /* int nTriple = points.Length / 3; Matrix m = new DenseMatrix(nTriple + 1, 3); Vector b = new DenseVector(nTriple + 1); @@ -1470,7 +1474,9 @@ private static double findCylinder(GeoPoint[] points, GeoVector[] normals, out G return maxerr; } } + */ } + #if DEBUG public #else @@ -1523,10 +1529,10 @@ bool ReconstructSurfaces(double precision) #endif return false; - Set usedFaces = new Set(); - - + //Unreachable code + /* + Set usedFaces = new Set(); List createdFaces = new List(); Dictionary newEdges = new Dictionary(); foreach (Edge edg in Edges) @@ -1546,6 +1552,7 @@ bool ReconstructSurfaces(double precision) } } return false; + */ } private class VectorInOctTree : IOctTreeInsertable diff --git a/CADability/SineCurve2D.cs b/CADability/SineCurve2D.cs index bd8f4c2e..926a88ad 100644 --- a/CADability/SineCurve2D.cs +++ b/CADability/SineCurve2D.cs @@ -120,6 +120,9 @@ public override double GetArea() double a1 = udiff * (Math.Sin(ustart) + Math.Sin(ustart + udiff)) / 2.0; double r1 = triangle + fromUnit.Determinant * (a0 + a1); return r1; + + //Unreachable code + /* // following the debug code to find the correct signs: // I don't understand the signs, they should be wrong in the code above, but turn out to be correct #if DEBUG @@ -129,6 +132,7 @@ public override double GetArea() double r4 = triangle - fromUnit.Determinant * (a0 - a1); System.Diagnostics.Trace.WriteLine("SinArea. " + (udiff > 0).ToString() + ", " + (fromUnit.Determinant > 0).ToString() + ", " + aa.ToString() + ", " + r1.ToString() + ", " + r2.ToString() + ", " + r3.ToString() + ", " + r4.ToString()); #endif + */ } internal override void GetTriangulationPoints(out GeoPoint2D[] interpol, out double[] interparam) { diff --git a/CADability/SphericalSurface.cs b/CADability/SphericalSurface.cs index bd61fe99..168d2296 100644 --- a/CADability/SphericalSurface.cs +++ b/CADability/SphericalSurface.cs @@ -352,6 +352,9 @@ public override ICurve Make3dCurve(ICurve2D curve2d) public override IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double umin, double umax, double vmin, double vmax, double precision) { return GetDualSurfaceCurves(new BoundingRect(umin, vmin, umax, vmax), pl, BoundingRect.EmptyBoundingRect, null, null); // ist dort schon richtig implementiert + + //Unreachable code + /* // hier könnte man die oben beschriebene 2D Schnittkure erzeugen Plane pln = new Plane(toUnit * pl.Location, toUnit * pl.DirectionX, toUnit * pl.DirectionY); bool rotated = false; @@ -447,6 +450,7 @@ public override IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double BSpline2D c2d = new BSpline2D(pnts, 2, false); DualSurfaceCurve dsc = new DualSurfaceCurve(elli, this, c2d, pl, c2dpl); return new IDualSurfaceCurve[] { dsc }; + */ // return base.GetPlaneIntersection(pl, umin, umax, vmin, vmax); } /// diff --git a/CADability/SphericalSurfaceNP.cs b/CADability/SphericalSurfaceNP.cs index cdcb726b..05f3d958 100644 --- a/CADability/SphericalSurfaceNP.cs +++ b/CADability/SphericalSurfaceNP.cs @@ -194,7 +194,7 @@ public override GeoPoint2D PositionOf(GeoPoint p) { return Plane.XYPlane.Intersect(beam); // intersection of XY plane } - catch (PlaneException pe) + catch (PlaneException) { return GeoPoint2D.Invalid; } diff --git a/CADability/Surface.cs b/CADability/Surface.cs index 3a6a76c8..640ff3c5 100644 --- a/CADability/Surface.cs +++ b/CADability/Surface.cs @@ -3080,8 +3080,13 @@ public virtual ICurve2D GetProjectedCurve(ICurve curve, double precision) } return new ProjectedCurve(curve, this, true, restricted, precision); } - if (!usedArea.IsInfinite) return new ProjectedCurve(curve, this, true, BoundingRect.EmptyBoundingRect, precision); - else return new ProjectedCurve(curve, this, true, usedArea, precision); + if (!usedArea.IsInfinite) + return new ProjectedCurve(curve, this, true, BoundingRect.EmptyBoundingRect, precision); + else + return new ProjectedCurve(curve, this, true, usedArea, precision); + + //Unreachable code + /* int n = 16; bool ok = false; BSpline2D b2d = null; @@ -3227,7 +3232,7 @@ public virtual ICurve2D GetProjectedCurve(ICurve curve, double precision) { b2d = new BSpline2D(through, 3, Precision.IsEqual(through[0], through[through.Length - 1])); // curve.IsClosed); } - catch (NurbsException ne) + catch (NurbsException) { List cleanThroughPoints = new List(); cleanThroughPoints.Add(through[0]); @@ -3278,6 +3283,7 @@ public virtual ICurve2D GetProjectedCurve(ICurve curve, double precision) if (ok || n > 1024) break; } return b2d; + */ } /// /// Implements @@ -4636,7 +4642,9 @@ public virtual double MaxDist(GeoPoint2D sp, GeoPoint2D ep, out GeoPoint2D mp) } } return max; - + + //Unreachable code + /* BoxedSurfaceEx.RawPointNormalAt(sp, out sp3d, out sn); // Punkt und Normale auf die Fläche am Startpunkt BoxedSurfaceEx.RawPointNormalAt(ep, out ep3d, out en); // Punkt und Normale auf die Fläche am Startpunkt d3d = ep3d - sp3d; // die Richtung der 3d-Linie @@ -4726,6 +4734,7 @@ public virtual double MaxDist(GeoPoint2D sp, GeoPoint2D ep, out GeoPoint2D mp) //catch (PolylineException) { } #endif return md; + */ } private GeoPoint2D[] newtonFindTangent(GeoVector dir3d, GeoPoint2D sp, GeoPoint2D ep, GeoVector sn, GeoVector en, double precision) @@ -5098,6 +5107,8 @@ public BSpline Refine(GeoPoint[] geopoints, int degree, bool closed, PlaneSurfac bsp.ThroughPoints(p.ToArray(), degree, closed); return bsp; //Debug + //Unreachable code + /* int maxThroughPoints = 200; int next_index = 1; int initp = p.Count; @@ -5174,6 +5185,7 @@ public BSpline Refine(GeoPoint[] geopoints, int degree, bool closed, PlaneSurfac return bspr; } } + */ } #region IOctTreeInsertable Members @@ -9165,7 +9177,7 @@ private void AddCube(BoundingRect uvPatch) dbgl.Add(pl); } } - catch (PolylineException ex) + catch (PolylineException) { } } dbgl.Add(Line.TwoPoints(cube.pll, cube.pll + 10 * cube.nll)); @@ -11047,6 +11059,9 @@ public virtual IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double res[i] = cvs[i] as IDualSurfaceCurve; } return res; + + //Unreachable code + /* // alter Text: ComputeIntersectionCurve cic = new ComputeIntersectionCurve(this, pl, umin, umax, vmin, vmax); #if DEBUG @@ -11054,6 +11069,7 @@ public virtual IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double // System.Diagnostics.Trace.WriteLine("Anzahl der Boxes: " + allCubes.Length.ToString()); #endif return cic.GetIntersectionCurves(new BoundingRect(umin, vmin, umax, vmax)); + */ } public virtual IDualSurfaceCurve[] GetSurfaceIntersection(ISurface surface, double umin, double umax, double vmin, double vmax, double precision) { diff --git a/CADability/SurfaceOfRevolution.cs b/CADability/SurfaceOfRevolution.cs index b566c6ea..817e1293 100644 --- a/CADability/SurfaceOfRevolution.cs +++ b/CADability/SurfaceOfRevolution.cs @@ -970,6 +970,9 @@ public override GeoPoint2D[] GetLineIntersection(GeoPoint startPoint, GeoVector #endif return res; + + //Unreachable code + /* // return base.GetLineIntersection(startPoint, direction); // bleibt auch hängen // Richards Code bleibt manchmal hängen GeoPoint sp = fromSurface * startPoint; @@ -1031,6 +1034,7 @@ public override GeoPoint2D[] GetLineIntersection(GeoPoint startPoint, GeoVector hp[i] = hps[i].p; } return hp; + */ } } /// diff --git a/CADability/TestsWithMathNet.cs b/CADability/TestsWithMathNet.cs index b0779ed4..069b036d 100644 --- a/CADability/TestsWithMathNet.cs +++ b/CADability/TestsWithMathNet.cs @@ -138,7 +138,7 @@ public static bool CurveIntersection2D(ICurve2D curve1, double spar1, double epa // mres.FunctionInfoAtMinimum.Value; return true; } - catch (Exception e) + catch (Exception) { return false; } @@ -178,7 +178,7 @@ public static bool CurveSurfaceIntersection(ISurface surface, ICurve curve, ref ip = lastIp; return true; } - catch (Exception e) + catch (Exception) { ip = GeoPoint.Origin; return false; @@ -622,7 +622,7 @@ public static bool PlaneFit(IEnumerable points, out GeoPoint location, return true; } } - catch (Exception ex) + catch (Exception) { } normal = GeoVector.NullVector; diff --git a/CADability/ToolsRoundMultiple.cs b/CADability/ToolsRoundMultiple.cs index 740b9dd2..fc7ea3d9 100644 --- a/CADability/ToolsRoundMultiple.cs +++ b/CADability/ToolsRoundMultiple.cs @@ -188,7 +188,7 @@ private bool showRound() } } } - catch (ApplicationException e) + catch (ApplicationException) { return false; } diff --git a/CADability/ToroidalSurface.cs b/CADability/ToroidalSurface.cs index 12ad2f01..61de9668 100644 --- a/CADability/ToroidalSurface.cs +++ b/CADability/ToroidalSurface.cs @@ -457,7 +457,7 @@ private GeoPoint[] GetLineIntersection3D(GeoPoint startPoint, GeoVector directio } } } - catch (ApplicationException ex) { } + catch (ApplicationException) { } return sol.ToArray(); } /// @@ -480,7 +480,7 @@ public override IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double if (d - (1 + minorRadius) >= -Precision.eps) { // System.Diagnostics.Trace.WriteLine("Das Ebene trifft nicht den Torus oder nur im einem Punkt"); - return new IDualSurfaceCurve[0]; + return Array.Empty(); } if (d <= Precision.eps) #region Zwei Kreis @@ -823,120 +823,123 @@ public override IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double } else { - return new IDualSurfaceCurve[0]; + return Array.Empty(); } - GeoPoint onz = pln.Intersect(GeoPoint.Origin, GeoVector.ZAxis); - double d = onz.z; - if (Math.Abs(d) - Math.Abs(minorRadius) > Precision.eps) - #region nichts - { - return new IDualSurfaceCurve[0]; - } - #endregion - if (Math.Abs(d) - Math.Abs(minorRadius) > -Precision.eps) - #region ein Kreis - { - // System.Diagnostics.Trace.WriteLine("ein Kreis "); - GeoVector majax = new GeoVector(1, 0, 0); - GeoVector minax = new GeoVector(0, 1, 0); - GeoPoint cnt = new GeoPoint(0, 0, d); - GeoPoint center = toTorus * cnt; - GeoVector majaxis = toTorus * majax; - GeoVector minaxis = toTorus * minax; - //im Weltsystem - Ellipse elli = Ellipse.Construct(); - elli.SetEllipseCenterAxis(center, majaxis, minaxis); - GeoPoint2D centerOnPl = pl.PositionOf(center); - //Auf der Ebene - GeoPoint2D p1OnPl = pl.PositionOf(center + majaxis); - GeoPoint2D p2OnPl = pl.PositionOf(center - minaxis); - Ellipse2D elli2d = Geometry.Ellipse2P2T(p1OnPl, p2OnPl, p2OnPl - centerOnPl, p1OnPl - centerOnPl); - ICurve2D c2dpl = elli2d.Trim(0.0, 1.0); - //Im (u,v) System - GeoPoint2D[] pnts = new GeoPoint2D[50]; - double f = Math.PI / 2; - if (d < 0) - f = 3 * Math.PI / 2; - for (int i = 0; i < pnts.Length; i++) - { - pnts[i].x = i * 2 * Math.PI / (pnts.Length - 1); - pnts[i].y = f; - } - BSpline2D c2d = new BSpline2D(pnts, 2, false); - DualSurfaceCurve dsc = new DualSurfaceCurve(elli, this, c2d, pl, c2dpl); - return new IDualSurfaceCurve[] { dsc }; - } - #endregion - else - #region zwei Kreis - { - // System.Diagnostics.Trace.WriteLine("zwei Kreis "); - double f = Math.Sqrt(minorRadius * minorRadius - d * d); - double rmax = 1 + f; - double rmin = 1 - f; - double amax = Math.Atan2(Math.Abs(d), f); - //Erste Kreis - GeoVector majax = new GeoVector(rmax, 0, 0); - GeoVector minax = new GeoVector(0, rmax, 0); - GeoPoint cnt = new GeoPoint(0, 0, d); - GeoPoint center = toTorus * cnt; - GeoVector majaxis = toTorus * majax; - GeoVector minaxis = toTorus * minax; - //im Weltsystem - Ellipse elli1 = Ellipse.Construct(); - elli1.SetEllipseCenterAxis(center, majaxis, minaxis); - elli1.StartParameter = 0.0; // wird mit obigem nicht gesetzt - elli1.SweepParameter = 2.0 * Math.PI; - GeoPoint2D centerOnPl = pl.PositionOf(center); - //Auf der Ebene - GeoPoint2D p1OnPl = pl.PositionOf(center + majaxis); - GeoPoint2D p2OnPl = pl.PositionOf(center - minaxis); - Ellipse2D elli2d = Geometry.Ellipse2P2T(p1OnPl, p2OnPl, p2OnPl - centerOnPl, p1OnPl - centerOnPl); - ICurve2D c2dpl1 = elli2d.Trim(0.0, 1.0); - //Im (u,v) System - GeoPoint2D[] pnts = new GeoPoint2D[50]; - f = amax; - if (d < 0) - f = 2 * Math.PI - amax; - for (int i = 0; i < pnts.Length; i++) - { - pnts[i].x = i * 2 * Math.PI / (pnts.Length - 1); - pnts[i].y = f; - } - BSpline2D c2d1 = new BSpline2D(pnts, 2, false); - DualSurfaceCurve dsc1 = new DualSurfaceCurve(elli1, this, c2d1, pl, c2dpl1); - //zeite Kreis - majax = new GeoVector(rmin, 0, 0); - minax = new GeoVector(0, rmin, 0); - majaxis = toTorus * majax; - minaxis = toTorus * minax; - //im Weltsystem - Ellipse elli2 = Ellipse.Construct(); - elli2.SetEllipseCenterAxis(center, majaxis, minaxis); - elli2.StartParameter = 0.0; // wird mit obigem nicht gesetzt - elli2.SweepParameter = Math.PI * 2.0; - //GeoPoint2D centerOnPl = pl.PositionOf(center); - //Auf der Ebene - p1OnPl = pl.PositionOf(center + majaxis); - p2OnPl = pl.PositionOf(center - minaxis); - elli2d = Geometry.Ellipse2P2T(p1OnPl, p2OnPl, p2OnPl - centerOnPl, p1OnPl - centerOnPl); - ICurve2D c2dpl2 = elli2d.Trim(0.0, 1.0); - //Im (u,v) System - f = Math.PI - amax; - if (d < 0) - f = Math.PI + amax; - for (int i = 0; i < pnts.Length; i++) - { - pnts[i].x = i * 2 * Math.PI / (pnts.Length - 1); - pnts[i].y = f; - } - BSpline2D c2d2 = new BSpline2D(pnts, 2, false); - DualSurfaceCurve dsc2 = new DualSurfaceCurve(elli2, this, c2d2, pl, c2dpl2); - return new IDualSurfaceCurve[] { dsc1, dsc2 }; - // return base.GetPlaneIntersection(pl, umin, umax, vmin, vmax); - } - #endregion + //Unreachable code + /* + GeoPoint onz = pln.Intersect(GeoPoint.Origin, GeoVector.ZAxis); + double d = onz.z; + if (Math.Abs(d) - Math.Abs(minorRadius) > Precision.eps) + #region nichts + { + return new IDualSurfaceCurve[0]; + } + #endregion + if (Math.Abs(d) - Math.Abs(minorRadius) > -Precision.eps) + #region ein Kreis + { + // System.Diagnostics.Trace.WriteLine("ein Kreis "); + GeoVector majax = new GeoVector(1, 0, 0); + GeoVector minax = new GeoVector(0, 1, 0); + GeoPoint cnt = new GeoPoint(0, 0, d); + GeoPoint center = toTorus * cnt; + GeoVector majaxis = toTorus * majax; + GeoVector minaxis = toTorus * minax; + //im Weltsystem + Ellipse elli = Ellipse.Construct(); + elli.SetEllipseCenterAxis(center, majaxis, minaxis); + GeoPoint2D centerOnPl = pl.PositionOf(center); + //Auf der Ebene + GeoPoint2D p1OnPl = pl.PositionOf(center + majaxis); + GeoPoint2D p2OnPl = pl.PositionOf(center - minaxis); + Ellipse2D elli2d = Geometry.Ellipse2P2T(p1OnPl, p2OnPl, p2OnPl - centerOnPl, p1OnPl - centerOnPl); + ICurve2D c2dpl = elli2d.Trim(0.0, 1.0); + //Im (u,v) System + GeoPoint2D[] pnts = new GeoPoint2D[50]; + double f = Math.PI / 2; + if (d < 0) + f = 3 * Math.PI / 2; + for (int i = 0; i < pnts.Length; i++) + { + pnts[i].x = i * 2 * Math.PI / (pnts.Length - 1); + pnts[i].y = f; + } + BSpline2D c2d = new BSpline2D(pnts, 2, false); + DualSurfaceCurve dsc = new DualSurfaceCurve(elli, this, c2d, pl, c2dpl); + return new IDualSurfaceCurve[] { dsc }; + } + #endregion + else + #region zwei Kreis + { + // System.Diagnostics.Trace.WriteLine("zwei Kreis "); + double f = Math.Sqrt(minorRadius * minorRadius - d * d); + double rmax = 1 + f; + double rmin = 1 - f; + double amax = Math.Atan2(Math.Abs(d), f); + //Erste Kreis + GeoVector majax = new GeoVector(rmax, 0, 0); + GeoVector minax = new GeoVector(0, rmax, 0); + GeoPoint cnt = new GeoPoint(0, 0, d); + GeoPoint center = toTorus * cnt; + GeoVector majaxis = toTorus * majax; + GeoVector minaxis = toTorus * minax; + //im Weltsystem + Ellipse elli1 = Ellipse.Construct(); + elli1.SetEllipseCenterAxis(center, majaxis, minaxis); + elli1.StartParameter = 0.0; // wird mit obigem nicht gesetzt + elli1.SweepParameter = 2.0 * Math.PI; + GeoPoint2D centerOnPl = pl.PositionOf(center); + //Auf der Ebene + GeoPoint2D p1OnPl = pl.PositionOf(center + majaxis); + GeoPoint2D p2OnPl = pl.PositionOf(center - minaxis); + Ellipse2D elli2d = Geometry.Ellipse2P2T(p1OnPl, p2OnPl, p2OnPl - centerOnPl, p1OnPl - centerOnPl); + ICurve2D c2dpl1 = elli2d.Trim(0.0, 1.0); + //Im (u,v) System + GeoPoint2D[] pnts = new GeoPoint2D[50]; + f = amax; + if (d < 0) + f = 2 * Math.PI - amax; + for (int i = 0; i < pnts.Length; i++) + { + pnts[i].x = i * 2 * Math.PI / (pnts.Length - 1); + pnts[i].y = f; + } + BSpline2D c2d1 = new BSpline2D(pnts, 2, false); + DualSurfaceCurve dsc1 = new DualSurfaceCurve(elli1, this, c2d1, pl, c2dpl1); + //zeite Kreis + majax = new GeoVector(rmin, 0, 0); + minax = new GeoVector(0, rmin, 0); + majaxis = toTorus * majax; + minaxis = toTorus * minax; + //im Weltsystem + Ellipse elli2 = Ellipse.Construct(); + elli2.SetEllipseCenterAxis(center, majaxis, minaxis); + elli2.StartParameter = 0.0; // wird mit obigem nicht gesetzt + elli2.SweepParameter = Math.PI * 2.0; + //GeoPoint2D centerOnPl = pl.PositionOf(center); + //Auf der Ebene + p1OnPl = pl.PositionOf(center + majaxis); + p2OnPl = pl.PositionOf(center - minaxis); + elli2d = Geometry.Ellipse2P2T(p1OnPl, p2OnPl, p2OnPl - centerOnPl, p1OnPl - centerOnPl); + ICurve2D c2dpl2 = elli2d.Trim(0.0, 1.0); + //Im (u,v) System + f = Math.PI - amax; + if (d < 0) + f = Math.PI + amax; + for (int i = 0; i < pnts.Length; i++) + { + pnts[i].x = i * 2 * Math.PI / (pnts.Length - 1); + pnts[i].y = f; + } + BSpline2D c2d2 = new BSpline2D(pnts, 2, false); + DualSurfaceCurve dsc2 = new DualSurfaceCurve(elli2, this, c2d2, pl, c2dpl2); + return new IDualSurfaceCurve[] { dsc1, dsc2 }; + // return base.GetPlaneIntersection(pl, umin, umax, vmin, vmax); + } + #endregion + */ } #endregion @@ -2482,9 +2485,9 @@ public override IDualSurfaceCurve[] GetDualSurfaceCurves(BoundingRect thisBounds } } } - if (other is CylindricalSurface cylindricalSurface) + if (other is CylindricalSurface cylindricalSurface) { // we need tangential points to split the result there - return cylindricalSurface.GetDualSurfaceCurves(otherBounds,this,thisBounds,seeds,extremePositions); + return cylindricalSurface.GetDualSurfaceCurves(otherBounds, this, thisBounds, seeds, extremePositions); } return base.GetDualSurfaceCurves(thisBounds, other, otherBounds, seeds, extremePositions); }