当前位置:网站首页>Revit secondary development - collision detection

Revit secondary development - collision detection

2022-07-07 22:22:00 Hey, hey, hey, hey, hey

Make a note of , It's easy to write This is the core code .

Not measured carefully , Anyway, the current detection is and rvt The self-contained collision detection results are the same .

List<ElementId> left;// Elements to detect collisions id
List<ElementId> right;// Elements to detect collisions id
string sResult="";
foreach(ElementId eid left)
{
    Element elem = doc.GetElement(eid);
    FilteredElementCollector collector = new FilteredElementCollector(doc,right);// Create collector , Specify the collection range 
    ElementIntersectsElementFilter filter = new ElementIntersectsElementFilter(elem);// use API Filter intersecting elements 
    List<Element> lstElem = collector.WherePasses(filter).ToElements().ToList();
    if(lstElem.Count > 0)
    {
        foreach(Element collision_elem lstElem)
        {
            sInfo += elem.Name+" Id:"+elem.Id+" ----- "+collision_elem.Name+" Id:"+collision_elem.Id +"\n";
        }
        // Handle two sets with the same id when , Prevent duplicate detection 
        if(right.Contains(eid))
            right.Remove(eid);
    }
}
TaskDialog.Show("result",sInfo);

Pure hand tap , May be wrong , You can modify or reply by yourself .

----------- to update ---------------

If you test a large model ,List<Element> lstElem = collector.WherePasses(filter).ToElements().ToList();   

Running this code will be very time-consuming , The interface appears to be suspended . Want to display the detection progress through the progress bar , Make the interface better .

It won't work in this way , Because I can't get the progress of detection ( I wonder if you can get it ?)

The same problem is also encountered in online query , And give the solution :

1. use boundingboxIntersectFilter and boundingboxIsInsideFilter Quickly filter out collision elements ( These two belong to the fast filter ), But the filtered elements will be inaccurate , We want to delete the included but disjoint elements from the set .

2. use ElementIntersectsSolidFilter( Slow filter ) Confirm whether there is a real collision

List<ElementId> left;
List<ElementId> right;
List<ElementId> realEids;// Real collision id
// Record key  And which elements have been detected 
Dictionary<ElementId,List<ElementId>> m_dicCheck;
int iCount = 0;// Quickly filtered id total 
foreach(ElementId eid left)
{// This cycle can display the overall progress of the test 
    // Prevent duplicate detection 
    List<ElementId> temp = right;
    if(m_dicCheck.Count > 0)
    {
        foreach(ElementId id in m_dicCheck.Keys)
        {
            if(m_dicCheck[id].Contains(eid))
                temp.Remove(id);
        }
        m_dicCheck.Add(eid,temp);
    }
    else
    {
        m_dicCheck.Add(eid,temp);
    }
    Element elem = doc.GetElement(eid);
    BoundingBoxXYZ boxXYZ = elem.get_BoundingBox(doc.ActiveView);
    Outline ol = new Outline(boxXYZ.Min,boxXYZ.Max);
    BoundingBoxIntersectsFilter boxIntersectsFilter = new BoundingBoxIntersectsFilter(ol);
    BoundingBoxIsInsideFilter boxIsInsideFilter = new BoundingBoxIsInsideFilter(ol);
    LogicalOrFilter filter = new LogicalOrFilter(boxIntersectsFilter,boxIsInsideFilter);
    FilteredElememntCollector collector = new FilteredElememntCollector(doc,temp);
    // Use a quick filter to get all intersections / Contained elements , And remove the duplicate in the set id
    List<ElementId> lstEid = collector.WherePasses(filter).ToElementIds().Distinct().ToList();
    // Remove the detection element itself 
    lstEid = lstEid.Where(e=>e != eid).ToList();
    iCount = lstEid.Count;
    // Get all of the currently detected elements solid
    List<Solid> lstSolid = GetElementSolid(elem);
    if(lstSolid.Count == 0)
        continue;
    // Then it is a cycle to judge whether the collision is real 
    foreach(Solid solid lstSolid)
    {// This loop can show the progress of individual element detection 
        FilteredElementCollector collisionCollector = new FilteredElementCollector(doc,lstEid);
        ElementIntersectsSolidFilter collisionFilter = new ElementIntersectsSolidFilter(solid);
        List<ElementId> Ids = collisionCollector.WherePasses(collisionFilter).ToElementIds().ToList();
        // Release the filter and collector , Otherwise, creating too many will overflow memory 
        collisionCollector.Dispose();
        collisionFilter.Dispose();
        if(Ids.Count > 0)
        {
            realEids.AddRange(Ids);
            if(tempEids.Count == iCount)
                break;
            // Will filter out id from lstEid Delete... From the collection , Narrow the detection range 
            foreach(ElementId itemId Ids)
            {
                if(lstEid.Contains(itemId)) lstEid.Remove(itemId);
            }
        }
    }
    //
    // Real collision elements id ad locum realEids,  Perform the operation on the result here 
    //
    realEids.Clear();
}

obtain Element Entity of Solid

private List<Solid> GetElementSolid(Element elem)
{
    List<Solid> lstSolid = new List<Solid>();
    Options opt = new Option();
    opt.ComputeReferences = true;
    opt.IncludeNonVisbleObjects = true;
    GeometryElement ge = element.get_Geomtry(opt);
    if(ge != null)
        lstSolid.AddRange(GetSolid(ge));
    return lstSolid;
}
private List<Solid> GetSolid(GeometryElement ge)
{
    List lstSolid = new List<Solid>();
    foreach(GeomtryObject go in ge)
    {
        if(go is Solid)
        {
            Solid solid = go as Solid;
            if(solid.SurfaceArea > 0 && solid.Volume > 0 && solid.Faces.Size > 1 && solid.Edges.Size > 1)
                lstSolid.Add(solid);
        }
        else if(go is GeometryInstance)
        {
            GeomtryElement ge = (go as GeometryInstance).GetInstanceGeometry();
            lstSolid.AddRange(GetSolid(ge));            
        }
    }
    return lstSolid;
}

Hand tapping , Correct or reply yourself if there is an error .

原网站

版权声明
本文为[Hey, hey, hey, hey, hey]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130606207393.html