Revit開發小功能集合

1.獲取Revit中打開的所有的View(視圖)

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    public class Command:IExternalCommand
    {
        /// <summary>
        /// 獲取所有打開的視圖並返回視圖名稱
        /// </summary>
        /// <param name="uidoc"></param>
        /// <returns></returns>
        private string GetOPenViews(UIDocument uidoc)
        {
            string info = null;
            IList<UIView> views = uidoc.GetOpenUIViews();
            foreach(UIView view in views)
            {
                info += uidoc.Document.GetElement(view.ViewId).Name+"\n";
            }
            return info;
        }
        public Result Execute(ExternalCommandData commandData,ref string message,ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;
            try
            {
                string res = GetOPenViews(uidoc);
                TaskDialog.Show("OpenViews", $"{res}");
                return Result.Succeeded;
            }
            catch(Exception ex)
            {
                TaskDialog.Show("Error Info", $"{ex.Message}");
                return Result.Failed;
            }
        }

    }
}


2.在不打開Revit的情況下讀取rvt文件數據

在Revit插件中可以在後臺打開rvt文件,並且訪問他的數據,但是這個數據讀取時依賴於Revit軟件的。
就是說必須要在Revit打開的情況下,運行一個插件,在插件代碼裏讀取rvt 的信息
我準備了一個機電測試文件,這個項目文件裏面一共畫了三個構建:一個長度爲8800mm的風管,一個長度爲6600mm的水管和一個橋架

下面的例子實現了打開一個rvt文件,並且過濾其中的風管類型的構建,並且獲取風管實例的長度,結果確實是8800mm

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    public class Command:IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData,ref string message,ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;

            Autodesk.Revit.ApplicationServices.Application app = commandData.Application.Application;
            Document _doc = app.OpenDocumentFile(@"D:\revit development project\Revit開發\機電測試.rvt");
            try
            {
                FilteredElementCollector filter = new FilteredElementCollector(_doc);
                filter.OfCategory(BuiltInCategory.OST_DuctCurves).WhereElementIsNotElementType();
                foreach(Element elem in filter)
                {
                    LocationCurve lc = elem.Location as LocationCurve;
                    TaskDialog.Show("Info",$"風管的長度={lc.Curve.Length*304.8}");
                }

                return Result.Succeeded;
            }
            catch(Exception ex)
            {
                TaskDialog.Show("Error Info", $"{ex.Message}");
                return Result.Failed;
            }
        }

    }
}


