Revit二次开发---链接文件碰撞检测

功能大概就是检测项目中的元素(包括链接文件中的构件)是否冲突

大致思路:

1、先获取到链接文件中所有构件转换后的solid,转化后的solid就可以直接和项目中的元素做检测了

2、获取要对比的元素所有边、面、solid

3、如果元素有边:用边和solid做检测,如没检测到还需面和边做检测;   如果元素没有边:用面和面做检测

----------------------------------------------------------------------

过滤链接文件内部构件

//key:链接文件id   value:内部构件id
Dictionary<ElementId,List<ElementId>> m_dicLinkIns;
//过滤链接文件
FilteredElementCollector fecLinks = new FilteredElementCollector(doc);
List<Element> lstElem = fecLinks.ofClass(typeof(RevitLinkInstance)).ToElements().ToList();
//过滤内部构件
foreach(Element elem in lstElem)
{
    RevitLinkInstance rvtLinkIns = elem as RevitLinkInstance;
    if(rvtLinkIns == null) continue;
    //得到链接文件文档
    Document linkDoc = rvtLinkIns.GetLinkDocument();
    if(linkDoc == null) continue;
    FilteredElementCollector fecLinkElems = new FilteredElementCollector;
    ElementClassFilter insFilter = new ElementClassFilter (typeof(FamilyInstance));
    ElementClassFilter hostFilter = new ElementClassFilter (typeof(HostObject));
    LogicalOrFilter filter = new LogicalOrFilter (insFilter,hostFilter);
    List<ElementId> lstEids = fecLinkElems.WherePasses(filter).ToElementIds().ToList();
    m_dicLinkIns.Add(rvtLinkIns.id,lstEids);
}

将链接文件中构件solid进行转换,并获取面、边

List<SolidModel> m_lstModels;
private void TransformSolid(Document doc,Element elem)
{
    ElementId linkId = null;
    RevitLinkInstance rvtLinkIns = null;
    if(elem.Document.IsLinked)
    {//如果是链接文档的构件,需找到对应链接文件
        foreach(Elementid eid in m_dicLinkIns.Keys)
        {
            if(m_dicLinkIns[eid].Contains(elem.Id))
            {
                rvtLinkIns = doc.GetElement(eid) as RevitLinkInstance;
                break;
            }
        }
    }
    List<Solid> lstSolids = GetSolids(elem);
    foreach(Solid solid in lstSolids)
    {
        Solid tempSolid = solid;
        if(rvtLinkIns != null)//生成一个转换后的solid
            tempSolid = SolidUtils.CreateTransformed(solid,rvtLinkIns.GetTransform());
        m_lstModels.lstSolids.Add(tempSolid);
        foreach(Face face in tempSolid.Faces)
        {//获取面
            m_lstModels.lstFaces.Add(face);
        }
        foreach(Edge edge in tempSolid.Edges)
        {//获取边
            Curve curve = edge.AsCurve();
            m_lstModels.lstEdges.Add(curve);
        }
    }
}

如果不知道如何获取元素Solid,可以去网上查查,也可以看下我的另一篇文章内容里有写。在链接内容底部

进行碰撞检测,两种情况

1.实体有边,用实体和边去测,没检测到再用面和边去测;

foreach(Curve curve in rightModel.lstEdges)
{
    foreach(Solid solid in leftModel.lstSolids)
    {
        SolidCurveIntersectionoPtions opt = new SolidCurveIntersectionoPtions();
        //solid与边做检测
        SolidCurveIntersection result = solid.IntersectWithCurve(curve,opt);
        if(result.SegmentCount > 0)
        {
            //碰撞了
        }
        else
        {
            foreach(Face face in solid.Faces)
            {
                IntersectionResultArray array = null;
                //solid的面与边做检测
                SetComparisonResult result2 = face.Intersect(curve,out array);
                if(array != null && result2 != SetComparisonResult.Disjoint)
                {
                    //碰撞了
                }
            }
        }
    }
}

 

2.实体没有边,用面与面做检测

foreach(Face rface in rightModel.lstFaces)
{
    foreach(Face lface in leftModel.lstFaces)
    {
        Curve curve = null;
        FaceIntersectionFaceResult result = lface.Intersect(rface, out curve);
        if(result == FaceIntersectionFaceResult.Intersecting)
        {
            //碰撞了
        }
    }
}

SolidModel类

public class SolidModel
{
    //元素id
    public ElementId id {get;set;}
    //元素实体
    public List<Solid> lstSolids {get;set;}
    //元素边
    public List<Curve> lstEdges {get;set;}
    //元素面
    public List<Face> lstFaces {get;set;}

    public SolidModel()
    {
        lstSolids =new List<Solid>();
        lstEdges =new List<Curve>();
        lstFaces =new List<Face>();
    }
}

-------------------------------------------

代码给个参考,不能直接运行。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿呦嘿呦嘿呦嘿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值