Что ж... Сам спросил - сам отвечу =)
В RevitAPI каких-либо методов проекции нет. Однако есть
нужная тема у Таммика. Правда у него там ошибка в методе
ProjectOnto - смотрите в комментариях.
Из его поста беру нужные мне методы:
Извините, вам запрещён просмотр содержимого спойлеров.
Теперь в коде плагина, получив нужные мне кривые, я их проецирую на плоскость. Для построения плоскости использую свойство семейства (окна или двери) FacingOrientation:
Plane plane = new Plane(familyInstance.FacingOrientation, new XYZ(0,0,0));
Методы у меня проецируют на плоскость точки. И если для отрезков это не вызовет проблем - там всего две точки (начало и конец), то для дуговых сегментов не подходит. На выручку приходит метод
Curve.Tessellate(), который дуговые сегменты апроксимирует. Остается только соединить полученные точки в новые отрезки (и только отрезки). Это делается тоже легко:
List<Curve> projectedCurves = new List<Curve>();
foreach (Curve curve in curves)
{
XYZ previosPoint = null;
for (var i = 0; i < curve.Tessellate().Count; i++)
{
XYZ xyzProjected = plane.ProjectOnto(curve.Tessellate()[i]);
if (i == 0)
previosPoint = plane.ProjectOnto(xyzProjected);
else
{
projectedCurves.Add(Line.CreateBound(previosPoint, xyzProjected));
previosPoint = xyzProjected;
}
}
}
В итоге получаю нужный мне контур окна, спроецированный на плоскость:
![](https://s17.postimg.org/xv2ke9qkb/Screenshot_16.png)
Для тех, у кого вдруг возник вопрос "Зачем это нужно?" - дело в том, что дальше я кривые собираю в CurveLoop и используя метод
ExporterIFCUtils.ComputeAreaOfCurveLoops() считаю площадь. Однако, в ходе тестов, выяснилось, что метод возвращает 0.0, если CurveLoop не лежит в одной плоскости. В справке этого не написано, к сожалению, хотя это логичное поведение