3.獲取元素的材質信息

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;
        /// <summary>
        /// 用一個輪廓來創建牆體,可以按照提供的輪廓創建形狀比較靈活的牆體,這裏創建一個梯形牆體
        /// </summary>
        /// <param name="doc"></param>
        public Wall CreateWall1(Document doc)
        {
            IList<Curve> curves = new List<Curve>();
            Line l1 = Line.CreateBound(XYZ.Zero, new XYZ(150, 0, 0));
            Line l2 = Line.CreateBound(XYZ.Zero, new XYZ(50, 0, 50));
            Line l3 = Line.CreateBound(new XYZ(50, 0, 50), new XYZ(100, 0, 50));
            Line l4 = Line.CreateBound(new XYZ(100, 0, 50), new XYZ(150, 0, 0));
            curves.Add(l1);
            curves.Add(l2);
            curves.Add(l3);
            curves.Add(l4);
            Wall wall1 = Wall.Create(doc, curves, false);
            return wall1;
        }
        /// <summary>
        /// 根據牆體的投影線,標高來創建牆體
        /// </summary>
        /// <param name="doc"></param>
        public Wall CreateWall2(Document doc)
        {
            // 創建一個輪廓,只需要創建牆體在x-o-y平面的投影就可以
            Curve curve1 = Line.CreateBound(XYZ.Zero, new XYZ(2000/unit, 0, 0)) as Curve;
            #region 找出標高最低的標高
            FilteredElementCollector coll = new FilteredElementCollector(doc);
            coll.OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType();
            List<Level> levels = new List<Level>();
            foreach (Level item in coll)
            {
                levels.Add(item);
            }
            levels.Sort((Level l1, Level l2) => l1.Elevation.CompareTo(l2.Elevation));
            #endregion

            //找出一個牆體類型
            FilteredElementCollector coll_wall = new FilteredElementCollector(doc).OfClass(typeof(WallType));
            ElementId levelId;
            ElementId wallTypeId;
            Level level = levels[0];
            if (level != null)
            {
                levelId = level.Id;
            }
            else
            {
                throw new Exception("標高爲空");
            }

            WallType type = coll_wall.FirstElement() as WallType;
            if (type != null)
            {
                wallTypeId = type.Id;
            }
            else
            {
                throw new Exception("牆體類型爲空");
            }

            Wall wall2 = Wall.Create(doc, curve1, levels[0].Id, false);
            return wall2;
        }

        /// <summary>
        /// 根據牆體的投影線,標高,牆體類型,偏移量,牆體高度創建牆體
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        public Wall CreateWall3(Document doc)
        {
            // 定義牆體的高度和偏移量
            double wall_height = 3000 / unit;
            double wall_offset = 300 / unit;
            // 創建一個輪廓,只需要創建牆體在x-o-y平面的投影就可以
            Curve curve1 = Line.CreateBound(XYZ.Zero, new XYZ(2000 / unit, 0, 0)) as Curve;
            #region 找出標高最低的標高
            FilteredElementCollector coll = new FilteredElementCollector(doc);
            coll.OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType();
            List<Level> levels = new List<Level>();
            foreach (Level item in coll)
            {
                levels.Add(item);
            }
            levels.Sort((Level l1, Level l2) => l1.Elevation.CompareTo(l2.Elevation));
            #endregion

            //找出一個牆體類型
            FilteredElementCollector coll_wall = new FilteredElementCollector(doc).OfClass(typeof(WallType));
            ElementId levelId;
            ElementId wallTypeId;
            Level level = levels[0];
            if (level != null)
            {
                levelId = level.Id;
            }
            else
            {
                throw new Exception("標高爲空");
            }

            WallType type = coll_wall.FirstElement() as WallType;
            if (type != null)
            {
                wallTypeId = type.Id;
            }
            else
            {
                throw new Exception("牆體類型爲空");
            }

            Wall wall2 = Wall.Create(doc,curve1,wallTypeId,levelId,wall_height,wall_offset,false,false);
            return wall2;

        }

        /// <summary>
        /// 需要的參數是前三種方法的不同組合就不寫了
        /// </summary>
        /// <param name="doc"></param>
        public Wall CreateWall4(Document doc)
        {
            //需要的參數是前三種方法的不同組合就不寫了
            return null;
        }
        /// <summary>
        /// 需要的參數是前三種方法的不同組合就不寫了
        /// </summary>
        /// <param name="doc"></param>
        public Wall CreateWall5(Document doc)
        {
            //需要的參數是前三種方法的不同組合就不寫了
            return null;
        }

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;
            try
            {
                using (Transaction ts = new Transaction(doc, "創建牆體"))
                {
                    ts.Start();
                    //CreateWall1(doc);
                    //CreateWall2(doc);
                    //CreateWall3(doc);
                    ts.Commit();
                }
                return Result.Succeeded;
            }
            catch(Exception ex)
            {
                throw new Exception(ex.StackTrace);
            }
        }

    }
}


5.編輯族參數(沒有成功,後期會更新)

注意:只有載入的族纔是可以修改的
using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;
            Reference reff = selection.PickObject(ObjectType.Element);
            Element elem = doc.GetElement(reff);

            //返回familySymbol的Id
            ElementId id = elem.GetTypeId();
            FamilySymbol fmSymbol = doc.GetElement(id) as FamilySymbol;

            // 返回編輯族的Document
            Document fmDoc = doc.EditFamily(fmSymbol.Family);


            // 得到FamilyManager,關於族參數的操作都在裏面
            FamilyManager manager = fmDoc.FamilyManager;
            IList<FamilyParameter> parameters = manager.GetParameters();
            string info = string.Empty;
            for(int i=0;i<parameters.Count;i++)
            {
                info += parameters[i].Definition.Name + "\n";
            }
            TaskDialog.Show("Parameter",info);
            Transaction ts = new Transaction(doc, "創建牆體");
            ts.Start();
          //  manager.RemoveParameter(parameters[-4]);
            manager.AddParameter("gender", BuiltInParameterGroup.PG_IDENTITY_DATA, ParameterType.Text, false);
          
            ts.Commit();
            fmDoc.LoadFamily(doc, new Opt());

            return Result.Succeeded;
        }

    }
    public class Opt : IFamilyLoadOptions
    {
        public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
        {
            overwriteParameterValues = true;
            return true;
        }

        public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
        {
            throw new NotImplementedException();
        }
    }
}

