예제 #1
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();
        }