private List <PlaneHelper> GetPlaneHelpers([NotNull] IFeature feature) { const bool includeAssociatedParts = true; SegmentsPlaneProvider planeProvider = SegmentsPlaneProvider.Create(feature, includeAssociatedParts); var indexedMultiPatch = (IIndexedMultiPatch)planeProvider.IndexedSegments; var result = new List <PlaneHelper>(); SegmentsPlane segmentsPlane; while ((segmentsPlane = planeProvider.ReadPlane()) != null) { result.Add(PlaneHelper.Create(segmentsPlane, indexedMultiPatch, this)); } return(result); }
private static IEnumerable <Either <NonPlanarError, SegmentsPlane> > GetPlanarRings( [NotNull] IFeature planarFeature, double coplanarityTolerance) { SegmentsPlaneProvider provider = SegmentsPlaneProvider.Create(planarFeature, false); SegmentsPlane segPlane; while ((segPlane = provider.ReadPlane()) != null) { // check for co-planarity double maximumOffset; yield return(IsCoplanar(segPlane, planarFeature, coplanarityTolerance, out maximumOffset) ? new Either <NonPlanarError, SegmentsPlane>(segPlane) : new NonPlanarError("Coplanarity tolerance is exceeded", maximumOffset, segPlane)); } }
protected override int ExecuteCore(IRow row, int tableIndex) { int errorCount = 0; var feature = row as IFeature; if (feature == null) { return(errorCount); } var geometryCollection = feature.Shape as IGeometryCollection; if (geometryCollection == null) { return(errorCount); } SegmentsPlaneProvider segmentsPlaneProvider = GetPlaneProvider(feature); SegmentsPlane segmentsPlane; while ((segmentsPlane = segmentsPlaneProvider.ReadPlane()) != null) { Plane3D plane; try { plane = segmentsPlane.Plane; } catch (Exception e) { errorCount += ReportInvalidPlane( $"Unable to determine plane: {e.Message}", segmentsPlane, feature); continue; } if (!plane.IsDefined) { errorCount += ReportInvalidPlane( "The segments of this face are collinear and do not define a valid plane", segmentsPlane, feature); continue; } double coplanarityTolerance = GeomUtils.AdjustCoplanarityTolerance(plane, _coplanarityTolerance, _zResolution, _xyResolution); double maxOffset = -1; int segmentsCount = 0; foreach (SegmentProxy segment in segmentsPlane.Segments) { segmentsCount++; IPnt point = segment.GetStart(true); //double f = normal.X * point.X + normal.Y * point.Y + // normalZ * point[2] + nf; // double offset = Math.Abs(f); double offset = plane.GetDistanceAbs(point.X, point.Y, point[2]); if (offset <= coplanarityTolerance) { continue; } maxOffset = Math.Max(offset, maxOffset); } if (segmentsCount < 3) { // TODO no need to check here once the plane is undefined in this case --> REMOVE const string description = "The segments of this face are collinear and do not define a valid plane"; IGeometry errorGeometry = GetErrorGeometry(feature.Shape.GeometryType, segmentsPlane.Segments); errorCount += ReportError(description, errorGeometry, Codes[Code.FaceDoesNotDefineValidPlane], null, row); continue; } if (maxOffset > 0) { string comparison = FormatLengthComparison( maxOffset, ">", _coplanarityTolerance, feature.Shape.SpatialReference); string description = $"Face with {segmentsCount} segments is not planar, max. offset = {comparison}"; IGeometry errorGeometry = GetErrorGeometry(feature.Shape.GeometryType, segmentsPlane.Segments); errorCount += ReportError(description, errorGeometry, Codes[Code.FaceNotCoplanar], TestUtils.GetShapeFieldName(feature), InvolvedRowUtils.GetInvolvedRows(row), new object[] { maxOffset }); } } return(errorCount); }