コード例 #1
0
 private void CommitCone()
 {
     for (int i = 0; i < ConeFaceBuffer.Count; i++)
     {
         DeferredFace       deferredFace = ConeFaceBuffer[i];
         ConvexFaceInternal face         = deferredFace.Face;
         ConvexFaceInternal pivot        = deferredFace.Pivot;
         ConvexFaceInternal oldFace      = deferredFace.OldFace;
         int faceIndex = deferredFace.FaceIndex;
         face.AdjacentFaces[faceIndex] = pivot.Index;
         pivot.AdjacentFaces[deferredFace.PivotIndex] = face.Index;
         for (int j = 0; j < NumOfDimensions; j++)
         {
             if (j != faceIndex)
             {
                 FaceConnector connector = ObjectManager.GetConnector();
                 connector.Update(face, j, NumOfDimensions);
                 ConnectFace(connector);
             }
         }
         if (pivot.VerticesBeyond.Count == 0)
         {
             FindBeyondVertices(face, oldFace.VerticesBeyond);
         }
         else if (pivot.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
         {
             FindBeyondVertices(face, pivot.VerticesBeyond, oldFace.VerticesBeyond);
         }
         else
         {
             FindBeyondVertices(face, oldFace.VerticesBeyond, pivot.VerticesBeyond);
         }
         if (face.VerticesBeyond.Count == 0)
         {
             ConvexFaces.Add(face.Index);
             UnprocessedFaces.Remove(face);
             ObjectManager.DepositVertexBuffer(face.VerticesBeyond);
             face.VerticesBeyond = EmptyBuffer;
         }
         else
         {
             UnprocessedFaces.Add(face);
         }
         ObjectManager.DepositDeferredFace(deferredFace);
     }
     for (int k = 0; k < AffectedFaceBuffer.Count; k++)
     {
         int num = AffectedFaceBuffer[k];
         UnprocessedFaces.Remove(FacePool[num]);
         ObjectManager.DepositFace(num);
     }
 }
コード例 #2
0
        /// <summary>
        /// Commits a cone and adds a vertex to the convex hull.
        /// </summary>
        void CommitCone()
        {
            // Add the current vertex.
            ConvexHull.Add(CurrentVertex);

            // Fill the adjacency.
            for (int i = 0; i < ConeFaceBuffer.Count; i++)
            {
                var face = ConeFaceBuffer[i];

                var newFace           = face.Face;
                var adjacentFace      = face.Pivot;
                var oldFace           = face.OldFace;
                var orderedPivotIndex = face.FaceIndex;

                newFace.AdjacentFaces[orderedPivotIndex]    = adjacentFace;
                adjacentFace.AdjacentFaces[face.PivotIndex] = newFace;

                // let there be a connection.
                for (int j = 0; j < Dimension; j++)
                {
                    if (j == orderedPivotIndex)
                    {
                        continue;
                    }
                    var connector = ObjectManager.GetConnector();
                    connector.Update(newFace, j, Dimension);
                    ConnectFace(connector);
                }

                // This could slightly help...
                if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
                {
                    FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
                }
                else
                {
                    FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
                }

                // This face will definitely lie on the hull
                if (newFace.VerticesBeyond.Count == 0)
                {
                    ConvexFaces.Add(newFace);
                    UnprocessedFaces.Remove(newFace);
                    ObjectManager.DepositVertexBuffer(newFace.VerticesBeyond);
                    newFace.VerticesBeyond = EmptyBuffer;
                }
                else // Add the face to the list
                {
                    UnprocessedFaces.Add(newFace);
                }

                // recycle the object.
                ObjectManager.DepositDeferredFace(face);
            }

            // Recycle the affected faces.
            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var face = AffectedFaceBuffer[fIndex];
                UnprocessedFaces.Remove(face);
                ObjectManager.DepositFace(face);
            }
        }
