文章目錄
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)獲取到GeometryElement
- 再從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
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;
}
}
}
持續更新