Revit二次開發第三回:模型線的建立與偏移
對於模型線ModelCurve的偏移,研究了好幾天,終於搞定。先稍微談下自己中間遇到的情況。
1.首先,API中並沒有提供直接的方法對ModelCurve進行偏移;
2.考慮到模型線的建立,需要用到引數Curve,因此想到了對先Curve進行偏移,API提供了相應的方法:Curve.CreatOffset
3.對Curve偏移過後,發現對應的模型線並未改變。然後才發現,需要對modelCurve.GeometryCurve重新賦值才行。
4.其中有個細節,在本例中為什麼先建立了模型線,然後再進行偏移,而不是建立和偏移一步到位?我做了測試,效果明顯不同。
如果是建立和偏移同時進行,即沒有預先做好模型線,那偏移完後的線是散開的,或者是交叉的;
而如果先建立了模型線,(本例中,先建立了封閉一圈的牆,然後根據牆基線建立的模型線),此時模型線自動形成封閉圖形,各自已有關聯性。然後再對Curve進行偏移,對GeometryCurve進行修改,各自的ModelCurve還是會繼續關聯。不過也正是因為關聯性,所以會引出新的問題:同一條線上,有3個Curve,偏移了一根,其他兩根也會跟著動,那遍歷的時候怎麼辦?會自動偏移三次。比如想偏移500mm,實際結果卻是500*3=1500mm。
5.偏移命令中有一個引數,XYZ normal,研究了好半天,才終於搞明白如何運用:
簡單來說,通常我們的Curve都是在XY平面中進行操作,因此XYZ可以直接取值(0,0,1),也就是Z軸方向。其實所謂的偏移方向由兩個向量的叉乘得來,即偏移方向=Curve方向 叉乘 參考向量normal方向。(右手螺旋法則:大拇指指向為偏移後線的方向)
設想一下,XY平面內的Curve,如何在叉乘一個參考向量後,還在XY平面內呢?顯然這個參考向量必須是垂直於XY平面的,那我們就直接取Z軸方向(0,0,1)即可。附圖作為參考,白線為XY平面內的Curve,紅線為偏移後的狀態,綠線為Z軸
下面上一段程式碼,對REVIT中的模型,拾取其牆列表,然後獲得牆的基線,最後根據基線,建立模型線,並對其進行偏移。
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
//獲取牆List
FilteredElementCollector wallCollector = new FilteredElementCollector(doc);
List<Wall> wallList=
wallCollector.OfCategory(BuiltInCategory.OST_Walls).OfClass(typeof(Wall)).
ToList().ConvertAll(x=>x as Wall);
//獲取牆的基線List
ElementId wallLevelID = null;
List<Curve> curveList = new List<Curve>();
foreach(Wall wall in wallList)
{
Curve wallCurve = (wall.Location as LocationCurve).Curve;
curveList.Add(wallCurve);
wallLevelID = wall.LevelId;
}
//建立模型線
List<ModelCurve> modelCurveList = new List<ModelCurve>();
foreach(var curve in curveList)
{
Transaction ts1 = new Transaction(doc, "info");
ts1.Start();
SketchPlane sktchPlane = SketchPlane.Create(doc, wallLevelID);
ModelCurve modelCurve = doc.Create.NewModelCurve(curve,sktchPlane);
ts1.Commit();
modelCurveList.Add(modelCurve);
}
//對modelCurve進行偏移。modelCurve.GeometryCurve是可讀可寫的,一定要注意
//另外,還需注意要對modelCurve.GeometryCurve重新進行賦值。
//此處只是對CUVve進行了偏移,而沒重新建立模型線
//而如果,先對Curve進行偏移,再生成模型線呢?==>試過了,這樣就沒有關聯性。
foreach (var modelCurve in modelCurveList)
{
Transaction ts1 = new Transaction(doc, "info");
ts1.Start();
//下面這行一定要注意,如果只寫curve.CreateOffset(500 / 304.8, new XYZ(0,0,1));
//是沒有變化的,只是使用了方法,但是並沒有給curve重新賦值。
modelCurve.GeometryCurve=
modelCurve.GeometryCurve.CreateOffset(500 / 304.5, new XYZ(0, 0, 1));
ts1.Commit();
}
return Result.Succeeded;
之前有個誤區,想改變ModelCurve,就想的改變對應的Curve就行,其實沒問題。不過並沒有想到直接對GeometryCurve進行修改(可讀可寫),而且就算想到了,也會忘記重新賦值。
可讀可寫這個思路,來自由葉先生的blog,以後還需多多光顧才是。