У меня есть стекло шторной панели (показано ниже) с набором вертикальных и горизонтальных линий в качестве опорных плоскостей, которые следует использовать для привязки специального оборудования к пересечениям, чтобы оно было правильно размещено.
Прямо сейчас специальное оборудование размещается с помощью плагина, который мы разрабатываем, вызывая Document.Create.NewFamilyInstance
, и его позиция определяется лицевой стороной стены, выбранной пользователем с помощью UIDocument.Selection.PickObject
. Однако мне нужно добавить эти контрольные строки в код, чтобы я мог разместить специальное оборудование точно на самом близком пересечении с тем местом, которое выбрал пользователь.
Я знаю, что эти эталонные плоскости будут отображаться только в виде высоты, и это то, что я использую при поиске этих объектов в коде, назначая options.View = _document.Document.ActiveView;
и вызывая API в виде высоты, но самое близкое, что я мог бы найти, рабочим решением является приведенный ниже код, и проблема в том, что я мог получить только строки (я знаю, что это те, которые составляют опорные плоскости из-за их положения), но я не могу найти способ преобразовать их в фактические экземпляры ReferencePlane для использования при вызове NewFamilyInstance.
Это возможно? Если нет, как я могу убедиться, что специальное оборудование привязано к закрытой ссылке, которую оно находит?
void FindReferencePlances(ElementId elementId)
{
var fi = _docMan.Document.GetElement(elementId) as FamilyInstance;
var transforms = fi.GetTransform();
string data = string.Empty;
Options options = new Options();
options.IncludeNonVisibleObjects = true;
options.ComputeReferences = true;
options.View = _docMan.Document.ActiveView;
var r = fi.GetFamilyPointPlacementReferences();
foreach (GeometryObject go in
fi.get_Geometry(options))
{
data += " - " +go.GetType().ToString()
+ Environment.NewLine;
if (go is GeometryInstance)
{
GeometryInstance gi = go as GeometryInstance;
foreach (GeometryObject goSymbol in
gi.GetSymbolGeometry())
{
data += " -- " + goSymbol.GetType().ToString()
+ Environment.NewLine;
if (goSymbol is Line)
{
Line line = goSymbol as Line;
data += " --- " + line.GetType().ToString() + " (" + line.Origin.ToString() + ")";
}
}
}
}
TaskDialog.Show("data", data);
}
Обновление: Не уверен, что это правильный способ сделать это, но я нашел способ получить все точки пересечения из линий базовой плоскости, чтобы я мог расположить свой объект рядом с ближайшей точкой. Приведенный ниже код не удаляет дубликаты.
public static List<XYZ> FindInstersectionsInReferencePlane(Document doc, ElementId elementId)
{
var fi = doc.GetElement(elementId) as FamilyInstance;
var transforms = fi.GetTransform();
string data = string.Empty;
Options options = new Options();
options.IncludeNonVisibleObjects = true;
options.ComputeReferences = true;
options.View = doc.Document.ActiveView;
var lines = fi.get_Geometry(options)
.Select(x => x as GeometryInstance)
.SelectMany(x => x.GetSymbolGeometry().ToList())
.OfType<Line>()
.ToList();
var results = new List<Tuple<Line, Line, IntersectionResultArray>>();
foreach (var l1 in lines)
{
foreach (var l2 in lines)
{
IntersectionResultArray r = null;
if (l1.Intersect(l2, out r) == SetComparisonResult.Overlap)
results.Add(Tuple.Create(l1, l2, r));
}
}
var points = new List<XYZ>();
foreach (var result in results)
{
foreach (IntersectionResult res in result.Item3)
{
points.Add(res.XYZPoint);
}
}
return points;
}