我有一个窗帘面板玻璃(如下所示),有一堆垂直和水平线作为参考平面,应该用来将专业设备捕捉到交叉点,以便正确放置它们。
目前,专业设备正在通过我们正在开发的插件放置Document.Create.NewFamilyInstance
,它的位置来自用户选择的墙壁表面UIDocument.Selection.PickObject
。但是,我需要在代码中获取这些参考线,以便我可以将专业设备准确地放置在离用户选择最近的交叉点处。
我知道这些参考平面只会显示在 Elevation 视图中,这就是我在代码中通过options.View = _document.Document.ActiveView;
在 Elevation 视图中分配和调用 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;
}