有没有办法使用Revit API获取视图中所有元素的最小BoundingBox?

问题描述 投票:0回答:1
namespace CropboxUtil
{
    [Transaction(TransactionMode.Manual)]
    internal static class ViewUtility
    {
        public static void CropToBoundingBox(this View view, short clearance = 5)
        {
            Document document = view.Document;
            

            using (var transaction = new Transaction(document))
            {
                transaction.Start("Visual Coordinate Grid: CropToBoundingBox");

                BoundingBoxXYZ elementsBoundingBox = view.GetBoundingBoxOfElements();

                if (elementsBoundingBox != null)
                {
                    view.CropBoxActive = true;
                    view.CropBoxVisible = true;

                    view.CropBox = elementsBoundingBox;
                    transaction.Commit();
                }
                else
                {
                    TaskDialog.Show("Error!", "Não foi possível definir os limites dos elementos!");
                    transaction.RollBack();
                }
            }        
        }

        public static BoundingBoxXYZ GetBoundingBoxOfElements(this View view)
        {
            List<Element> elements = view.GetElements();

            try
            {
                double maxX = elements.Max(e => e.get_BoundingBox(view).Max.X);
                double maxY = elements.Max(e => e.get_BoundingBox(view).Max.Y);
                double maxZ = elements.Max(e => e.get_BoundingBox(view).Max.Z);

                double minX = elements.Min(e => e.get_BoundingBox(view).Min.X);
                double minY = elements.Min(e => e.get_BoundingBox(view).Min.Y);
                double minZ = elements.Min(e => e.get_BoundingBox(view).Min.Z);

                XYZ max = new XYZ(maxX, maxY, maxZ);
                XYZ min = new XYZ(minX, minY, minZ);

                return new BoundingBoxXYZ
                {
                    Max = max,
                    Min = min,
                };
            }
            catch (Autodesk.Revit.Exceptions.ApplicationException)
            {
                throw;
            }
        }

        public static List<Element> GetElements(this View view)
        {
            Document document = view.Document;
            Category sectionCategory = Category.GetCategory(document, BuiltInCategory.OST_Sections);

            return new FilteredElementCollector(document, view.Id)
                                                .WhereElementIsNotElementType()
                                                .WhereElementIsViewIndependent()
                                                .Where(e => e.CanBeHidden(view))
                                                .Where(e => e.Category != sectionCategory)
                                                .Cast<Element>()
                                                .ToList();
        }
    }
}

当我运行上面的代码时,调用

someViewInstanceObject.CropToBoundingBox()
如果裁剪框小于视图的对象限制,则会正确调整。 但是,如果裁剪框大于视图的对象限制,则它保持不变。但它应该 但是它应该缩小到包含对象限制的更小的可能。 有什么想法吗? PS.:间隙参数供以后使用。

c# .net revit-api
1个回答
0
投票
return new FilteredElementCollector(document, view.Id)                                               
           .WhereElementIsNotElementType()                                            
           .WhereElementIsViewIndependent()
           .Where(e => e.CanBeHidden(view))
           .Where(e => e.Category != null) //Avoid null exceptions
           .Where(e => e.Category.CategoryType is CategoryType.Model) //this is the trick
           .Cast<Element>()
           .ToList();

发现

GetElements
方法无法正常工作。我通过 LINQ 应用的过滤器并未从
FilteredElementCollector
中删除一些注释元素。所以我尝试了这种新方法:使用
CategoryType
仅过滤
CategoryType.Model
元素。 效果很好。无论如何,也许只有这个过滤器才能完成这项工作。

PS.:从 3D 视图调用时它仍然工作得很有趣,也许它需要

Transformation
才能在 3D 视图上正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.