示例#1
0
 private void AddFaceToTessellatedShapeBuilder(TessellatedFace theFace)
 {
     TessellatedShapeBuilder.AddFace(theFace);
     TessellatedFaceBoundary.Clear();
     FaceMaterialId = ElementId.InvalidElementId;
     CreatedFacesCount++;
 }
        /// <summary>
        /// Start collecting edges for a face to create a BRep solid.
        /// </summary>
        /// <param name="materialId">The material id of the face.</param>
        /// <param name="canTriangulate">Whether we can delay processing bad boundary data.</param>
        public void StartCollectingFace(ElementId materialId, bool canTriangulate)
        {
            if (TessellatedShapeBuilder == null)
            {
                throw new InvalidOperationException("StartCollectingFaceSet has not been called.");
            }

            if (TessellatedFaceBoundary == null)
            {
                TessellatedFaceBoundary = new List <IList <XYZ> >();
            }
            else
            {
                TessellatedFaceBoundary.Clear();
            }

            if (TessellatedFaceVertices == null)
            {
                TessellatedFaceVertices = new IFCFuzzyXYZSet(GetVertexTolerance());
            }

            DelayedFaceBoundary           = null;
            CanProcessDelayedFaceBoundary = canTriangulate;
            FaceMaterialId = materialId;
        }
示例#3
0
        /// <summary>
        /// Remove the current invalid face from the list of faces to create a BRep solid.
        /// </summary>
        override public void AbortCurrentFace()
        {
            if (TessellatedFaceBoundary != null)
            {
                TessellatedFaceBoundary.Clear();
            }

            FaceMaterialId = ElementId.InvalidElementId;
        }
 private void AddFaceToTessellatedShapeBuilder(TessellatedFace theFace, bool extraFace)
 {
     TessellatedShapeBuilder.AddFace(theFace);
     TessellatedFaceBoundary.Clear();
     FaceMaterialId = ElementId.InvalidElementId;
     if (extraFace)
     {
         ExtraCreatedFacesCount++;
     }
     else
     {
         CreatedFacesCount++;
     }
 }
示例#5
0
        /// <summary>
        /// Stop collecting faces to create a BRep solid.
        /// </summary>
        public void StopCollectingFaceSet()
        {
            if (TessellatedShapeBuilder == null)
            {
                throw new InvalidOperationException("StartCollectingFaceSet has not been called.");
            }

            TessellatedShapeBuilder.CloseConnectedFaceSet();

            if (TessellatedFaceBoundary != null)
            {
                TessellatedFaceBoundary.Clear();
            }

            if (TessellatedFaceVertices != null)
            {
                TessellatedFaceVertices.Clear();
            }

            FaceMaterialId = ElementId.InvalidElementId;
        }
示例#6
0
        /// <summary>
        /// Start collecting faces to create a BRep solid.
        /// </summary>
        public void StartCollectingFaceSet()
        {
            if (TessellatedShapeBuilder == null)
            {
                TessellatedShapeBuilder = new TessellatedShapeBuilder();
            }

            TessellatedShapeBuilder.OpenConnectedFaceSet(false);
            ResetCreatedFacesCount();

            if (TessellatedFaceVertices != null)
            {
                TessellatedFaceVertices.Clear();
            }

            if (TessellatedFaceBoundary != null)
            {
                TessellatedFaceBoundary.Clear();
            }

            FaceMaterialId = ElementId.InvalidElementId;
        }
