/// <summary>
        /// Check for any occurence where distance of two vertices are too narrow (within the tolerance)
        /// </summary>
        /// <param name="entityId">The integer number representing the current IFC entity Id</param>
        /// <param name="shapeEditScope">the shapeEditScope</param>
        /// <param name="inputVerticesList">Input list of the vertices</param>
        /// <param name="outputVerticesList">Output List of the valid vertices, i.e. not vertices that are too close to each other</param>
        /// <returns></returns>
        public static void CheckAnyDistanceVerticesWithinTolerance(int entityId, IFCImportShapeEditScope shapeEditScope, IList <XYZ> inputVerticesList, out IList <XYZ> outputVerticesList)
        {
            // Check triangle that is too narrow (2 vertices are within the tolerance
            double shortSegmentTolerance = shapeEditScope.TryToCreateSolid() ?
                                           shapeEditScope.Document.Application.ShortCurveTolerance :
                                           shapeEditScope.Document.Application.VertexTolerance;

            int         lastVertex = 0;
            IList <XYZ> vertList   = new List <XYZ>();

            outputVerticesList = vertList;
            for (int ii = 1; ii <= inputVerticesList.Count; ii++)
            {
                int currIdx = (ii % inputVerticesList.Count);

                double dist = inputVerticesList[lastVertex].DistanceTo(inputVerticesList[currIdx]);
                if (dist >= shortSegmentTolerance)
                {
                    vertList.Add(inputVerticesList[lastVertex]);
                    lastVertex = currIdx;
                }
                else
                {
                    string distAsString      = IFCUnitUtil.FormatLengthAsString(dist);
                    string shortDistAsString = IFCUnitUtil.FormatLengthAsString(shortSegmentTolerance);
                    string warningString     = "Distance between vertices " + lastVertex + " and " + currIdx +
                                               " is " + distAsString + ", which is less than the minimum " + (shapeEditScope.TryToCreateSolid() ? "Solid" : "Mesh") +
                                               " distance of " + shortDistAsString + ", removing second point.";

                    Importer.TheLog.LogComment(entityId, warningString, false);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Check for any occurence where distance of two vertices are too narrow (within the tolerance)
        /// </summary>
        /// <param name="entityId">The integer number representing the current IFC entity Id</param>
        /// <param name="shapeEditScope">the shapeEditScope</param>
        /// <param name="inputVerticesList">Input list of the vertices</param>
        /// <param name="outputVerticesList">Output List of the valid vertices, i.e. not vertices that are too close to each other</param>
        /// <returns></returns>
        public static void CheckAnyDistanceVerticesWithinTolerance(int entityId, IFCImportShapeEditScope shapeEditScope, IList <XYZ> inputVerticesList, out IList <XYZ> outputVerticesList)
        {
            // Check triangle that is too narrow (2 vertices are within the tolerance)
            double shortSegmentTolerance = shapeEditScope.TryToCreateSolid() ?
                                           shapeEditScope.Document.Application.ShortCurveTolerance :
                                           shapeEditScope.Document.Application.VertexTolerance;

            int         lastVertex = 0;
            IList <XYZ> vertList   = new List <XYZ>();

            outputVerticesList = vertList;
            for (int ii = 1; ii <= inputVerticesList.Count; ii++)
            {
                int currIdx = (ii % inputVerticesList.Count);

                double dist = inputVerticesList[lastVertex].DistanceTo(inputVerticesList[currIdx]);
                if (dist >= shortSegmentTolerance)
                {
                    vertList.Add(inputVerticesList[lastVertex]);
                    lastVertex = currIdx;
                }
                else if (Importer.TheOptions.VerboseLogging)
                {
                    // Because of the way garbage collection works with the API, calling FormatLengthAsString too often
                    // (i.e. millions of times) can cause IFC import to run out of memory.  As such, we limit the
                    // calls to VerboseLogging only, which is used for debugging.

                    string distAsString      = IFCUnitUtil.FormatLengthAsString(dist);
                    string shortDistAsString = IFCUnitUtil.FormatLengthAsString(shortSegmentTolerance);
                    string warningString     = "Distance between vertices " + lastVertex + " and " + currIdx +
                                               " is " + distAsString + ", which is less than the minimum " + (shapeEditScope.TryToCreateSolid() ? "Solid" : "Mesh") +
                                               " distance of " + shortDistAsString + ", removing second point.";

                    Importer.TheLog.LogComment(entityId, warningString, false);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Create geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        protected override void CreateShapeInternal(IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            base.CreateShapeInternal(shapeEditScope, lcs, scaledLcs, guid);

            IList <XYZ> loopVertices = Bound.LoopVertices;
            int         count        = 0;

            if (loopVertices == null || ((count = loopVertices.Count) == 0))
            {
                throw new InvalidOperationException("#" + Id + ": missing loop vertices, ignoring.");
            }

            if (count < 3)
            {
                throw new InvalidOperationException("#" + Id + ": too few loop vertices (" + count + "), ignoring.");
            }

            if (!Orientation)
            {
                loopVertices.Reverse();
            }

            // Apply the transform
            IList <XYZ> transformedVertices = new List <XYZ>();

            foreach (XYZ vertex in loopVertices)
            {
                transformedVertices.Add(scaledLcs.OfPoint(vertex));
            }

            // The tolerance we use to determine if loop vertices are too close to one another is based on what type of data
            // we are trying to create.  If we are trying to create a Solid, then we must have vertices that are further apart than ShortCurveTolerance.
            // If we are trying to cerate a Mesh, then the smaller VertexTolerance is acceptable.
            double shortSegmentTolerance = shapeEditScope.TryToCreateSolid() ?
                                           shapeEditScope.Document.Application.ShortCurveTolerance :
                                           shapeEditScope.Document.Application.VertexTolerance;

            // Check that the loop vertices don't contain points that are very close to one another;
            // if so, throw the point away and hope that the TessellatedShapeBuilder can repair the result.
            // Warn in this case.  If the entire boundary is bad, report an error and don't add the loop vertices.
            IList <XYZ> validVertices = new List <XYZ>();
            int         lastVertex    = 0;

            for (int ii = 1; ii <= count; ii++)
            {
                int currIdx = (ii % count);

                double dist = transformedVertices[lastVertex].DistanceTo(transformedVertices[currIdx]);
                if (dist >= shortSegmentTolerance)
                {
                    validVertices.Add(transformedVertices[lastVertex]);
                    lastVertex = currIdx;
                }
                else
                {
                    string warningString = GenerateShortDistanceCommentString(dist, shortSegmentTolerance, lastVertex, currIdx, shapeEditScope.TryToCreateSolid());
                    IFCImportFile.TheLog.LogComment(Id, warningString, false);
                }
            }

            // We are going to catch any exceptions if the loop is invalid.
            // We are going to hope that we can heal the parent object in the TessellatedShapeBuilder.
            bool bPotentiallyAbortFace = false;

            count = validVertices.Count;
            if (validVertices.Count < 3)
            {
                IFCImportFile.TheLog.LogComment(Id, "Too few distinct loop vertices (" + count + "), ignoring.", false);
                bPotentiallyAbortFace = true;
            }
            else
            {
                try
                {
                    shapeEditScope.AddLoopVertices(validVertices);
                }
                catch (InvalidOperationException ex)
                {
                    IFCImportFile.TheLog.LogComment(Id, ex.Message, false);
                    bPotentiallyAbortFace = true;
                }
            }

            if (bPotentiallyAbortFace && IsOuter)
            {
                shapeEditScope.AbortCurrentFace();
            }
        }