1. 程式人生 > >[Revit二次開發] Selection互動API-建立柱子並計算體積

[Revit二次開發] Selection互動API-建立柱子並計算體積

摘要:

  本文主要是對Selection互動API的應用:

1.選擇一個點,在該點建立一個柱子;
2.選擇剛建立的柱子,計算其體積;
3.框選若干元素,得到選中的牆的數量。

專案完整程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;// StructuralType.NonStructural
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection; //Selection
using Autodesk.Revit.Attributes;


namespace Sele
{
    [TransactionAttribute(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            //選擇一個點
            Selection s1 = uidoc.Selection;//using Autodesk.Revit.UI.Selection;
            XYZ point = null;

            try
            {
                point = s1.PickPoint("請選擇一個點"); //將在Revit的左下角提示
            }
            catch
            {
                return Result.Succeeded;
            }

            //由於需要修改點,所以需要建立一個事務Transaction
            Transaction t1 = new Transaction(doc,"t1");
            t1.Start();
            FamilySymbol familySymbol = doc.GetElement(new ElementId(338378)) as FamilySymbol;//建立一個柱子,其Id為338378
            //判斷族型別
            if (!familySymbol.IsActive)
            {
                familySymbol.Activate();
            }
            Level level = null;//宣告標高
            FamilyInstance fi = doc.Create.NewFamilyInstance(point, familySymbol, level, StructuralType.NonStructural);//using Autodesk.Revit.DB.Structure;

            Selection s2 = uidoc.Selection;
            Reference re = s2.PickObject(ObjectType.Edge, "請選擇一個物體");
            Element ele = doc.GetElement(re);
            Options opt = new Options();
            GeometryElement gelem = ele.get_Geometry(opt);
            double v = 0.0;//宣告體積
            v = GetSolid(gelem).Sum(m => m.Volume) * 0.3048 * 0.3048 * 0.3048;
            TaskDialog.Show("Hint", "選中的物體體積為:" + v.ToString("f3"));

            //過濾元素"牆"
            IList<Element> pickedElements = s2.PickElementsByRectangle(new WallSelectionFilter(), "請框選目標物體");
            double num = pickedElements.Count();
            TaskDialog.Show("Hint", "已選中牆的數量為:" + num);

            return Result.Succeeded;
        }

        private List<Solid> GetSolid(GeometryElement gelem)
        {
            List<Solid> solids = new List<Solid>();
            foreach(GeometryObject obj in gelem)//遍歷陣列gelem中每一個GeometryObject型別的物件
            {
                if(obj is Solid)//元素是3d實體
                {
                    solids.Add(obj as Solid);
                }
                if(obj is GeometryElement)//GeometryElement:元素的幾何表示。
                {
                    solids.AddRange(GetSolid(obj as GeometryElement));
                }
                if(obj is GeometryInstance)
                {
                    GeometryInstance gins = obj as GeometryInstance;
                    GeometryElement gelm = gins.GetInstanceGeometry();
                    solids.AddRange(GetSolid(gelem));
                }
            }
            return solids;
        }     
    }
    //自定義過濾器
    public class WallSelectionFilter:ISelectionFilter
    {
        public bool AllowElement(Element elem)
        {
            return elem is Wall;
        }

        public bool AllowReference(Autodesk.Revit.DB.Reference reference,Autodesk.Revit.DB.XYZ position)
        {
            return true;
        }
    }
}

效果:

參考文獻:

 周婧禕《Autodesk Revit 2016二次開發入門教程》