功能大概就是检测项目中的元素(包括链接文件中的构件)是否冲突
大致思路:
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>();
}
}
-------------------------------------------
代码给个参考,不能直接运行。