Exemple #1
0
 public bool IsValid(decimal epsilon = 0.5m)
 {
     return(!GetCoplanarFaces().Any() && // Check coplanar faces
            !GetBackwardsFaces(epsilon).Any() && // Check faces are pointing outwards
            !Faces.Any(x => x.GetNonPlanarVertices(epsilon).Any()) && // Check face vertices are all on the plane
            Faces.All(x => x.IsConvex()));   // Check all faces are convex
 }
Exemple #2
0
        protected override object GetFieldValue(Item cognitiveIndexable)
        {
            if (Faces == null || Faces.Length == 0)
            {
                return(null);
            }

            if (Faces.Any(x => x.FaceAttributes.Gender.Equals("male")) &&
                Faces.Any(x => x.FaceAttributes.Gender.Equals("female")))
            {
                return(2);
            }

            if (Faces.Any(x => x.FaceAttributes.Gender.Equals("male")))
            {
                return(3);
            }

            if (Faces.Any(x => x.FaceAttributes.Gender.Equals("female")))
            {
                return(4);
            }

            return(1);
        }
Exemple #3
0
        private bool _containsOnInside(Point passedPoint)
        {
            if (Faces.Any(face => face.Contains(passedPoint)))
            {
                return(false);
            }
            Line  testLine = new Line(Point.Origin, passedPoint);
            Line  intersectionLine;
            int   counter = 0;
            Point intersectionPoint;

            foreach (Polygon face in this.Faces)
            {
                intersectionPoint = face.IntersectWithLine(testLine).As <Point>();
                if (intersectionPoint != null)
                {
                    intersectionLine = new Line(passedPoint, intersectionPoint);
                    if (intersectionLine.Direction.Equals(testLine.Direction))
                    {
                        counter++;
                    }
                }
            }
            if (counter % 2 == 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Exemple #4
0
 public Face AddFace(Face face)
 {
     if (Faces.Any(f => f.IsMatchFor(face)))
     {
         throw new InvalidOperationException("There is allready such a face in the shape!");
     }
     Faces.Add(face);
     return(face);
 }
 public Face2D AddFace(Face2D face)
 {
     if (Faces.Any(f => f.IsMatchFor(face)))
     {
         //throw new InvalidOperationException("There is already such a face in the shape!");
         Debug.Log("There is already such a face in the shape!");
         return(face);
     }
     Faces.Add(face);
     face.Shape = this;
     _lazyExitedEdges.isValeChanged = true;
     _lazyAllEdges.isValeChanged    = true;
     _lazyAllPoints.isValeChanged   = true;
     return(face);
 }
Exemple #6
0
        /// <summary>
        /// Gets neighbours that do not have any uncovered neighbours and are not contained in any face.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="nodeInFaces">Whether we found a node that is contained in a face.</param>
        /// <returns></returns>
        private List <TNode> GetSoloNeighbours(TNode node, out bool nodeInFaces)
        {
            var soloNeighbours = new List <TNode>();

            nodeInFaces = false;

            foreach (var neighbour in Graph.GetNeighbours(node).Where(x => !IsCovered(x)))
            {
                if (UncoveredNeighboursCount(neighbour) == 0)
                {
                    if (Faces.Any(x => x.Contains(neighbour)))
                    {
                        nodeInFaces = true;
                        continue;
                    }

                    soloNeighbours.Add(neighbour);
                }
            }

            return(soloNeighbours);
        }
Exemple #7
0
 public bool Contains(Point point)
 {
     if (Faces.Any(face => face.Contains(point)))
     {
         return(true);
     }
     if (this.IsConvex)
     {
         foreach (Plane face in this.Faces)
         {
             if (face.PointIsOnNormalSide(point))
             {
                 return(false);
             }
         }
     }
     else
     {
         return(_containsOnInside(point));
     }
     return(true);
 }
Exemple #8
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Validates this mesh. </summary>
        ///
        /// <remarks>   TODO: Think about this
        ///             How much do we really want to do at this top level?  Without making certain assumptions
        ///             it's really difficult to do anything useful but we want to be as flexible as possible.
        ///             Since we currently only create elements by adding faces, it's pretty safe, I think, to
        ///             insist that all faces have at least three edges.
        ///
        ///             Darrell Plank, 12/8/2017. </remarks>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        public virtual bool Validate()
        {
            if (VerticesInternal.Count == 0)
            {
                if (HalfEdgesInternal.Count != 0 && FacesInternal.Count != 0)
                {
                    throw new MeshNavException("No vertices but we have other elements");
                }
            }

            if (Faces.Any(face => face.Edges().Take(3).Count() != 3 && !face.IsBoundary))
            {
                throw new MeshNavException("Faces with less than three sides not allowed");
            }

            if (Faces.Where(f => f.IsAlive).Any(f => !f.HalfEdge.IsAlive))
            {
                throw new MeshNavException("Live faces point to dead halfedges");
            }

            if (Vertices.Where(v => v.IsAlive).Any(v => v.Mesh != this || !v.Edge.IsAlive))
            {
                throw new MeshNavException("Live vertices point at dead half edges or don't belong to this mesh");
            }

            if (HalfEdges.Where(he => he.IsAlive).Any(he => !he.InitVertex.IsAlive || he.Face != null && !he.Face.IsAlive))
            {
                throw new MeshNavException("Live halfedge points at dead component");
            }

            if (HalfEdges.Where(he => he.IsAlive).Any(he => he.InitVertex == he.Opposite.InitVertex))
            {
                throw new MeshNavException("Edge and opposite oriented identically");
            }
            return(true);
        }
Exemple #9
0
        /// <summary>
        /// Gets a path that is conencted to already discovered vertices.
        /// </summary>
        /// <remarks>
        /// It tries to minimize the number of chains with only a single node.
        /// </remarks>
        /// <returns></returns>
        private List <TNode> GetNextPath()
        {
            var firstVertex = default(TNode);
            var firstDepth  = int.MaxValue;
            var foundFirst  = false;

            // Save a node that is the covered neighbour of the firstVertex
            var hasOrigin = false;
            var origin    = default(TNode);

            // Check if there is at least one covered node
            if (Graph.Vertices.Any(IsCovered))
            {
                foreach (var node in Graph.Vertices.Where(x => !IsCovered(x)))
                {
                    var coveredNeighbours = Graph.GetNeighbours(node).Where(IsCovered).ToList();

                    if (coveredNeighbours.Count == 0)
                    {
                        continue;
                    }

                    var minDepthIndex = coveredNeighbours.MinBy(GetDepth);
                    var minDepth      = GetDepth(coveredNeighbours[minDepthIndex]);

                    if (minDepth < firstDepth)
                    {
                        firstVertex = node;
                        firstDepth  = minDepthIndex;
                        foundFirst  = true;

                        hasOrigin = true;
                        origin    = coveredNeighbours[minDepthIndex];
                    }
                }
            }
            else
            {
                // If there are no covered nodes, find a one that is a leaf
                firstVertex = Graph.Vertices.First(x => Graph.GetNeighbours(x).Count() == 1);
                foundFirst  = true;
            }

            // Must not happen
            if (!foundFirst)
            {
                throw new InvalidOperationException();
            }

            var chain = new List <TNode>();

            chain.Add(firstVertex);
            SetDepth(firstVertex, ChainsCounter);

            var nodeInFaces = false;

            // Check if we have an origin vertex and if the first vertex has any uncovered neighbour.
            // If it does not have any uncovered neighbour, it will normally form a chain of the lenght 1.
            // We want to prevent it and check if the origin node has any neighbour with the same characteristics.
            if (groupSoloVertices && hasOrigin && UncoveredNeighboursCount(firstVertex) == 0)
            {
                var soloNeighbours = GetSoloNeighbours(origin, out nodeInFaces);

                foreach (var neighbour in soloNeighbours)
                {
                    chain.Add(neighbour);
                    SetDepth(neighbour, ChainsCounter);
                }
            }

            while (true)
            {
                var lastNode   = chain[chain.Count - 1];
                var neighbours = Graph.GetNeighbours(lastNode).Where(x => !IsCovered(x)).ToList();

                // Break if there are not neigbours
                if (neighbours.Count == 0)
                {
                    break;
                }

                if (groupSoloVertices)
                {
                    var soloNeighbours = GetSoloNeighbours(lastNode, out var nodeInFacesLocal);

                    if (nodeInFacesLocal)
                    {
                        nodeInFaces = true;
                    }

                    // Add solo neighbours as above.
                    // Break if we found at least one.
                    if (soloNeighbours.Count != 0)
                    {
                        foreach (var neighbour in soloNeighbours)
                        {
                            chain.Add(neighbour);
                            SetDepth(neighbour, ChainsCounter);
                        }

                        break;
                    }
                }

                var nextNode = neighbours[0];
                if (Faces.Any(x => x.Contains(nextNode)))
                {
                    nodeInFaces = true;
                }

                chain.Add(nextNode);
                SetDepth(nextNode, ChainsCounter);

                // Break if we found a node that is contained in a face.
                // We do not want this path to continue with that face.
                if (nodeInFaces)
                {
                    break;
                }
            }

            ChainsCounter++;
            return(chain);
        }