public static IGeometry GetGeometryComponent([NotNull] IFeature feature,
                                                     GeometryComponent component)
        {
            IGeometry shape = feature.Shape;

            return(shape == null ? null : GetGeometryComponent(shape, component));
        }
        /// <summary>
        /// returns -1 if neighbourFeature is polygon, geometryComponent is entireGeometry and point lies within neighbourFeature.
        /// otherwise returns distance.
        /// </summary>
        private static double GetDistance([NotNull] IPoint point,
                                          [NotNull] IFeature neighbourFeature,
                                          [NotNull] IPoint nearestPoint,
                                          GeometryComponent geometryComponent,
                                          double maxNeededDistance,
                                          out bool isWithinPolygon,
                                          out bool onRightSide)
        {
            isWithinPolygon = false;
            if (geometryComponent == GeometryComponent.Boundary &&
                neighbourFeature.Shape is IPolygon)
            {
                return(GetDistanceToCurve(point, neighbourFeature, nearestPoint,
                                          maxNeededDistance, out onRightSide));
            }

            if (geometryComponent == GeometryComponent.Vertices)
            {
                onRightSide = false;
                return(GetDistanceToVertices(point, neighbourFeature, nearestPoint,
                                             maxNeededDistance));
            }

            // other cases: create component geometry explicitly
            IGeometry neighbourGeometry =
                Assert.NotNull(GeometryComponentUtils.GetGeometryComponent(
                                   neighbourFeature, geometryComponent));

            if (geometryComponent == GeometryComponent.EntireGeometry &&
                neighbourGeometry is IPolygon)
            {
                if (((IRelationalOperator)neighbourGeometry).Disjoint(point))
                {
                    // the point is outside the polygon - get the distance to the boundary
                    // (faster than getting the distance to the entire polygon)
                    return(GetDistanceToCurve(point, neighbourFeature, nearestPoint,
                                              maxNeededDistance, out onRightSide));
                }

                // the point is inside the polygon or exactly on the boundary
                isWithinPolygon = true;
                onRightSide     = false;             // polygons borders are defined counter clock wise
                return(-1);
            }

            if (geometryComponent == GeometryComponent.EntireGeometry &&
                neighbourGeometry is IPolyline)
            {
                return(GetDistanceToCurve(point, neighbourFeature, nearestPoint,
                                          maxNeededDistance, out onRightSide));
            }

            // Use IProximityOperator.QueryNearestPoint so that the error geometry can be constructed
            ((IProximityOperator)neighbourGeometry).QueryNearestPoint(
                point, esriSegmentExtension.esriNoExtension, nearestPoint);
            onRightSide = false;
            return(((IProximityOperator)point).ReturnDistance(nearestPoint));
        }
        private int ReportError([NotNull] IFeature pointFeature,
                                [NotNull] IFeature referenceFeature,
                                [NotNull] IPoint point,
                                [NotNull] IPoint nearPoint,
                                double distance,
                                double minimumDistance, bool isWithinPolygon,
                                GeometryComponent geometryComponent,
                                [CanBeNull] IValidRelationConstraint validConstraint)
        {
            IssueCode issueCode;
            string    description;
            IGeometry errorGeometry;

            if (isWithinPolygon)
            {
                description   = "Point lies within polygon";
                errorGeometry = GeometryFactory.Clone(point);

                issueCode = validConstraint == null
                                                    ? Codes[Code.PointWithin]
                                                    : Codes[Code.PointWithin_ConstraintNotFulfilled];
            }
            else
            {
                if (geometryComponent == GeometryComponent.EntireGeometry)
                {
                    description =
                        string.Format(
                            "Point is too close to reference feature: {0}",
                            FormatLengthComparison(distance, "<", minimumDistance,
                                                   _spatialReference));
                }
                else
                {
                    description =
                        string.Format(
                            "Point is too close to {0} of reference feature: {1}",
                            GeometryComponentUtils.GetDisplayText(geometryComponent),
                            FormatLengthComparison(distance, "<", minimumDistance,
                                                   _spatialReference));
                }

                bool reportAsConnectionLine = MinimumErrorLineLength >= 0 &&
                                              distance >= MinimumErrorLineLength;

                errorGeometry =
                    GetErrorGeometry(point, nearPoint, reportAsConnectionLine);

                issueCode = validConstraint == null
                                                    ? Codes[Code.PointTooClose]
                                                    : Codes[Code.PointTooClose_ConstraintNotFulfilled];
            }

            return(ReportError(description, errorGeometry,
                               issueCode, _shapeFieldName,
                               pointFeature, referenceFeature));
        }