コード例 #3
0
ファイル: ConvexHullInternal.cs プロジェクト: hipigod/Dynamo
        /// <summary>
        /// Removes the faces "covered" by the current vertex and adds the newly created ones.
        /// </summary>
        private void CreateCone()
        {
            var oldFaces = AffectedFaceBuffer;

            var currentVertexIndex = CurrentVertex.Index;

            for (int fIndex = 0; fIndex < oldFaces.Count; fIndex++)
            {
                var oldFace = oldFaces[fIndex];

                // Find the faces that need to be updated
                int updateCount = 0;
                for (int i = 0; i < Dimension; i++)
                {
                    var af = oldFace.AdjacentFaces[i];
                    if (af.Tag == 0) // Tag == 0 when oldFaces does not contain af
                    {
                        UpdateBuffer[updateCount]  = af;
                        UpdateIndices[updateCount] = i;
                        ++updateCount;
                    }
                }

                // Recycle the face for future use
                if (updateCount == 0)
                {
                    // If the face is present in the unprocessed list, remove it
                    UnprocessedFaces.Remove(oldFace);

                    RecycleFace(oldFace);
                    RecycledFaceStack.Push(oldFace);
                }

                for (int i = 0; i < updateCount; i++)
                {
                    var adjacentFace = UpdateBuffer[i];

                    int oldFaceAdjacentIndex = 0;
                    var adjFaceAdjacency     = adjacentFace.AdjacentFaces;
                    for (int j = 0; j < Dimension; j++)
                    {
                        if (object.ReferenceEquals(oldFace, adjFaceAdjacency[j]))
                        {
                            oldFaceAdjacentIndex = j;
                            break;
                        }
                    }

                    var forbidden = UpdateIndices[i]; // Index of the face that corresponds to this adjacent face

                    ConvexFaceInternal newFace;

                    int          oldVertexIndex;
                    VertexWrap[] vertices;

                    // Recycle the oldFace
                    if (i == updateCount - 1)
                    {
                        RecycleFace(oldFace);
                        newFace        = oldFace;
                        vertices       = newFace.Vertices;
                        oldVertexIndex = vertices[forbidden].Index;
                    }
                    else // Pop a face from the recycled stack or create a new one
                    {
                        newFace  = GetNewFace();
                        vertices = newFace.Vertices;
                        for (int j = 0; j < Dimension; j++)
                        {
                            vertices[j] = oldFace.Vertices[j];
                        }
                        oldVertexIndex = vertices[forbidden].Index;
                    }

                    int orderedPivotIndex;

                    // correct the ordering
                    if (currentVertexIndex < oldVertexIndex)
                    {
                        orderedPivotIndex = 0;
                        for (int j = forbidden - 1; j >= 0; j--)
                        {
                            if (vertices[j].Index > currentVertexIndex)
                            {
                                vertices[j + 1] = vertices[j];
                            }
                            else
                            {
                                orderedPivotIndex = j + 1;
                                break;
                            }
                        }
                    }
                    else
                    {
                        orderedPivotIndex = Dimension - 1;
                        for (int j = forbidden + 1; j < Dimension; j++)
                        {
                            if (vertices[j].Index < currentVertexIndex)
                            {
                                vertices[j - 1] = vertices[j];
                            }
                            else
                            {
                                orderedPivotIndex = j - 1;
                                break;
                            }
                        }
                    }

                    vertices[orderedPivotIndex] = CurrentVertex;

                    CalculateFacePlane(newFace);
                    newFace.AdjacentFaces[orderedPivotIndex]         = adjacentFace;
                    adjacentFace.AdjacentFaces[oldFaceAdjacentIndex] = newFace;

                    // let there be a connection.
                    for (int j = 0; j < Dimension; j++)
                    {
                        if (j == orderedPivotIndex)
                        {
                            continue;
                        }
                        var connector = GetNewConnector();
                        connector.Update(newFace, j, Dimension);
                        ConnectFace(connector);
                    }

                    // This could slightly help...
                    if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
                    {
                        FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
                    }
                    else
                    {
                        FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
                    }

                    // This face will definitely lie on the hull
                    if (newFace.VerticesBeyond.Count == 0)
                    {
                        ConvexFaces.Add(newFace);
                        UnprocessedFaces.Remove(newFace);
                        EmptyBufferStack.Push(newFace.VerticesBeyond);
                        newFace.VerticesBeyond = EmptyBuffer;
                    }
                    else // Add the face to the list
                    {
                        UnprocessedFaces.Add(newFace);
                    }
                }
            }
        }