示例#7
0
        /// <summary>
        /// Add one loop of vertices that will define a boundary loop of the current face.
        /// </summary>
        /// <param name="id">The id of the IFCEntity, for error reporting.</param>
        /// <param name="loopVertices">The list of vertices.</param>
        /// <returns>True if the operation succeeded, false oherwise.</returns>
        public bool AddLoopVertices(int id, List <XYZ> loopVertices)
        {
            int vertexCount = (loopVertices == null) ? 0 : loopVertices.Count;

            if (vertexCount < 3)
            {
                Importer.TheLog.LogComment(id, "Too few distinct loop vertices, ignoring.", false);
                return(false);
            }

            List <XYZ> adjustedLoopVertices         = null;
            IList <Tuple <int, int> > interiorLoops = null;

            int numOuterCreated = 0;

            bool succeeded = false;

            for (int pass = 0; pass < 2 && !succeeded; pass++)
            {
                // If we have AnyGeometry as a target, we are using Solid tolerances on a first pass.
                // If that would fail, try again using Mesh tolerances.
                if (pass == 1 && !RevertToMeshIfPossible())
                {
                    break;
                }

                succeeded = true;

                // numOuterCreated is the size of the main "outer" loop after removing duplicates
                // and self-intersecting loops.  In all valid cases, numOuterCreated = numTotalCreated.
                numOuterCreated = 0;

                // The total number of non-duplicate loops.  This can differ if we are trying to create
                // a solid vs. a mesh.
                int numTotalCreated = 0;

                // The vertices of the main (presumably outer) loop.
                adjustedLoopVertices = new List <XYZ>();

                // The list of vertices of the self-intersecting loops.
                // Note that we will check that the self-interecting loops do not themselves self-intersect.
                interiorLoops = new List <Tuple <int, int> >();
                int lastInteriorLoopIndex = -1;

                IDictionary <XYZ, int> createdVertices =
                    new SortedDictionary <XYZ, int>(new IFCXYZFuzzyComparer(GetVertexTolerance()));

                for (int ii = 0; ii < vertexCount; ii++)
                {
                    XYZ loopVertex = loopVertices[ii];

                    int createdVertexIndex = -1;
                    if (createdVertices.TryGetValue(loopVertex, out createdVertexIndex))
                    {
                        // We will allow the first and last point to be equivalent, or the current and last point.  Otherwise we will throw.
                        if (((createdVertexIndex == 0) && (ii == vertexCount - 1)) || (createdVertexIndex == numTotalCreated - 1))
                        {
                            continue;
                        }

                        // If we have a real self-intersection, mark the loop created by the intersection
                        // for removal later.
                        if (loopVertex.DistanceTo(loopVertices[createdVertexIndex]) < MathUtil.SmallGap())
                        {
                            if (lastInteriorLoopIndex > createdVertexIndex)
                            {
                                // The interior loops overlap; this is probably too much to try to fix.
                                succeeded = false;
                                break;
                            }
                            // Sorted in reverse order so we can more easily create the interior loops later.
                            int numToRemove = ii - createdVertexIndex;
                            interiorLoops.Insert(0, Tuple.Create(createdVertexIndex, numToRemove));
                            lastInteriorLoopIndex = ii;
                            numOuterCreated      -= numToRemove;
                            continue;
                        }

                        // Note that if pass == 1, CanRevertToMesh will be false.
                        if (!CanRevertToMesh())
                        {
                            Importer.TheLog.LogWarning(id, "Loop is self-intersecting, truncating.", false);
                        }
                        succeeded = false;
                        break;
                    }

                    XYZ adjustedXYZ = TessellatedFaceVertices.FindOrAdd(loopVertex);

                    adjustedLoopVertices.Add(adjustedXYZ);
                    createdVertices[adjustedXYZ] = numTotalCreated;
                    numTotalCreated++;
                    numOuterCreated++;
                }

                if (numOuterCreated < 3)
                {
                    succeeded = false;
                }
            }

            // Checking start and end points should be covered above.
            if (numOuterCreated < 3)
            {
                Importer.TheLog.LogComment(id, "Loop has less than 3 distinct vertices, ignoring.", false);
                return(false);
            }

            // Remove the interior loops from the loop boundary, in reverse order, and add them
            // to the tessellated face boundary.
            foreach (Tuple <int, int> interiorLoop in interiorLoops)
            {
                int startIndex = interiorLoop.Item1;
                int count      = interiorLoop.Item2;
                if (count >= 3)
                {
                    TessellatedFaceBoundary.Add(loopVertices.GetRange(startIndex, count));
                }
                adjustedLoopVertices.RemoveRange(startIndex, count);
            }

            if (interiorLoops.Count > 0)
            {
                Importer.TheLog.LogWarning(id, "Loop is self-intersecting, fixing.", false);
            }

            TessellatedFaceBoundary.Add(adjustedLoopVertices);
            return(true);
        }