From 8155a370afe30bdf98721fc9d4889424992a7830 Mon Sep 17 00:00:00 2001 From: ChrisClems Date: Thu, 5 Dec 2024 07:30:29 -0800 Subject: [PATCH 01/12] Changed spline approximation precision setting source from Project.Frame.GetDoubleSetting() to Settings.GlobalSettings.GetDoubleValue() to accomodate headless import for DXF files with splines. Added required handler to Settings.cs SetValue() method to change double values in GlobalSettings. --- CADability/ImportDxf.cs | 2 +- CADability/Settings.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CADability/ImportDxf.cs b/CADability/ImportDxf.cs index c623df28..2ec597d3 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; 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; From 9d76510804473cf5ce35549535090eec33865941 Mon Sep 17 00:00:00 2001 From: ChrisClems Date: Thu, 5 Dec 2024 15:10:22 -0800 Subject: [PATCH 02/12] Add ExportPathWithoutBlock method and accompanying GlobalSetting check to enable it. --- CADability/ExportDxf.cs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) 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); From 26c3176139dd06d59137e33e21f27984fd418a31 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 6 Dec 2024 14:05:48 -0800 Subject: [PATCH 03/12] Add IEquatable implementation to BoundingRect Implement the IEquatable interface for the BoundingRect struct to improve equality checks. Resolves CS0660 and CS0661 warning from compiler. --- CADability/BoundingRect.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) 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; + } + } } } From a6ca75f3dc2b50f7eead78d96e6d8f616ef8bfa2 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 6 Dec 2024 17:07:25 -0800 Subject: [PATCH 04/12] Remove unused maxInterpolError field from BSpline.cs. Fixes compiler warning CS0414. --- CADability/BSpline.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/CADability/BSpline.cs b/CADability/BSpline.cs index c6e45e38..08ad09d3 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; From aa06859cc79d1ad41e919bebfd091fb3c2bfd899 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 6 Dec 2024 17:11:20 -0800 Subject: [PATCH 05/12] Remove unused syncCallBack variable. Fixes compiler warning CS0414 --- CADability/ConstructAction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CADability/ConstructAction.cs b/CADability/ConstructAction.cs index ee4d2166..545e36e5 100644 --- a/CADability/ConstructAction.cs +++ b/CADability/ConstructAction.cs @@ -7137,7 +7137,7 @@ protected void Finish() * in der Callback Methode ausführen. Dann kann man immer noch Escape drücken, wenns zu lange dauart (Vervielfältigen, Schraffur) */ Thread backgroundTask; - bool finishedBackgroundTask, syncCallBack; + bool finishedBackgroundTask; Delegate CallbackOnDone; private void StartThread(object pars) { // das läuft im background thread From 5e11b82eeb7c306be96527efbff3e56eb35257ed Mon Sep 17 00:00:00 2001 From: Chris Clemons Date: Sat, 7 Dec 2024 11:20:05 -0800 Subject: [PATCH 06/12] Revert "Remove unused syncCallBack variable. Fixes compiler warning CS0414" This reverts commit aa06859cc79d1ad41e919bebfd091fb3c2bfd899. --- CADability/ConstructAction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CADability/ConstructAction.cs b/CADability/ConstructAction.cs index 545e36e5..ee4d2166 100644 --- a/CADability/ConstructAction.cs +++ b/CADability/ConstructAction.cs @@ -7137,7 +7137,7 @@ protected void Finish() * in der Callback Methode ausführen. Dann kann man immer noch Escape drücken, wenns zu lange dauart (Vervielfältigen, Schraffur) */ Thread backgroundTask; - bool finishedBackgroundTask; + bool finishedBackgroundTask, syncCallBack; Delegate CallbackOnDone; private void StartThread(object pars) { // das läuft im background thread From 8e3e8f2f74b617f1bce689fd216c314bbb842f5f Mon Sep 17 00:00:00 2001 From: Chris Clemons Date: Sat, 7 Dec 2024 11:49:15 -0800 Subject: [PATCH 07/12] Remove unused variables 'spu' and 'epu'. Fixes two CS0414 compiler warnings. --- CADability/DualSurfaceCurve.cs | 5 ----- 1 file changed, 5 deletions(-) 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) From 87d2cb65d9e3720275e3489deed7eb6d2959d545 Mon Sep 17 00:00:00 2001 From: Chris Clemons Date: Sat, 7 Dec 2024 13:06:16 -0800 Subject: [PATCH 08/12] Removed unused exception variable assignments in several try/catch blocks. Resolves several compiler warnings. --- CADability/BorderQuadTree.cs | 2 +- CADability/Face.cs | 4 ++-- CADability/NurbsSurface.cs | 4 ++-- CADability/Shell.cs | 4 ++-- CADability/SphericalSurfaceNP.cs | 2 +- CADability/Surface.cs | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) 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/Face.cs b/CADability/Face.cs index 80edc21c..ab072f62 100644 --- a/CADability/Face.cs +++ b/CADability/Face.cs @@ -6305,7 +6305,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 +6606,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(); diff --git a/CADability/NurbsSurface.cs b/CADability/NurbsSurface.cs index 15c1db61..e9e4b554 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; } diff --git a/CADability/Shell.cs b/CADability/Shell.cs index 137a1b76..d8df4bf4 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); 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..b3374d4c 100644 --- a/CADability/Surface.cs +++ b/CADability/Surface.cs @@ -3227,7 +3227,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]); @@ -9165,7 +9165,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)); From b73455194a92b5b366c77286a21fc6d64c0cd2d0 Mon Sep 17 00:00:00 2001 From: Chris Clemons Date: Sat, 7 Dec 2024 13:06:16 -0800 Subject: [PATCH 09/12] Removed unused exception variable assignments in several try/catch blocks. Resolves several compiler warnings. --- CADability/BSpline2D.cs | 2 +- CADability/Block.cs | 2 +- CADability/BorderOperation.cs | 2 +- CADability/ColorDef.cs | 2 +- CADability/ColorSetting.cs | 2 +- CADability/ConstrHatchInside.cs | 4 ++-- CADability/CoordSys.cs | 2 +- CADability/Edge.cs | 2 +- CADability/Ellipse2D.cs | 2 +- CADability/ExportToWebGl.cs | 2 +- CADability/Filter.cs | 4 ++-- CADability/GeneralCurve2D.cs | 2 +- CADability/LayerList.cs | 2 +- CADability/LayoutView.cs | 4 ++-- CADability/MultiGeoPointProperty.cs | 2 +- CADability/Plane.cs | 2 +- CADability/PrintToGDI.cs | 12 ++++++------ CADability/Project.cs | 4 ++-- CADability/Projection.cs | 2 +- CADability/TestsWithMathNet.cs | 6 +++--- CADability/ToolsRoundMultiple.cs | 2 +- CADability/ToroidalSurface.cs | 2 +- 22 files changed, 33 insertions(+), 33 deletions(-) diff --git a/CADability/BSpline2D.cs b/CADability/BSpline2D.cs index faa928cd..b1d877ce 100644 --- a/CADability/BSpline2D.cs +++ b/CADability/BSpline2D.cs @@ -606,7 +606,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/BorderOperation.cs b/CADability/BorderOperation.cs index de3b4cb5..f32c50a5 100644 --- a/CADability/BorderOperation.cs +++ b/CADability/BorderOperation.cs @@ -317,7 +317,7 @@ private void GenerateClusterSet() GeoVector2D dir2 = border2.DirectionAt(isp[j].par2).Normalized; dirz = dir1.x * dir2.y - dir1.y * dir2.x; } - catch (GeoVectorException e) + catch (GeoVectorException) { dirz = 0.0; } 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/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/Edge.cs b/CADability/Edge.cs index 190a4587..a035e699 100644 --- a/CADability/Edge.cs +++ b/CADability/Edge.cs @@ -2713,7 +2713,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/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/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/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/GeneralCurve2D.cs b/CADability/GeneralCurve2D.cs index 8e1df221..d4e33c39 100644 --- a/CADability/GeneralCurve2D.cs +++ b/CADability/GeneralCurve2D.cs @@ -1627,7 +1627,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); } 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/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/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..8f414804 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); } @@ -909,7 +909,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 +1230,7 @@ public override void Print(Graphics gr, bool doShading) br.Dispose(); } } - catch (Exception ex) + catch (Exception) { } @@ -1535,7 +1535,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 +1844,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 +2488,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 d57f8a82..0e23ca3f 100644 --- a/CADability/Projection.cs +++ b/CADability/Projection.cs @@ -1548,7 +1548,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/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..99cb140e 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(); } /// From b4675343f56afdcf99d595b039723d597d558ba9 Mon Sep 17 00:00:00 2001 From: ChrisClems Date: Tue, 10 Dec 2024 12:42:59 -0800 Subject: [PATCH 10/12] Translated comments in CurveGraph.cs to English via OpenAI. --- CADability/CurveGraph.cs | 269 +++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 136 deletions(-) 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; } } From d1998f6c59944a63f00ddc808df71b006f466fe0 Mon Sep 17 00:00:00 2001 From: Michel Date: Wed, 11 Dec 2024 13:37:18 +0100 Subject: [PATCH 11/12] Comment unreachable code --- CADability/BSpline.cs | 5 +- CADability/BSpline2D.cs | 26 ++- CADability/Border.cs | 2 + CADability/BorderOperation.cs | 7 +- CADability/ConicalSurface.cs | 5 +- CADability/CopyMatrixObjects.cs | 16 +- CADability/Curves2D.cs | 8 - CADability/CylindricalSurface.cs | 21 +- CADability/Edge.cs | 4 +- CADability/Ellipse.cs | 93 ++++---- CADability/EllipseArc2D.cs | 36 ++-- CADability/Face.cs | 17 +- CADability/GeneralCurve.cs | 41 ++-- CADability/GeneralCurve2D.cs | 6 + CADability/GeneralSweptCurve.cs | 3 + CADability/ImportDxf.cs | 6 +- CADability/ImportStep.cs | 5 +- CADability/InterpolatedDualSurfaceCurve.cs | 18 +- CADability/Line2D.cs | 7 +- CADability/Make3D.cs | 9 +- CADability/NDimTree.cs | 3 + CADability/NurbsSurface.cs | 3 + CADability/Parametric.cs | 2 +- CADability/PrintToGDI.cs | 1 - CADability/Projection.cs | 5 +- CADability/SelectObjectsAction.cs | 1 - CADability/Shape.cs | 11 +- CADability/Shell.cs | 13 +- CADability/SineCurve2D.cs | 4 + CADability/SphericalSurface.cs | 4 + CADability/Surface.cs | 22 +- CADability/SurfaceOfRevolution.cs | 4 + CADability/ToroidalSurface.cs | 233 +++++++++++---------- 33 files changed, 360 insertions(+), 281 deletions(-) diff --git a/CADability/BSpline.cs b/CADability/BSpline.cs index 08ad09d3..193b4018 100644 --- a/CADability/BSpline.cs +++ b/CADability/BSpline.cs @@ -3082,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); @@ -3092,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 b1d877ce..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(); } 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 f32c50a5..64dd076e 100644 --- a/CADability/BorderOperation.cs +++ b/CADability/BorderOperation.cs @@ -804,9 +804,10 @@ 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; + if (found) + return new CompoundShape(); + + return new CompoundShape(new SimpleShape(border1)); } throw new BorderException("unexpected error in BorderOperation.Intersection!", BorderException.BorderExceptionType.InternalError); } 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/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/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/Edge.cs b/CADability/Edge.cs index a035e699..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 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/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/Face.cs b/CADability/Face.cs index ab072f62..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 @@ -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/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 d4e33c39..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; @@ -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 2ec597d3..29e24e9c 100644 --- a/CADability/ImportDxf.cs +++ b/CADability/ImportDxf.cs @@ -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/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/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 e9e4b554..9b611ca9 100644 --- a/CADability/NurbsSurface.cs +++ b/CADability/NurbsSurface.cs @@ -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/PrintToGDI.cs b/CADability/PrintToGDI.cs index 8f414804..54494be6 100644 --- a/CADability/PrintToGDI.cs +++ b/CADability/PrintToGDI.cs @@ -826,7 +826,6 @@ public override BoundingRect GetExtent() public override bool HitTest(ref BoundingRect rect, bool includeControlPoints) { return true; - return false; } #endregion } diff --git a/CADability/Projection.cs b/CADability/Projection.cs index 0e23ca3f..5997b42e 100644 --- a/CADability/Projection.cs +++ b/CADability/Projection.cs @@ -1246,7 +1246,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. @@ -1399,6 +1401,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 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/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 d8df4bf4..f6fa2dda 100644 --- a/CADability/Shell.cs +++ b/CADability/Shell.cs @@ -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/Surface.cs b/CADability/Surface.cs index b3374d4c..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; @@ -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 @@ -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/ToroidalSurface.cs b/CADability/ToroidalSurface.cs index 99cb140e..61de9668 100644 --- a/CADability/ToroidalSurface.cs +++ b/CADability/ToroidalSurface.cs @@ -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); } From 6c366b714f92d0227237e3170eded8d20f887274 Mon Sep 17 00:00:00 2001 From: ChrisClems Date: Wed, 11 Dec 2024 07:29:38 -0800 Subject: [PATCH 12/12] Translate comments in BorderOperation.cs to English. --- CADability/BorderOperation.cs | 270 ++++++++++++++++++---------------- 1 file changed, 141 insertions(+), 129 deletions(-) diff --git a/CADability/BorderOperation.cs b/CADability/BorderOperation.cs index f32c50a5..21d3bd40 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,7 +813,7 @@ public CompoundShape Difference() } return new CompoundShape(ss); } - // sie überschneiden sich, aber der Inhalt ist leer, also border1 liefern + // they intersect, but the content is empty, so return border1 if (found) return new CompoundShape(); else return new CompoundShape(new SimpleShape(border1)); break; @@ -814,23 +824,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 +867,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 +884,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 +912,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 +923,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 +932,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 +945,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 +1054,7 @@ internal void MakeUnused() } } - // als key für Dictionary + // as a key for Dictionary internal class BorderPair : IComparable { int id1, id2;