public static List <IPolygon> GetFaces( [NotNull] IIndexedMultiPatch indexedMultiPatch, int patchIndex) { IMultiPatch multiPatch = indexedMultiPatch.BaseGeometry; var patches = (IGeometryCollection)multiPatch; var ring = patches.Geometry[patchIndex] as IRing; if (ring != null) { bool beginning = false; multiPatch.GetRingType(ring, ref beginning); // TODO handle undefined/invalid ring types? return(beginning ? new List <IPolygon> { GetFace(multiPatch, ring) } : new List <IPolygon>()); } List <int> partIndexes = indexedMultiPatch.GetPartIndexes(patchIndex); var result = new List <IPolygon>(partIndexes.Count); foreach (int partIndex in partIndexes) { WKSPointZ[] wksPoints = GetWksPointZs(indexedMultiPatch, partIndex); IPolygon face = GeometryFactory.CreatePolygon(wksPoints, multiPatch .SpatialReference); result.Add(face); } return(result); }
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; } }