Exemple #4
0
        private static void AssertEmpty(GeometryComponent geometryComponent,
                                        IGeometry geometry)
        {
            var component = GeometryComponentUtils.GetGeometryComponent(geometry,
                                                                        geometryComponent);

            Assert.NotNull(component);
            Assert.IsTrue(component.IsEmpty);
        }
        public static int ReportIntersections(
            [NotNull] IRow row1, int tableIndex1,
            [NotNull] IRow row2, int tableIndex2,
            [NotNull] IErrorReporting errorReporting,
            [CanBeNull] IssueCode issueCode,
            [CanBeNull] IValidRelationConstraint validRelationConstraint,
            bool reportIndividualParts,
            [CanBeNull] GeometryConstraint validIntersectionGeometryConstraint = null,
            GeometryComponent geomComponent1 = GeometryComponent.EntireGeometry,
            GeometryComponent geomComponent2 = GeometryComponent.EntireGeometry)
        {
            Assert.ArgumentNotNull(row1, nameof(row1));
            Assert.ArgumentNotNull(row2, nameof(row2));
            Assert.ArgumentNotNull(errorReporting, nameof(errorReporting));

            if (row1 == row2)
            {
                return(_noError);
            }

            string errorDescription;

            if (HasFulfilledConstraint(row1, tableIndex1,
                                       row2, tableIndex2,
                                       validRelationConstraint, "Features intersect",
                                       out errorDescription))
            {
                return(_noError);
            }

            IGeometry shape1 = ((IFeature)row1).Shape;
            IGeometry shape2 = ((IFeature)row2).Shape;

            var g1 = GeometryComponentUtils.GetGeometryComponent(shape1, geomComponent1);
            var g2 = GeometryComponentUtils.GetGeometryComponent(shape2, geomComponent2);

            var errorCount = 0;

            if (g1 != null && g2 != null)
            {
                foreach (IGeometry errorGeometry in
                         IntersectionUtils.GetAllIntersections(g1, g2))
                {
                    if (validIntersectionGeometryConstraint == null ||
                        !validIntersectionGeometryConstraint.IsFulfilled(errorGeometry))
                    {
                        errorCount += errorReporting.Report(errorDescription,
                                                            errorGeometry,
                                                            issueCode, reportIndividualParts,
                                                            row1, row2);
                    }
                }
            }

            return(errorCount);
        }
        private static IGeometry GetLineEndPoint([NotNull] IGeometry shape,
                                                 GeometryComponent component)
        {
            var polyCurve = shape as IPolycurve;

            Assert.NotNull(polyCurve, GetNotSupportedMessage(shape, component));

            return(polyCurve.IsEmpty
                                       ? new PointClass {
                SpatialReference = shape.SpatialReference
            }
                                       : polyCurve.ToPoint);
        }
        private static IGeometry GetCentroidPoint([NotNull] IGeometry shape,
                                                  GeometryComponent component)
        {
            var area = shape as IArea;

            Assert.NotNull(area, GetNotSupportedMessage(shape, component));

            return(shape.IsEmpty
                                       ? new PointClass {
                SpatialReference = shape.SpatialReference
            }
                                       : area.Centroid);
        }
        private static IGeometry GetBoundary([NotNull] IGeometry shape,
                                             GeometryComponent component)
        {
            var topoOp = shape as ITopologicalOperator;

            Assert.NotNull(topoOp, GetNotSupportedMessage(shape, component));

            // note: calling Boundary on an empty MultiPatch returns a NON-EMPTY polyline
            //       with 5 empty vertices and length = NaN

            return(shape.IsEmpty
                                       ? new PolylineClass {
                SpatialReference = shape.SpatialReference
            }
                                       : topoOp.Boundary);
        }
        private GeometryComponent Read_GeometryComponent(BinaryReader reader)
        {
            var result = new GeometryComponent();

            result.Version = ReadVersion(reader, 1, 0x14120B5A0);

            result.IndexCount   = reader.ReadUInt32();
            result.VertextCount = reader.ReadUInt32();
            result.IndexFormat  = reader.ReadUInt32();

            var indexDataLength = reader.ReadInt32();

            result.IndexData     = reader.ReadBytes(indexDataLength);
            result.VertexStreams = Read_List(reader, Read_VertexStream, 1, 0x1411D9B70);

            return(result);
        }
        private static IGeometry GetVertices([NotNull] IGeometry shape,
                                             GeometryComponent component)
        {
            switch (shape.GeometryType)
            {
            case esriGeometryType.esriGeometryPoint:
                return(GeometryFactory.Clone(shape));

            case esriGeometryType.esriGeometryMultipoint:
            case esriGeometryType.esriGeometryMultiPatch:
            case esriGeometryType.esriGeometryPolygon:
            case esriGeometryType.esriGeometryPolyline:
                var         points     = (IPointCollection)GeometryFactory.Clone(shape);
                IMultipoint multipoint = GeometryFactory.CreateMultipoint(points);
                GeometryUtils.Simplify(multipoint);

                return(multipoint);

            default:
                throw new ArgumentException(GetNotSupportedMessage(shape, component));
            }
        }
        public static string GetDisplayText(GeometryComponent geometryComponent)
        {
            switch (geometryComponent)
            {
            case GeometryComponent.EntireGeometry:
                return("entire geometry");

            case GeometryComponent.Boundary:
                return("boundary");

            case GeometryComponent.Vertices:
                return("vertices");

            case GeometryComponent.LineEndPoints:
                return("end points");

            case GeometryComponent.LineStartPoint:
                return("start point");

            case GeometryComponent.LineEndPoint:
                return("end point");

            case GeometryComponent.Centroid:
                return("centroid");

            case GeometryComponent.LabelPoint:
                return("label point");

            case GeometryComponent.InteriorVertices:
                return("interior vertices");

            default:
                throw new ArgumentOutOfRangeException(
                          nameof(geometryComponent), geometryComponent,
                          $@"Unsupported geometry component: {geometryComponent}");
            }
        }
        public static IGeometry GetGeometryComponent([NotNull] IGeometry shape,
                                                     GeometryComponent component)
        {
            switch (component)
            {
            case GeometryComponent.EntireGeometry:
                return(shape);

            case GeometryComponent.Boundary:
                return(GetBoundary(shape, component));

            case GeometryComponent.Vertices:
                return(GetVertices(shape, component));

            case GeometryComponent.LineEndPoints:
                return(GetLineEndPoints(shape, component));

            case GeometryComponent.LineStartPoint:
                return(GetLineStartPoint(shape, component));

            case GeometryComponent.LineEndPoint:
                return(GetLineEndPoint(shape, component));

            case GeometryComponent.Centroid:
                return(GetCentroidPoint(shape, component));

            case GeometryComponent.LabelPoint:
                return(GetLabelPoint(shape, component));

            case GeometryComponent.InteriorVertices:
                return(GetInteriorVertices(shape, component));

            default:
                throw new ArgumentOutOfRangeException(
                          $"Illegal geometry component: {component}");
            }
        }
        private static IGeometry GetInteriorVertices([NotNull] IGeometry shape,
                                                     GeometryComponent component)
        {
            Assert.True(shape.GeometryType == esriGeometryType.esriGeometryPolyline,
                        GetNotSupportedMessage(shape, component));

            if (shape.IsEmpty)
            {
                return(new MultipointClass {
                    SpatialReference = shape.SpatialReference
                });
            }

            var points = (IPointCollection)GeometryFactory.Clone(shape);

            points.RemovePoints(points.PointCount - 1, 1);
            points.RemovePoints(0, 1);

            IMultipoint multipoint = GeometryFactory.CreateMultipoint(points);

            GeometryUtils.Simplify(multipoint);

            return(multipoint);
        }