6.訪問牆體結構層信息

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;

            Reference reff = selection.PickObject(ObjectType.Element, "please select a wall");
            Wall wall = doc.GetElement(reff) as Wall;
            string info = string.Empty;
            CompoundStructure compoundStructure = wall.WallType.GetCompoundStructure();
            foreach(CompoundStructureLayer item in compoundStructure.GetLayers())
            {
                if (item.MaterialId == ElementId.InvalidElementId) continue;
                Material m = doc.GetElement(item.MaterialId) as Material;
                if (m == null) continue;
                info += m.Name + "\n";
            }

            TaskDialog.Show("牆體結構材質",info);
            return Result.Succeeded;
        }
    }
}

7.取消選中元素

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
using System.Threading;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;
            IList<Reference> reffs = selection.PickObjects(ObjectType.Element);
            string info = string.Empty;
            foreach(var item in reffs)
            {
                info += doc.GetElement(item).Name + "\n";
            }
            info += "點擊確認三秒鐘以後會自動取消選中地元素";
            TaskDialog.Show("Title", info);
            Thread.Sleep(3 * 1000);
            // 方法1
            elementSet.Clear();
            // 方法2
            selection.SetElementIds(new List<ElementId>());
            return Result.Succeeded;
        }
    }
}

8.選中元素

2015以後的版本都用selection.SetElementIds(List ids)這個方法來設置元素選中。

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
using System.Threading;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;
            Reference reff = selection.PickObject(ObjectType.Element);
            Element elem = doc.GetElement(reff);
            selection.SetElementIds(new List<ElementId>() { elem.Id});
            TaskDialog.Show("選擇", "已經選中");
            Thread.Sleep(2*1000);
            // 傳入一個空的列表,即取消選中
            selection.SetElementIds(new List<ElementId>());
            return Result.Succeeded;
        }
    }
}

9獲取元素的幾何信息

Revit中元素的幾何信息可以通過get_Geometry(Options)方法獲取,這個方法返回一個GeometryElement類型的值,GeometryElement裏面包含了這個元素所有的GeometryObject
這個函數需要傳入一個Options的參數,Options有一個默認無參數的構造器,Options類有下面幾個屬性可以設置:

屬性 說明
ComputeReferences 這是一個布爾值,如果是true,那麼返回的Reference不爲空,默認爲false
IncludeNonVisibleObjects 設置是否包含不可見的幾何
DetailLevel 對應視圖的詳細程度
IsReadOnly 是否只讀
View 返回這個視圖中可見的幾何
注意:獲取元素幾何信息一般分爲系統族和載入族來考慮,如果是系統族使用XX.get_Geometry(opt)獲取到的就是實體(Solid)
  • 如果族是載入族,要看是否是剪切過的族,如果是剪切過的族,那麼方法與系統族類似
  • 如果不是剪切過的族,那麼
  1. 通過XX.get_Geometry(opt)獲取到GeometryElement
  2. 再從GeometryElement獲取到GeometryInstance,再從GeometryInstance.GetInstanceGeometr()或者GeometryInstance.GetSymbolGeometry()獲取Solid進行操作

GeometryObject有下面的幾個子類:

  • Autodesk.Revit.DB.XX.Curve
  • Autodesk.Revit.DB.XX.Face
  • Autodesk.Revit.Db.XX.Edge
  • Autodesk.Revit.DB.XX.GeometryElement
  • Autodek.Revit.DB.XX.GeometryInstance
  • Autodesk.Revit.DB.XX.Mesh
  • Autodesk.Revit.DB.XX.Point
  • Autodesk.Revit.DB.XX.PolyLine
  • Autodesk.Revit.DB.XX.Profile
  • Autodesk.Revit.DB.XX.Solid
