1. 程式人生 > >Revit二次開發第三回:模型線的建立與偏移

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,以後還需多多光顧才是。