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