下面的代碼實現了獲取一個系統族(牆)的底面積和一個載入族(柱子)的底面積 ```csharp using System; using System.Collections.Generic; using Autodesk.Revit.UI; using Autodesk.Revit.DB; using Autodesk.Revit.Attributes; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.DB.Electrical; using System.Threading; namespace 插件 { [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)] [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)] [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)] public class Command : IExternalCommand { public readonly double unit = 304.8;
    public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
    {
        UIDocument uidoc = commandData.Application.ActiveUIDocument;
        Document doc = uidoc.Document;
        Selection selection = uidoc.Selection;

        Options opt = new Options
        {
            ComputeReferences = true,
            DetailLevel = ViewDetailLevel.Fine,
            IncludeNonVisibleObjects = false
        };
        // wall
        Reference reff = selection.PickObject(ObjectType.Element, "選擇一堵牆");
        Wall wall = doc.GetElement(reff) as Wall;
        GetWallBottomFaceAndComputeArea(wall, opt);

        // column
        Reference refColumn = selection.PickObject(ObjectType.Element, "請選擇一個柱子");
        FamilyInstance instance = doc.GetElement(refColumn) as FamilyInstance;
        GetColumnBottomFaceAndComputeArea(instance, opt);



        return Result.Succeeded;
    }
    /// <summary>
    /// 獲取一個沒有剪切的柱子實體最下面的面,並且輸出面積
    /// </summary>
    /// <param name="fmInstance"></param>
    /// <param name="opt"></param>
    public void GetColumnBottomFaceAndComputeArea(FamilyInstance fmInstance,Options opt)
    {
        GeometryElement geoElem = fmInstance.get_Geometry(opt);
        Face face = null;
        foreach(GeometryObject obj in geoElem)
        {
            if(obj is Solid)
            {
                Solid solid = obj as Solid;
                if(solid.Faces.Size>0)
                {
                face = FindBottomFace(solid);
                }
            }
            else if(obj is GeometryInstance)
            {
                GeometryInstance gmInstance = obj as GeometryInstance;
                // 獲取實例的solid
                GeometryElement geoElem1 = gmInstance.GetInstanceGeometry();
                // 獲取族類型的solid
                //GeometryElement geoElem1 = gmInstance.GetSymbolGeometry();
                foreach(GeometryObject obj2 in geoElem1)
                {
                    if(obj2 is Solid)
                    {
                        Solid solid = obj2 as Solid;
                        if(solid.Faces.Size>0)
                        {
                        face = FindBottomFace(solid);
                        }
                    }
                }
            }
        }
        TaskDialog.Show("柱子的底面積", face.Area.ToString());
    }
    /// <summary>
    /// 獲取牆體實體最下面的面,並且輸出面積
    /// </summary>
    /// <param name="wall"></param>
    /// <param name="opt"></param>
    public void GetWallBottomFaceAndComputeArea(Wall wall,Options opt)
    {
        GeometryElement geoElem = wall.get_Geometry(opt);
        foreach(GeometryObject obj in geoElem)
        {
            Solid solid = obj as Solid;
            // 排除獲取到的不是實體和獲取到的無效實體
            if(solid!=null && solid.Faces.Size>0)
            {
                Face face = FindBottomFace(solid);
                TaskDialog.Show("面積", face.Area.ToString());
            }
        }
    }
    /// <summary>
    /// 找出一個實體最下面的一個面
    /// </summary>
    /// <param name="solid"></param>
    /// <returns></returns>
    public Face FindBottomFace(Solid solid)
    {
        foreach(Face face in solid.Faces)
        {
            PlanarFace face1 = face as PlanarFace;
            if(face!=null)
            {
                if(face1.FaceNormal.X<0.01 && face1.FaceNormal.Y<0.01 && face1.FaceNormal.Z<0)
                {
                    return face;
                }
            }
        }
        return null;
    }
}   

}

### 10綁定命令——傳遞創建門命令
```csharp
using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
using System.Threading;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIApplication uiapp = new UIApplication(commandData.Application.Application);
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;
            // 傳遞創建門的命令
            CommandTest(uiapp);



            return Result.Succeeded;
        }

        private void CommandTest(UIApplication uiapp)
        {
            RevitCommandId CommandId = RevitCommandId.LookupPostableCommandId(PostableCommand.Door);
            if(uiapp.CanPostCommand(CommandId))
            {
                uiapp.PostCommand(CommandId);
            }
        }


    }
}

10 預覽Revit視圖的控件