Exemple #14
0
 public void ProcessNew(BoundingSphereComponent bounds, TransformComponent transform, GeometryComponent geometry)
 => this.Partition.Add(transform.Entity, bounds.Radius, transform.Transform, this.GeometryService);
Exemple #15
0
        protected virtual void UppdateGeometry(IEntityManager manager, ElementTag tag, GeometryComponent geo)
        {
            var en = manager.GetEntity(tag);

            en.RemoveComponents <GeometryComponent>();
            en.AddComponent(geo);
        }
Exemple #16
0
        static void ComputeTangents(GeometryComponent geo)
        {
            var positions          = geo.Positions;
            var triangleIndices    = geo.Indices;
            var textureCoordinates = geo.TextureCoordinates;
            var normals            = geo.Normals;

            var tan1 = new Vector3[positions.Length];

            //var tan2 = new Vector3[positions.Count];
            for (int t = 0; t < triangleIndices.Length; t += 3)
            {
                var i1 = triangleIndices[t];
                var i2 = triangleIndices[t + 1];
                var i3 = triangleIndices[t + 2];

                var v1 = positions[i1];
                var v2 = positions[i2];
                var v3 = positions[i3];

                var w1 = textureCoordinates[i1];
                var w2 = textureCoordinates[i2];
                var w3 = textureCoordinates[i3];

                float x1 = v2.X - v1.X;
                float x2 = v3.X - v1.X;
                float y1 = v2.Y - v1.Y;
                float y2 = v3.Y - v1.Y;
                float z1 = v2.Z - v1.Z;
                float z2 = v3.Z - v1.Z;

                float s1 = w2.X - w1.X;
                float s2 = w3.X - w1.X;
                float t1 = w2.Y - w1.Y;
                float t2 = w3.Y - w1.Y;

                float r    = 1.0f / (s1 * t2 - s2 * t1);
                var   udir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
                //var vdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

                tan1[i1] += udir;
                tan1[i2] += udir;
                tan1[i3] += udir;

                //tan2[i1] += vdir;
                //tan2[i2] += vdir;
                //tan2[i3] += vdir;
            }

            geo.Tangents = new List <Vector3>();
            geo.Binormal = new List <Vector3>();
            for (int i = 0; i < positions.Length; i++)
            {
                var n = normals[i];
                var t = tan1[i];
                t = (t - n * Vector3.Dot(n, t));
                t.Normalize();
                var b = Vector3.Cross(n, t);
                geo.Tangents.Add(t);
                geo.Binormal.Add(b);
            }
        }
 private static string GetNotSupportedMessage([NotNull] IGeometry shape,
                                              GeometryComponent component)
 {
     return(string.Format("{0} not supported for geometry type {1}",
                          component, shape.GeometryType));
 }
