边界框相交
Bounding Box intersection
为了查找与几何相交的元素,我使用了 Jeremy 在其博客 http://thebuildingcoder.typepad.com/blog/2010/12/find-intersecting-elements.html 中的示例 post。但是边界框始终平行于 X、Y 和 Z 轴,这可能会导致问题,例如 return 元素并没有真正发生冲突,因为有时边界框并不总是与几何重合,因为族实例被旋转。除此之外,还有一个问题是边界框会考虑符号的几何形状而不是实例,并且也会考虑翻转的几何形状,这意味着边界框比我要找的要大。有没有办法获取当前视图中的真实几何图形?我该如何解决这个问题?
有很多方法可以解决这个问题。一般在做碰撞检测的时候,总会先运行超快的pre-processing步来确定候选元素,然后在后面的步骤中一步步更精确地缩小搜索范围。在这种情况下,您可以先考虑边界框相交,然后再执行 post-processing 以将结果缩小到您的确切目标。
一个重要的问题是:边界框是否真的提供了您需要的所有元素,甚至更多?您确定缺少 none 吗?
一旦确定,您需要做的就是添加 post-processing 步骤,应用您关心的详细注意事项。
一个简单的可能是:目标体积中是否包含所有目标元素几何体顶点?
更复杂的方法可能涉及检索目标元素和目标体积的完整实体,并在它们之间执行布尔交集,以完全准确地确定它们是否相交、分离或包含在彼此中。
还有很多其他的可以想象。
能否提供一个 complete minimal reproducible case 以便我们了解确切的上下文并分析可以做什么?或许您可以包括一个 axis-aligned 接线盒和一个不包括的接线盒,这样我们就可以了解您现有算法的执行情况。谢谢!
我正在使用另一种策略,即访问实例的几何形状来验证族实例的面是否与更近的管道发生冲突。
class FindIntersection
{
public Conduit ConduitRun { get; set; }
public FamilyInstance Jbox { get; set; }
public List<Conduit> GetListOfConduits = new List<Conduit>();
public FindIntersection(FamilyInstance jbox, UIDocument uiDoc)
{
XYZ jboxPoint = (jbox.Location as LocationPoint).Point;
FilteredElementCollector filteredCloserConduits = new FilteredElementCollector(uiDoc.Document);
List<Element> listOfCloserConduit = filteredCloserConduits.OfClass(typeof(Conduit)).ToList().Where(x =>
((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(0).DistanceTo(jboxPoint) < 30 ||
((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(1).DistanceTo(jboxPoint) < 30).ToList();
//getting the location of the box and all conduit around.
Options opt = new Options();
opt.View = uiDoc.ActiveView;
GeometryElement geoEle = jbox.get_Geometry(opt);
//getting the geometry of the element to acess the geometry of the instance.
foreach (GeometryObject geomObje1 in geoEle)
{
GeometryElement geoInstance = (geomObje1 as GeometryInstance).GetInstanceGeometry();
//the geometry of the family instance can be acess by this method that returns a GeometryElement type.
//so we must get the GeometryObject again to acess the Face of the family instance.
if (geoInstance != null)
{
foreach (GeometryObject geomObje2 in geoInstance)
{
Solid geoSolid = geomObje2 as Solid;
if (geoSolid != null)
{
foreach (Face face in geoSolid.Faces)
{
foreach (Element cond in listOfCloserConduit)
{
Conduit con = cond as Conduit;
Curve conCurve = (con.Location as LocationCurve).Curve;
SetComparisonResult set = face.Intersect(conCurve);
if (set.ToString() == "Overlap")
{
//getting the conduit the intersect the box.
GetListOfConduits.Add(con);
}
}
}
}
}
}
}
}
}
我在 filtering for intersecting elements and conduits intersecting a junction box 上的博客 post 中总结了这次讨论和迄今为止的结果。
为了查找与几何相交的元素,我使用了 Jeremy 在其博客 http://thebuildingcoder.typepad.com/blog/2010/12/find-intersecting-elements.html 中的示例 post。但是边界框始终平行于 X、Y 和 Z 轴,这可能会导致问题,例如 return 元素并没有真正发生冲突,因为有时边界框并不总是与几何重合,因为族实例被旋转。除此之外,还有一个问题是边界框会考虑符号的几何形状而不是实例,并且也会考虑翻转的几何形状,这意味着边界框比我要找的要大。有没有办法获取当前视图中的真实几何图形?我该如何解决这个问题?
有很多方法可以解决这个问题。一般在做碰撞检测的时候,总会先运行超快的pre-processing步来确定候选元素,然后在后面的步骤中一步步更精确地缩小搜索范围。在这种情况下,您可以先考虑边界框相交,然后再执行 post-processing 以将结果缩小到您的确切目标。
一个重要的问题是:边界框是否真的提供了您需要的所有元素,甚至更多?您确定缺少 none 吗?
一旦确定,您需要做的就是添加 post-processing 步骤,应用您关心的详细注意事项。
一个简单的可能是:目标体积中是否包含所有目标元素几何体顶点?
更复杂的方法可能涉及检索目标元素和目标体积的完整实体,并在它们之间执行布尔交集,以完全准确地确定它们是否相交、分离或包含在彼此中。
还有很多其他的可以想象。
能否提供一个 complete minimal reproducible case 以便我们了解确切的上下文并分析可以做什么?或许您可以包括一个 axis-aligned 接线盒和一个不包括的接线盒,这样我们就可以了解您现有算法的执行情况。谢谢!
我正在使用另一种策略,即访问实例的几何形状来验证族实例的面是否与更近的管道发生冲突。
class FindIntersection
{
public Conduit ConduitRun { get; set; }
public FamilyInstance Jbox { get; set; }
public List<Conduit> GetListOfConduits = new List<Conduit>();
public FindIntersection(FamilyInstance jbox, UIDocument uiDoc)
{
XYZ jboxPoint = (jbox.Location as LocationPoint).Point;
FilteredElementCollector filteredCloserConduits = new FilteredElementCollector(uiDoc.Document);
List<Element> listOfCloserConduit = filteredCloserConduits.OfClass(typeof(Conduit)).ToList().Where(x =>
((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(0).DistanceTo(jboxPoint) < 30 ||
((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(1).DistanceTo(jboxPoint) < 30).ToList();
//getting the location of the box and all conduit around.
Options opt = new Options();
opt.View = uiDoc.ActiveView;
GeometryElement geoEle = jbox.get_Geometry(opt);
//getting the geometry of the element to acess the geometry of the instance.
foreach (GeometryObject geomObje1 in geoEle)
{
GeometryElement geoInstance = (geomObje1 as GeometryInstance).GetInstanceGeometry();
//the geometry of the family instance can be acess by this method that returns a GeometryElement type.
//so we must get the GeometryObject again to acess the Face of the family instance.
if (geoInstance != null)
{
foreach (GeometryObject geomObje2 in geoInstance)
{
Solid geoSolid = geomObje2 as Solid;
if (geoSolid != null)
{
foreach (Face face in geoSolid.Faces)
{
foreach (Element cond in listOfCloserConduit)
{
Conduit con = cond as Conduit;
Curve conCurve = (con.Location as LocationCurve).Curve;
SetComparisonResult set = face.Intersect(conCurve);
if (set.ToString() == "Overlap")
{
//getting the conduit the intersect the box.
GetListOfConduits.Add(con);
}
}
}
}
}
}
}
}
}
我在 filtering for intersecting elements and conduits intersecting a junction box 上的博客 post 中总结了这次讨论和迄今为止的结果。