Command類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
namespace 插件2
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    class Command:IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData,ref string message,ElementSet elementSet)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            PreWindow window = new PreWindow(commandData.Application.Application);
            window.Show();
           return Result.Succeeded;
        }
    }
}

界面的XMAL

<Window x:Class="插件2.PreWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:插件2"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="400">
    <Grid Name="grid">
        
    </Grid>
</Window>

界面後臺

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace 插件2
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class PreWindow : Window
    {
        UIApplication uiapp = null;
        Autodesk.Revit.ApplicationServices.Application app = null;
        Document doc = null;
        public PreWindow()
        {
            InitializeComponent();
        }
        public PreWindow(Autodesk.Revit.ApplicationServices.Application app)
        {
            InitializeComponent();
            this.app = app;
            uiapp = new UIApplication(this.app);
            this.doc = uiapp.ActiveUIDocument.Document;
            PreviewControl preview = new PreviewControl(doc, doc.ActiveView.Id);
            this.grid.Children.Add(preview);
        }

    }
}

效果如下:

在這裏插入圖片描述

11 對元素的基本操作

Revit中可以通過API對元素進行復制,移動,旋轉,鏡像等基本操作。這些功能都可以通過ElementTransformUtils類來實現,下面是簡單的示例

using System;
using System.Collections.Generic;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
using System.Threading;
namespace 插件
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.UsingCommandData)]
    public class Command : IExternalCommand
    {
        public readonly double unit = 304.8;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
        {
            UIApplication uiapp = new UIApplication(commandData.Application.Application);
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection selection = uidoc.Selection;

            #region 移動
            TaskDialog.Show("Move", "下面請選擇一個牆體,這個牆體將會向右移動1000mm");
            Wall wall = doc.GetElement(selection.PickObject(ObjectType.Element)) as Wall;
            using (Transaction ts = new Transaction(doc, "Move"))
            {
                ts.Start();
                ElementTransformUtils.MoveElement(doc, wall.Id, new XYZ(1000 / unit, 0, 0));
                ts.Commit();
            }
            #endregion

            #region 複製
            TaskDialog.Show("Copy", "選擇一個牆體,這個牆體上方1000mm處複製一個新的牆體");
            Wall wall1 = doc.GetElement(selection.PickObject(ObjectType.Element)) as Wall;
            using (Transaction ts = new Transaction(doc, "Copy"))
            {
                ts.Start();
                ElementTransformUtils.CopyElement(doc, wall1.Id, new XYZ(0, 1000 / 304.8, 0));
                ts.Commit();
            }
            #endregion

            #region 旋轉
            TaskDialog.Show("Rotate", "選擇一個牆體,將會把這個牆體順時針旋轉45度");
            Wall wall2 = doc.GetElement(selection.PickObject(ObjectType.Element)) as Wall;
            using (Transaction ts = new Transaction(doc, "Rotate"))
            {
                ts.Start();
                XYZ pt1 = ((wall2.Location as LocationCurve).Curve as Line).GetEndPoint(0);
                Line line = Line.CreateBound(new XYZ(pt1.X, pt1.Y, 0), pt1);
                ElementTransformUtils.RotateElement(doc, wall2.Id, line, 45);
                ts.Commit();
            }
            #endregion


            #region 鏡像
            TaskDialog.Show("Mirror", "選擇一個牆體,再點擊兩個點,將會把這個牆體以兩個點連成的直線爲軸鏡像一個新的牆體");
            Wall wall3 = doc.GetElement(selection.PickObject(ObjectType.Element)) as Wall;
            using (Transaction ts = new Transaction(doc, "Mirror"))
            {
                ts.Start();
                XYZ pt1 = selection.PickPoint("請選擇鏡像軸的第一個端點");
                XYZ pt2 = selection.PickPoint("請選擇鏡像軸的第二個端點");
                XYZ origin = (pt1 + pt2)/2;
                XYZ pt3 = new XYZ(origin.X, origin.Y, origin.Z + 100);
                Plane plane = Plane.CreateByThreePoints(pt1, pt2, pt3);
                ElementTransformUtils.MirrorElement(doc, wall3.Id, plane);
                ts.Commit();
            }
            #endregion




            return Result.Succeeded;
        }



    }
}

持續更新

參考博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章