Exemple #18
0
        private int CheckTable([NotNull] IFeature feature,
                               [NotNull] IFeatureClass referenceClass,
                               int referenceClassIndex)
        {
            GeometryComponent geometryComponent =
                GetGeometryComponent(referenceClassIndex);

            IValidRelationConstraint validConstraint =
                GetValidRelationConstraint(referenceClassIndex);

            if (_pointTemplate == null)
            {
                _pointTemplate = new PointClass();
            }

            var errorCount = 0;

            foreach (IPoint point in GetNodes(feature.Shape, _pointTemplate))
            {
                ISpatialFilter    filter = PrepareSpatialFilter(point, referenceClassIndex);
                QueryFilterHelper helper = _helper[referenceClassIndex];

                const int pointClassIndex = 0;
                foreach (IRow referenceRow in Search((ITable)referenceClass,
                                                     filter, helper, point))
                {
                    if (TestUtils.IsSameRow(feature, referenceRow))
                    {
                        continue;
                    }

                    var referenceFeature = (IFeature)referenceRow;

                    string conditionMessage;
                    if (validConstraint != null &&
                        validConstraint.HasConstraint &&
                        validConstraint.IsFulfilled(feature, pointClassIndex,
                                                    referenceFeature, referenceClassIndex,
                                                    out conditionMessage))
                    {
                        continue;
                    }

                    double standardDistance;
                    double?rightSideDistance;
                    double maxNeededDistance = GetMaxNeededDistance(
                        feature, referenceFeature, referenceClassIndex,
                        out standardDistance, out rightSideDistance);
                    maxNeededDistance = Math.Max(maxNeededDistance, _pointClassXyTolerance);

                    bool   isWithinPolygon;
                    bool   onRightSide;
                    double distance = GetDistance(point, referenceFeature, _nearPoint,
                                                  geometryComponent, maxNeededDistance,
                                                  out isWithinPolygon, out onRightSide);

                    if (AllowCoincidentPoints &&
                        IsSmallerThanXyTolerance(distance, referenceClassIndex))
                    {
                        continue;
                    }

                    if (distance > maxNeededDistance)
                    {
                        continue;
                    }

                    double minimumDistance = maxNeededDistance;
                    if (rightSideDistance.HasValue)
                    {
                        if (_referenceFlipConditions == null)
                        {
                            _referenceFlipConditions =
                                CreateFlipConditions(_referenceFlipExpressions);
                        }

                        bool flip = _referenceFlipConditions.Count > 0
                                                                    ? _referenceFlipConditions[
                            referenceClassIndex -
                            _firstReferenceClassIndex].IsFulfilled(
                            referenceFeature)
                                                                    : false;

                        double useDistance = (onRightSide == flip)
                                                                             ? standardDistance
                                                                             : rightSideDistance.Value;
                        if (distance > useDistance)
                        {
                            continue;
                        }

                        minimumDistance = useDistance;
                    }

                    errorCount += ReportError(feature, referenceFeature,
                                              point, _nearPoint,
                                              distance, minimumDistance,
                                              isWithinPolygon, geometryComponent,
                                              validConstraint);
                }
            }

            return(errorCount);
        }
