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,以后还需多多光顾才是。

猜你喜欢

转载自blog.csdn.net/niaxiapia/article/details/80376279