Пример #1
0
        /// <summary>
        /// Tests if a point is within a curveloop.  The point wil be projected onto the
        /// plane which holds the curveloop before the test is executed.
        /// </summary>
        /// <param name="point">The point to test.</param>
        /// <param name="curveloop">A curveloop that lies in a plane.</param>
        /// <returns>True, if the point was inside the curveloop after the
        /// point was projected onto the curveloop's plane. False, otherwise.</returns>
        private static bool IsPointInsideCurveLoop(XYZ point, CurveLoop curveloop)
        {
            // Starting at the point, shoot an infinite ray in one direction and count how many
            // times the ray intersects the edges of the curveloop.  If the ray intersects
            // an odd number of edges, then the point was inside the curveloop.  If it
            // intersects an even number of times, then the point was outside the curveloop.
            //
            // Note: Revit doesn't have an infinite ray class, so a very long Line is used instead.
            // This test can fail if the curveloop is wider than the very long line.

            // Calculate the plane on which the edges of the curveloop lie.
            Plane plane = Plane.CreateByThreePoints(curveloop.ElementAt(0).GetEndPoint(0),
                                                    curveloop.ElementAt(1).GetEndPoint(0),
                                                    curveloop.ElementAt(2).GetEndPoint(0));

            // Project the test point on the plane.
            XYZ projectedPoint = ProjectPointOnPlane(plane, point);

            // Create a very long bounded line that starts at projectedPoint and runs
            // along the plane's surface.
            Line veryLongLine = Line.CreateBound(projectedPoint,
                                                 projectedPoint + (RANDOM_X_SCALE * plane.XVec) + (RANDOM_Y_SCALE * plane.YVec));

            // Count how many edges of curveloop intersect veryLongLine.
            int intersectionCount = 0;

            foreach (var edge in curveloop)
            {
                IntersectionResultArray resultArray;
                SetComparisonResult     res = veryLongLine.Intersect(edge, out resultArray);
                if (SetComparisonResult.Overlap == res)
                {
                    intersectionCount += resultArray.Size;
                }
            }

            // If the intersection count is ODD, then the point is inside the curveloop.
            return(1 == (intersectionCount % 2));
        }
Пример #2
0
        public Polygon2D GetStairAreaPolygon(UIDocument currentDocument, Stairs stair, string key)
        {
            ICollection <ElementId> allRunsIds = stair.GetStairsRuns();
            ElementId currentId = allRunsIds.ElementAt(0);

            if (key.Equals(RevitObjectManager.BASE_LEVEL_KEY))
            {
                foreach (ElementId currentBaseId in allRunsIds)
                {
                    StairsRun currentStairsRun  = currentDocument.Document.GetElement(currentBaseId) as StairsRun;
                    StairsRun selectedStairsRun = currentDocument.Document.GetElement(currentId) as StairsRun;

                    if (currentStairsRun.BaseElevation < selectedStairsRun.BaseElevation)
                    {
                        currentId = currentBaseId;
                    }
                }
            }
            else if (key.Equals(RevitObjectManager.TOP_LEVEL_KEY))
            {
                foreach (ElementId currentTopId in allRunsIds)
                {
                    StairsRun currentStairsRun  = currentDocument.Document.GetElement(currentTopId) as StairsRun;
                    StairsRun selectedStairsRun = currentDocument.Document.GetElement(currentId) as StairsRun;

                    if (currentStairsRun.TopElevation > selectedStairsRun.TopElevation)
                    {
                        currentId = currentTopId;
                    }
                }
            }

            List <Vector2D> areaNodes      = new List <Vector2D>();
            StairsRun       finalStairsRun = currentDocument.Document.GetElement(currentId) as StairsRun;
            CurveLoop       stairPath      = finalStairsRun.GetStairsPath();
            Curve           firstStairPathCurve;

            if (stairPath.Count() > 1)
            {
                if ((finalStairsRun.StairsRunStyle.Equals(StairsRunStyle.Winder) || finalStairsRun.StairsRunStyle.Equals(StairsRunStyle.Spiral)) &&
                    key.Equals(RevitObjectManager.TOP_LEVEL_KEY))
                {
                    firstStairPathCurve = stairPath.ElementAt(stairPath.Count() - 1);
                }
                else
                {
                    firstStairPathCurve = stairPath.ElementAt(0);
                }
            }
            else
            {
                firstStairPathCurve = stairPath.ElementAt(0);
            }

            double stairsRunsWidth = ConvertFeetToMeters(finalStairsRun.ActualRunWidth * STAIRS_AREA_SHRINK_FACTOR);

            if (stairsRunsWidth < DEFAULT_AREA_RADIUS)
            {
                stairsRunsWidth = DEFAULT_AREA_RADIUS;
            }

            double pathsLength = ConvertFeetToMeters(firstStairPathCurve.Length * STAIRS_AREA_SHRINK_FACTOR);

            if (pathsLength < DEFAULT_AREA_RADIUS)
            {
                pathsLength = DEFAULT_AREA_RADIUS;
            }

            Vector2D pathsStart    = GeometryFactory.CreateVector2D(ConvertFeetToMeters(firstStairPathCurve.GetEndPoint(0).X), ConvertFeetToMeters(firstStairPathCurve.GetEndPoint(0).Y), MEASUREMENTUNITFACTOR);
            Vector2D pathsEnd      = GeometryFactory.CreateVector2D(ConvertFeetToMeters(firstStairPathCurve.GetEndPoint(1).X), ConvertFeetToMeters(firstStairPathCurve.GetEndPoint(1).Y), MEASUREMENTUNITFACTOR);
            Vector2D pathDirection = pathsEnd.Difference(pathsStart);
            Vector2D pathDirectionPerpenticular = pathDirection.Rotate((-1) * Math.PI / 2).GetAsNormalized();

            Vector2D firstNode = pathsStart.Add(pathDirectionPerpenticular.Multiply(stairsRunsWidth / 2));

            areaNodes.Add(firstNode);
            Vector2D pointToAdd = firstNode.Add(pathDirection);

            areaNodes.Add(pointToAdd);
            pointToAdd = pointToAdd.Add(pathDirectionPerpenticular.Multiply((-1) * stairsRunsWidth));
            areaNodes.Add(pointToAdd);
            pointToAdd = pointToAdd.Add(pathDirection.Multiply(-1));
            areaNodes.Add(pointToAdd);
            areaNodes.Add(firstNode);

            Polygon2D areaPolygon = GeometryFactory.CreatePolygon2D(areaNodes.ToArray(), finalStairsRun.Name);

            return(areaPolygon);
        }