private static void GetClosePart([NotNull] SegmentProxy neighbor, [NotNull] IPnt near, double searchDistanceSquared, bool is3D, out double min, out double max) { Pnt p = Pnt.Create(near); IList <double[]> limits; bool cut = SegmentUtils.CutCurveCircle(neighbor, p, searchDistanceSquared, is3D, out limits); if (cut == false || limits.Count == 0) { min = SegmentUtils.GetClosestPointFraction(neighbor, p, is3D); max = min; } else { min = double.MaxValue; max = double.MinValue; foreach (double[] limit in limits) { foreach (double d in limit) { min = Math.Min(d, min); max = Math.Max(d, max); } } } min = Math.Max(min, 0); max = Math.Max(max, 0); min = Math.Min(min, 1); max = Math.Min(max, 1); }
private void Initialize() { _indexedMultipatch = GetAdaptedMultiPatch(); IMultiPatch multiPatch = _indexedMultipatch.BaseGeometry; _verticalFaceSegments = new List <SegmentProxy>(); var patches = (IGeometryCollection)multiPatch; var verticalPatchParts = new Dictionary <int, List <int> >(); int patchCount = patches.GeometryCount; for (int patchIndex = 0; patchIndex < patchCount; patchIndex++) { List <int> partIndexes = _indexedMultipatch.GetPartIndexes(patchIndex); foreach (int partIndex in partIndexes) { int partSegmentCount = _indexedMultipatch.GetPartSegmentCount(partIndex); var segments = new List <SegmentProxy>(partSegmentCount); for (int segmentIndex = 0; segmentIndex < partSegmentCount; segmentIndex++) { segments.Add( _indexedMultipatch.GetSegment(partIndex, segmentIndex)); } Plane plane = QaGeometryUtils.CreatePlane( (IEnumerable <SegmentProxy>)segments); if (Math.Abs(plane.GetNormalVector().Z) < double.Epsilon) { List <int> verticalParts; if (!verticalPatchParts.TryGetValue( patchIndex, out verticalParts)) { verticalParts = new List <int>(); verticalPatchParts.Add(patchIndex, verticalParts); } verticalParts.Add(partIndex); _verticalFaceSegments.AddRange(segments); } } } if (verticalPatchParts.Count > 0) { object missing = Type.Missing; IMultiPatch nonVerticalMultiPatch = new MultiPatchClass { SpatialReference = multiPatch.SpatialReference }; for (int patchIndex = 0; patchIndex < patchCount; patchIndex++) { List <int> verticalParts; IGeometry patch = ((IGeometryCollection)multiPatch).Geometry[patchIndex]; if (!verticalPatchParts.TryGetValue( patchIndex, out verticalParts)) { IGeometry clone = GeometryFactory.Clone(patch); ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry( clone, ref missing, ref missing); var ring = patch as IRing; if (ring != null) { bool isBeginning = false; esriMultiPatchRingType ringType = multiPatch.GetRingType(ring, ref isBeginning); nonVerticalMultiPatch.PutRingType( (IRing)clone, ringType); } } else { if (patch is IRing) { continue; } List <int> partIndexes = _indexedMultipatch.GetPartIndexes(patchIndex); foreach (int partIndex in partIndexes) { if (verticalParts.Contains(partIndex)) { continue; } int partSegmentCount = _indexedMultipatch.GetPartSegmentCount(partIndex); var points = new List <WKSPointZ>(3); for (int segmentIndex = 0; segmentIndex < partSegmentCount; segmentIndex++) { SegmentProxy segment = _indexedMultipatch.GetSegment( partIndex, segmentIndex); const bool as3D = true; Pnt p = segment.GetStart(as3D); points.Add( WKSPointZUtils.CreatePoint(p.X, p.Y, p[2])); } IRing ring = CreateRing(points); ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry( ring, ref missing, ref missing); } } } _nonVerticalMultipatch = nonVerticalMultiPatch; } else { _nonVerticalMultipatch = multiPatch; } }