From f36f9a775f8d5328204f88691cf3f32c796a3000 Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Tue, 3 Oct 2023 17:42:00 +0300 Subject: [PATCH 1/6] CreateVerticesAndCurveIndices reuse indices at the ends of segments --- Elements/src/Geometry/IndexedPolycurve.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Elements/src/Geometry/IndexedPolycurve.cs b/Elements/src/Geometry/IndexedPolycurve.cs index 35cfd4e63..16f5d8f8f 100644 --- a/Elements/src/Geometry/IndexedPolycurve.cs +++ b/Elements/src/Geometry/IndexedPolycurve.cs @@ -205,7 +205,7 @@ private static (List>, List) CreateVerticesAndCurveIndices(I vertices.Add(curve.Start); last = curve.End; curveIndices.Add(new[] { index, index + 1 }); - index += 2; + index += 1; } else if (curve is Arc) { @@ -213,7 +213,7 @@ private static (List>, List) CreateVerticesAndCurveIndices(I vertices.Add(curve.Mid()); last = curve.End; curveIndices.Add(new[] { index, index + 1, index + 2 }); - index += 3; + index += 2; } else { From 595d60527c6b16bb8b1a9e320d4103c9c0cb85b0 Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Tue, 3 Oct 2023 17:45:04 +0300 Subject: [PATCH 2/6] Fix IndexedPolycurve.TransformAt TransformAt used incorrect calculation `d = this.Length() * u` that is wrong when parameter is no longer in [0,1] domain. --- Elements/src/Geometry/Polyline.cs | 34 +++++++++---------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/Elements/src/Geometry/Polyline.cs b/Elements/src/Geometry/Polyline.cs index b33e77545..1b1e6968e 100644 --- a/Elements/src/Geometry/Polyline.cs +++ b/Elements/src/Geometry/Polyline.cs @@ -96,9 +96,7 @@ public override Transform TransformAt(double u) throw new Exception($"The parameter {u} is not on the trimmed portion of the basis curve. The parameter must be between {Domain.Min} and {Domain.Max}."); } - var segmentIndex = 0; - var o = PointAtInternal(u, out segmentIndex); - Vector3 x = Vector3.XAxis; // Vector3: Convert to XAxis + var o = PointAtInternal(u, out var segmentIndex); // Check if the provided parameter is equal // to one of the vertices. @@ -119,7 +117,7 @@ public override Transform TransformAt(double u) { var idx = this.Vertices.IndexOf(a); - if (idx == 0 || idx == this.Vertices.Count - 1) + if (!(this is Polygon) && (idx == 0 || idx == this.Vertices.Count - 1)) { return CreateOrthogonalTransform(idx, a, normals[idx]); } @@ -129,26 +127,14 @@ public override Transform TransformAt(double u) } } - var d = this.Length() * u; - var totalLength = 0.0; - var segments = Segments(); - var normal = new Vector3(); - for (var i = 0; i < segments.Length; i++) - { - var s = segments[i]; - var currLength = s.Length(); - if (totalLength <= d && totalLength + currLength >= d) - { - var parameterOnSegment = d - totalLength; - o = s.PointAt(parameterOnSegment); - var previousNormal = normals[i]; - var nextNormal = normals[(i + 1) % this.Vertices.Count]; - normal = ((nextNormal - previousNormal) * parameterOnSegment + previousNormal).Unitized(); - x = s.Direction().Cross(normal); - break; - } - totalLength += currLength; - } + var nextIndex = (segmentIndex + 1) % this.Vertices.Count; + var segment = new Line(Vertices[segmentIndex], Vertices[nextIndex]); + var parameterOnSegment = u - segmentIndex; + var previousNormal = normals[segmentIndex]; + var nextNormal = normals[nextIndex]; + var normal = ((nextNormal - previousNormal) * parameterOnSegment + previousNormal).Unitized(); + var x = segment.Direction().Cross(normal); + return new Transform(o, x, normal, x.Cross(normal)); } From dfafd0247cdbcf4828844d0bad4e50238f057cac Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Wed, 4 Oct 2023 13:17:27 +0300 Subject: [PATCH 3/6] Add IndexedPolycurveTests.PreservesIndicesTransformed --- Elements/src/Geometry/Polyline.cs | 2 +- Elements/test/IndexedPolyCurveTests.cs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Elements/src/Geometry/Polyline.cs b/Elements/src/Geometry/Polyline.cs index 1b1e6968e..d61ddc66c 100644 --- a/Elements/src/Geometry/Polyline.cs +++ b/Elements/src/Geometry/Polyline.cs @@ -88,7 +88,7 @@ public virtual Line[] Segments() /// Get the transform at the specified parameter along the polyline. /// /// The parameter on the polygon between 0.0 and length. - /// A transform with its Z axis aligned trangent to the polyline. + /// A transform with its Z axis aligned tangent to the polyline. public override Transform TransformAt(double u) { if (!Domain.Includes(u, true)) diff --git a/Elements/test/IndexedPolyCurveTests.cs b/Elements/test/IndexedPolyCurveTests.cs index f45ab29a9..619cf20d8 100644 --- a/Elements/test/IndexedPolyCurveTests.cs +++ b/Elements/test/IndexedPolyCurveTests.cs @@ -186,5 +186,23 @@ public void Intersects() Assert.Contains(new Vector3(5, 2), results); Assert.Contains(new Vector3(2.5, 7.5), results); } + + [Fact] + public void PreservesIndicesTransformed() + { + var pc = CreateTestPolycurve(); + var indices = pc.CurveIndices; + var copy = pc.TransformedPolycurve(new Transform(10, 0, 0)); + var newIndicies = copy.CurveIndices; + Assert.Equal(indices.Count, newIndicies.Count); + for (int i = 0; i < indices.Count; i++) + { + Assert.Equal(indices[i].Count, newIndicies[i].Count); + for (int j = 0; j < indices[i].Count; j++) + { + Assert.Equal(indices[i][j], newIndicies[i][j]); + } + } + } } } \ No newline at end of file From ed37ab5e970df0ce94d9e14dbb6ab06a7eedb3d4 Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Wed, 4 Oct 2023 16:56:15 +0300 Subject: [PATCH 4/6] CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdd2d9fe0..e05c206b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,8 @@ - `Polygon.Contains3D` passed wrong `out Containment containment` parameter in some cases. - Code generation supports `Vector3?` and `Color?` types. - +- `Polyline.TransformAt` returns correct transformations when parameter on domain is provided. +- `IndexedPolycurve` constructor that takes list of `BoundedCurve` now produces `CurveIndices` that share vertices and are withing index range. This means `IndexedPolyline.TransformedPolyline` preserves `CurveIndicies` on new `IndexedPolyline`. ### Changed - `GltfExtensions.UseReferencedContentExtension` is now true by default. From 8d0e4bdcd24b1873b50af4d5eac1069c7d0f767c Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Wed, 4 Oct 2023 17:28:42 +0300 Subject: [PATCH 5/6] Add PolylineTests.PolylineTransformAt --- Elements/test/PolylineTests.cs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Elements/test/PolylineTests.cs b/Elements/test/PolylineTests.cs index 2ce511e3b..dff99593f 100644 --- a/Elements/test/PolylineTests.cs +++ b/Elements/test/PolylineTests.cs @@ -774,5 +774,35 @@ public void PolylineForceAngleComplianceWithZeroAngle() Assert.True(CheckPolylineAngles(angles, normalizedPathEnd)); Assert.True(CheckPolylineAngles(angles, normalizedPathEndYAxisReferenceVector)); } + + [Fact] + public void PolylineTransformAt() + { + var polyline = new Polyline((0, 0), (5, 0), (5, 10), (-5, 10)); + + var transform = polyline.TransformAt(0); + Assert.Equal((0, 0), transform.Origin); + Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis); + + //transform = polyline.TransformAt(0.5); + //Assert.Equal((2.5, 0), transform.Origin); + //Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis); + + transform = polyline.TransformAt(1); + Assert.Equal((5, 0), transform.Origin); + Assert.Equal((Vector3.XAxis + Vector3.YAxis).Unitized().Negate(), transform.ZAxis); + + //transform = polyline.TransformAt(1.25); + //Assert.Equal((5, 2.5), transform.Origin); + //Assert.Equal(Vector3.YAxis.Negate(), transform.ZAxis); + + transform = polyline.TransformAt(2); + Assert.Equal((5, 10), transform.Origin); + Assert.Equal((Vector3.YAxis - Vector3.XAxis).Unitized().Negate(), transform.ZAxis); + + transform = polyline.TransformAt(2.75); + Assert.Equal((-2.5, 10), transform.Origin); + Assert.Equal(Vector3.XAxis, transform.ZAxis); + } } } \ No newline at end of file From 97ab9f545af58854b370459f6ecb33f9699fa1c9 Mon Sep 17 00:00:00 2001 From: Dmytro Muravskyi Date: Wed, 4 Oct 2023 17:40:33 +0300 Subject: [PATCH 6/6] Uncomment lines in PolylineTransformAt test --- Elements/test/PolylineTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Elements/test/PolylineTests.cs b/Elements/test/PolylineTests.cs index dff99593f..7d4ee2188 100644 --- a/Elements/test/PolylineTests.cs +++ b/Elements/test/PolylineTests.cs @@ -784,17 +784,17 @@ public void PolylineTransformAt() Assert.Equal((0, 0), transform.Origin); Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis); - //transform = polyline.TransformAt(0.5); - //Assert.Equal((2.5, 0), transform.Origin); - //Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis); + transform = polyline.TransformAt(0.5); + Assert.Equal((2.5, 0), transform.Origin); + Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis); transform = polyline.TransformAt(1); Assert.Equal((5, 0), transform.Origin); Assert.Equal((Vector3.XAxis + Vector3.YAxis).Unitized().Negate(), transform.ZAxis); - //transform = polyline.TransformAt(1.25); - //Assert.Equal((5, 2.5), transform.Origin); - //Assert.Equal(Vector3.YAxis.Negate(), transform.ZAxis); + transform = polyline.TransformAt(1.25); + Assert.Equal((5, 2.5), transform.Origin); + Assert.Equal(Vector3.YAxis.Negate(), transform.ZAxis); transform = polyline.TransformAt(2); Assert.Equal((5, 10), transform.Origin);