Exemple #19
0
        public TerrainChunk(float[,] heightMap, uint chunkSize, uint offsetX, uint offsetY, ShaderResourceView texture, SamplerState sampler)
        {
            var mapSize     = chunkSize;
            var fullMapSize = heightMap.GetLength(1) - 1;
            var numPoints   = mapSize * 2 + 1;
            var triPoints   = new Vector3[numPoints * numPoints];
            var triUV       = new Vector2[numPoints * numPoints];

            for (var z = 0; z < numPoints; z++)
            {
                for (var x = 0; x < numPoints; x++)
                {
                    if (z % 2 == 0)
                    {
                        if (x % 2 == 0)
                        {
                            triPoints[x + z * numPoints] = new Vector3(x / 2 + offsetX - 0.5f,
                                                                       GetHeight(heightMap, x / 2 + offsetX, z / 2 + offsetY, -1, -1),
                                                                       fullMapSize - (z / 2 + offsetY - 0.5f));
                        }
                        else
                        {
                            triPoints[x + z * numPoints] = new Vector3(x / 2 + offsetX - 0.0f,
                                                                       GetHeight(heightMap, x / 2 + offsetX, z / 2 + offsetY, 0, -1),
                                                                       fullMapSize - (z / 2 + offsetY - 0.5f));
                        }
                    }
                    else
                    {
                        if (x % 2 == 0)
                        {
                            triPoints[x + z * numPoints] = new Vector3(x / 2 + offsetX - 0.5f,
                                                                       GetHeight(heightMap, x / 2 + offsetX, z / 2 + offsetY, -1, 0),
                                                                       fullMapSize - (z / 2 + offsetY - 0));
                        }
                        else
                        {
                            triPoints[x + z * numPoints] = new Vector3(x / 2 + offsetX - 0.0f,
                                                                       GetHeight(heightMap, x / 2 + offsetX, z / 2 + offsetY, 0, 0),
                                                                       fullMapSize - (z / 2 + offsetY - 0));
                        }
                    }
                    triUV[x + z * numPoints] = new Vector2(x / (numPoints - 1.0f), z / (numPoints - 1.0f));
                }
            }

            var indices = new uint[mapSize * mapSize * 24];
            var count   = 0;

            for (uint y = 0; y < numPoints - 1; y++)
            {
                for (uint x = 0; x < numPoints - 1; x++)
                {
                    var mapSize2 = numPoints;
                    var fx       = x;
                    if ((x % 2 == 0 && y % 2 == 0) || (x % 2 != 0 && y % 2 != 0))
                    {
                        indices[count++] = fx + y * mapSize2;
                        indices[count++] = fx + 1 + y * mapSize2;
                        indices[count++] = fx + 1 + (y + 1) * mapSize2;

                        indices[count++] = fx + y * mapSize2;
                        indices[count++] = fx + 1 + (y + 1) * mapSize2;
                        indices[count++] = fx + (y + 1) * mapSize2;
                    }
                    if ((x % 2 != 0 && y % 2 == 0) || (x % 2 == 0 && y % 2 != 0))
                    {
                        indices[count++] = fx + y * mapSize2;
                        indices[count++] = fx + 1 + y * mapSize2;
                        indices[count++] = fx + (y + 1) * mapSize2;

                        indices[count++] = fx + (y + 1) * mapSize2;
                        indices[count++] = fx + 1 + y * mapSize2;
                        indices[count++] = fx + 1 + (y + 1) * mapSize2;
                    }
                }
            }

            var geo = new GeometryComponent();

            geo.Executor.Geometry.Vertices = triPoints;
            geo.Executor.Geometry.Normals  = CalcNormals(triPoints, numPoints);
            geo.Executor.Geometry.Indices  = indices;
            geo.Executor.Geometry.UVs      = triUV;
            geo.Executor.Geometry.Topology = Topology.TriangleList;
            geo.Executor.RenderParameter.SetParameter("AlbedoTexture", texture);
            geo.Executor.RenderParameter.SetParameter("Sampler", sampler);
            this.AddComponent(geo);
        }