/// <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>
        /// 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();
        }