这段时间一直在忙项目,加上过年休息了一段时间,重新接触代码的时候竟感到有点陌生,思绪也有点乱,看来状态还是要慢慢调整回来呀。
因为软件及协同方式的原因,Revit相对Cad来说会更容易出现误删除元素的情况,这段时间做项目的时候出现了两次电气末端点位误删除或误修改的情况,所以想通过二次开发来对这些点位进行检查,降低项目的审核成本。
思路其实很简单,首先在第一次点位确定后,读取点位的ID与位置信息,用文件将这些信息进行储存。然后当要审核点位的时候,重新读取点位ID与位置信息,将这些信息与储存的信息进行匹配,过滤出哪些点位被调整,最后提示用户即可。
以下关键代码:
储存关键信息:
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document doc = commandData.Application.ActiveUIDocument.Document;
List<string> keyDatas = new List<string>();
foreach(Element elem in CheckETool.GetEElement(doc))
{
//族与类型
Parameter parameter = elem.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM);
//位置信息
LocationPoint locationPoint = elem.Location as LocationPoint;
if (locationPoint != null)
{
//导出关键信息
CheckETool cet = new CheckETool();
cet.InputXML(@"C:UsersimfourDesktop测试文件夹KeyData.xml", elem.Id.IntegerValue, parameter.AsValueString(), locationPoint.Point.ToString(), locationPoint.Rotation.ToString());
}
else
{
//线性路径
//to do
}
}
return Result.Succeeded;
}
检查信息:
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document doc = commandData.Application.ActiveUIDocument.Document;
//List<Element> newElems = new List<Element>();
//List<Element> modElems = new List<Element>();
List<string> newElems = new List<string>();
List<string> modElems = new List<string>();
List<string> delElems = new List<string>();
CheckETool cet = new CheckETool();
//判断新元素及被调整的元素
foreach (Element elem in CheckETool.GetEElement(doc))
{
int status = cet.CheckElement(@"C:UsersimfourDesktop测试文件夹KeyData.xml", elem);
if (status == 0)
{
string info = elem.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString() + ",id" + elem.Id.ToString();
newElems.Add(info);
}
if (status == 1)
{
string info = elem.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString() + ",id" + elem.Id.ToString();
modElems.Add(info);
}
}
//判断被删除元素
cet.GetDeletedElement(@"C:UsersimfourDesktop测试文件夹KeyData.xml", doc, ref delElems);
if (newElems.Count == 0 && modElems.Count == 0 && delElems.Count == 0)
{
TaskDialog.Show("task", "检测已完成,点位无问题");
}
else
{
StreamWriter streamWriter = new StreamWriter(@"C:UsersimfourDesktop测试文件夹result.txt", false, Encoding.Default);
if (newElems.Count > 0)
{
streamWriter.WriteLine("==================================================");
streamWriter.WriteLine("检测到" + newElems.Count + "个新点位:");
foreach(string str in newElems)
{
streamWriter.WriteLine(str);
}
}
if (modElems.Count > 0)
{
streamWriter.WriteLine("==================================================");
streamWriter.WriteLine("检测到" + modElems.Count + "个点位被修改:");
foreach (string str in modElems)
{
streamWriter.WriteLine(str);
}
}
if (delElems.Count > 0)
{
streamWriter.WriteLine("==================================================");
streamWriter.WriteLine("检测到" + delElems.Count + "个点位被删除:");
foreach (string str in delElems)
{
streamWriter.WriteLine(str);
}
}
streamWriter.Close();
}
return Result.Succeeded;
}
用到的方法:
class CheckETool
{
public static IList<Element>GetEElement(Document document)
{
FilteredElementCollector fec = new FilteredElementCollector(document);
//过滤器
List<ElementFilter> elementFilters = new List<ElementFilter>();
BuiltInCategory[] builtInCategories = {
BuiltInCategory.OST_ElectricalFixtures,//电气装置
BuiltInCategory.OST_ElectricalEquipment,//电气设备
BuiltInCategory.OST_FireAlarmDevices,//火警装置
BuiltInCategory.OST_NurseCallDevices,//护理呼叫装置
BuiltInCategory.OST_DataDevices,//数据装置
BuiltInCategory.OST_LightingDevices,//照明装置
BuiltInCategory.OST_LightingFixtures,//灯具
BuiltInCategory.OST_TelephoneDevices,//电话装置
BuiltInCategory.OST_CommunicationDevices,//通讯装置
BuiltInCategory.OST_Sprinklers,//喷头
BuiltInCategory.OST_PlumbingFixtures//卫浴装置
};
foreach (var BIC in builtInCategories)
{
ElementFilter ef = new ElementCategoryFilter(BIC);
elementFilters.Add(ef);
}
LogicalOrFilter filter = new LogicalOrFilter(elementFilters);
return fec.WherePasses(filter).WhereElementIsNotElementType().ToElements();
}
public void InputXML(string fileFullName, int id, string familyAndTypeName, string locationPoint, string locationRotation)
{
XmlDocument xmlDoc = new XmlDocument();
//如文件存在则检索节点并删除
if (File.Exists(fileFullName))
{
xmlDoc.Load(fileFullName);
var tNote = xmlDoc.DocumentElement.SelectSingleNode("id" + id.ToString());
if (tNote != null)
{
xmlDoc.DocumentElement.RemoveChild(tNote);
}
}
else
{
XmlDeclaration xmlDec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
//根节点
XmlElement root = xmlDoc.CreateElement("ERoot");
xmlDoc.AppendChild(xmlDec);
xmlDoc.AppendChild(root);
}
XmlElement idNote = xmlDoc.CreateElement("id" + id.ToString());
xmlDoc.DocumentElement.AppendChild(idNote);
XmlElement familyAndTypeNameNote = xmlDoc.CreateElement("FamilyAndTypeName");
familyAndTypeNameNote.InnerText = familyAndTypeName;
idNote.AppendChild(familyAndTypeNameNote);
XmlElement locationPointNote = xmlDoc.CreateElement("LocationPoint");
locationPointNote.InnerText = locationPoint;
idNote.AppendChild(locationPointNote);
XmlElement locationRotationNote = xmlDoc.CreateElement("LocationRotation");
locationRotationNote.InnerText = locationRotation;
idNote.AppendChild(locationRotationNote);
xmlDoc.Save(fileFullName);
}
/// <summary>
/// "-1:查找失败"
/// "0:未记录此元素"
/// "1:元素位置被调整"
/// "2:元素位置符合记录"
/// </summary>
/// <param name="fileFullName"></param>
/// <param name="element"></param>
/// <returns></returns>
public int CheckElement(string fileFullName, Element element)
{
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(fileFullName))
{
xmlDoc.Load(fileFullName);
string sID = "id" + element.Id.IntegerValue;
var tNote = xmlDoc.DocumentElement.SelectSingleNode(sID);
if (tNote != null)
{
LocationPoint locationPoint = element.Location as LocationPoint;
//判断location
if (locationPoint.Point.ToString() == tNote.SelectSingleNode("LocationPoint").InnerText && locationPoint.Rotation.ToString() == tNote.SelectSingleNode("LocationRotation").InnerText)
{
return 2;
}
else
{
return 1;
}
}
else
{
return 0;
}
}
else
{
//TaskDialog.Show("Error","未有配置文件");
}
return -1;
}
public List<string> GetDeletedElement(string fileFullName, Document document,ref List<string>deletedElems)
{
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(fileFullName))
{
xmlDoc.Load(fileFullName);
foreach (XmlElement note in xmlDoc.DocumentElement.ChildNodes)
{
ElementId elementId = new ElementId(Convert.ToInt32(note.Name.Replace("id", "")));
if(document.GetElement(elementId) == null)
{
string info = note.SelectSingleNode("FamilyAndTypeName").InnerText + "," + note.Name;
deletedElems.Add(info);
}
}
}
return deletedElems;
}
}
测试效果:
这次只做了一个简单的尝试,实际编写的时候发现还有许多地方是值得深化的,例如返回结果其实可以做成一个窗口,并和模型元素关联,方便直接在模型查看;又或者将结果表达得更详细,表达出具体是怎样的修改等等。而且这个末端点位修改的检测实质就是文档比对,这样一想的话还可以有非常多的其他用处。
微信公众号:xuebim
关注建筑行业BIM发展、研究建筑新技术,汇集建筑前沿信息!
← 微信扫一扫,关注我们+
评论前必须登录!
注册