Revit API根据链接文件开洞
开洞信息数据:
start
url:http://greatverve.cnblogs.com/p/revit-api-opening-info.html
<?xml version="1.0" encoding="utf-8"?>
<Openings>
<Opening WallId="618644">
<PT1 X="-46.4673223917839" Y="25.9434404529416" Z="9.8753280839895" />
<PT2 X="-46.4673223917839" Y="24.2374037075347" Z="8.16929133858268" />
</Opening>
<Opening WallId="618699">
<PT1 X="28.3358272145153" Y="24.2374037075345" Z="9.8753280839895" />
<PT2 X="28.3358272145153" Y="25.9434404529413" Z="8.16929133858268" />
</Opening>
<Opening WallId="618722">
<PT1 X="-10.7125018356066" Y="57.0806634229704" Z="9.8753280839895" />
<PT2 X="-12.4185385810134" Y="57.0806634229704" Z="8.16929133858268" />
</Opening>
<Opening WallId="618662">
<PT1 X="-20.8620650191645" Y="-1.31828670826329" Z="9.8753280839895" />
<PT2 X="-19.1560282737577" Y="-1.31828670826329" Z="8.16929133858268" />
</Opening>
</Openings>
<Openings>
<Opening WallId="618644">
<PT1 X="-46.4673223917839" Y="25.9434404529416" Z="9.8753280839895" />
<PT2 X="-46.4673223917839" Y="24.2374037075347" Z="8.16929133858268" />
</Opening>
<Opening WallId="618699">
<PT1 X="28.3358272145153" Y="24.2374037075345" Z="9.8753280839895" />
<PT2 X="28.3358272145153" Y="25.9434404529413" Z="8.16929133858268" />
</Opening>
<Opening WallId="618722">
<PT1 X="-10.7125018356066" Y="57.0806634229704" Z="9.8753280839895" />
<PT2 X="-12.4185385810134" Y="57.0806634229704" Z="8.16929133858268" />
</Opening>
<Opening WallId="618662">
<PT1 X="-20.8620650191645" Y="-1.31828670826329" Z="9.8753280839895" />
<PT2 X="-19.1560282737577" Y="-1.31828670826329" Z="8.16929133858268" />
</Opening>
</Openings>
//根据导出开洞信息开洞
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class cmdOpening : IExternalCommand
{
public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
{
UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
Selection sel = uiDoc.Selection;
Transaction ts = new Transaction(doc, "http://revit.5d6d.com");
ts.Start();
string strPath = @"C:\Users\HongYe\Desktop\OpeningInfo.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(strPath);
foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
{
//;
Wall wall = doc.get_Element(new ElementId(Convert.ToInt32(node.Attributes["WallId"].Value))) as Wall;
XmlNode nodePt1 = node.SelectSingleNode("PT1");
XYZ pt1 = new XYZ(double.Parse(nodePt1.Attributes["X"].Value), double.Parse(nodePt1.Attributes["Y"].Value), double.Parse(nodePt1.Attributes["Z"].Value));
XmlNode nodePt2 = node.SelectSingleNode("PT2");
XYZ pt2 = new XYZ(double.Parse(nodePt2.Attributes["X"].Value), double.Parse(nodePt2.Attributes["Y"].Value), double.Parse(nodePt2.Attributes["Z"].Value));
doc.Create.NewOpening(wall, pt1, pt2);
}
ts.Commit();
return Result.Succeeded;
}
}
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
//导出开洞信息
public class cmd : IExternalCommand
{
/// <summary>
/// 找到链接文档中与风管相交的墙
/// </summary>
/// <param name="doc"></param>
/// <param name="duct"></param>
/// <returns></returns>
public static List<Wall> FindDuctWall(Document doc, Duct duct)
{
List<Wall> listWall = new List<Wall>();
//找到outLine
BoundingBoxXYZ bb = duct.get_BoundingBox(doc.ActiveView);
Outline outline = new Outline(bb.Min, bb.Max);
//
FilteredElementCollector collector = new FilteredElementCollector(doc);
BoundingBoxIntersectsFilter invertFilter = new BoundingBoxIntersectsFilter(outline, false);
IList<Element> noIntersectWalls = collector.OfClass(typeof(Wall)).WherePasses(invertFilter).ToElements();
foreach (Element el in noIntersectWalls)
{
Wall wall = el as Wall;
if (wall != null)
listWall.Add(wall);
}
return listWall;
}
public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
{
UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
UIApplication uiApp = cmdData.Application;
Document doc = uiDoc.Document;
Selection selection = uiDoc.Selection;
try
{
Transaction ts = new Transaction(doc, "http://revit.5d6d.com");
ts.Start();
string strPath = @"C:\Users\HongYe\Desktop\OpeningInfo.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(strPath);
List<string> listPath = GetLinkFilePaths(doc);
Document docLink = uiApp.Application.OpenDocumentFile(listPath[0]);
//
FilteredElementCollector collIns = new FilteredElementCollector(doc);//
collIns.OfClass(typeof(Instance)).OfCategory(BuiltInCategory.OST_RvtLinks);//RevitLinkType
Transform transForm = null;
foreach (Element elDoc in collIns)
{
Instance ins = elDoc as Instance;
if (ins != null)
{
transForm = ins.GetTransform();
}
}
//风管
FilteredElementCollector collDuct = new FilteredElementCollector(doc);
collDuct.OfClass(typeof(Duct)).OfCategory(BuiltInCategory.OST_DuctCurves);
foreach (Element elDuct in collDuct)
{
Duct duct = elDuct as Duct;
List<Wall> listWall = FindDuctWall(docLink, duct);//找到链接文档中与风管相交的墙
foreach (Wall wall in listWall)
{
//求面和线的交点
Face face = FindWallFace(wall);
Curve curve = FindDuctCurve(duct);
XYZ xyz = FindFaceCurve(face, curve);
//墙线的向量
XYZ wallVector = FindWallVector(wall);
//找到风管的宽和高
double dWidth = GetDuctWidth(duct);
double dHeigh = GetDuctHeight(duct);
int iUp = 100;
int iDown = 100;
int iLeft = 100;
int iRight = 100;
//左上角
XYZ pt1 = xyz + new XYZ(0, 0, 1) * (dHeigh / 2 + iUp) / 304.8;
pt1 = pt1 - wallVector.Normalize() * (dWidth / 2 + iLeft) / 304.8;
pt1 = pt1 - transForm.Origin;
//右下角
XYZ pt2 = xyz + new XYZ(0, 0, -1) * (dHeigh / 2 + iDown) / 304.8;
pt2 = pt2 + wallVector.Normalize() * (dWidth / 2 + iRight) / 304.8;
pt2 = pt2 - transForm.Origin;
//开洞
//doc.Create.NewOpening(wall, pt1, pt2);
//wall.Id.IntegerValue.ToString();
//pt1.X;
XmlElement xmlEl = xmlDoc.CreateElement("Opening");
xmlEl.SetAttribute("WallId", wall.Id.IntegerValue.ToString());
XmlElement elPt1 = xmlDoc.CreateElement("PT1");
elPt1.SetAttribute("X", pt1.X.ToString());
elPt1.SetAttribute("Y", pt1.Y.ToString());
elPt1.SetAttribute("Z", pt1.Z.ToString());
xmlEl.AppendChild(elPt1);
XmlElement elPt2 = xmlDoc.CreateElement("PT2");
elPt2.SetAttribute("X", pt2.X.ToString());
elPt2.SetAttribute("Y", pt2.Y.ToString());
elPt2.SetAttribute("Z", pt2.Z.ToString());
xmlEl.AppendChild(elPt2);
xmlDoc.DocumentElement.AppendChild(xmlEl);
}
}
ts.Commit();
xmlDoc.Save(strPath);
}
catch (Exception ex)
{
WinFormTools.MsgBox(ex.ToString());
}
return Result.Succeeded;
}
//找到风管宽度
public static double GetDuctWidth(Duct duct)
{
double dWidth = 0;
foreach (Parameter p in duct.Parameters)
{
if (p.Definition.Name == "宽度")
{
dWidth = double.Parse(p.AsValueString());
break;
}
}
return dWidth;
}
//找到风管高度
public static double GetDuctHeight(Duct duct)
{
double dHeigh = 0;
foreach (Parameter p in duct.Parameters)
{
if (p.Definition.Name == "高度")
{
dHeigh = double.Parse(p.AsValueString());
break;
}
}
return dHeigh;
}
/// <summary>
/// 找到墙线的向量
/// </summary>
/// <param name="wall"></param>
/// <returns></returns>
public static XYZ FindWallVector(Wall wall)
{
LocationCurve lCurve = wall.Location as LocationCurve;
XYZ xyz = lCurve.Curve.get_EndPoint(1) - lCurve.Curve.get_EndPoint(0);
return xyz;
}
/// <summary>
/// 求线和面的交点
/// </summary>
/// <param name="face"></param>
/// <param name="curve"></param>
/// <returns></returns>
public static XYZ FindFaceCurve(Face face, Curve curve)
{
//求交点
IntersectionResultArray intersectionR = new IntersectionResultArray();//交点集合
SetComparisonResult comparisonR;//Comparison比较
comparisonR = face.Intersect(curve, out intersectionR);
XYZ intersectionResult = null;//交点坐标
if (SetComparisonResult.Disjoint != comparisonR)//Disjoint不交
{
if (!intersectionR.IsEmpty)
{
intersectionResult = intersectionR.get_Item(0).XYZPoint;
}
}
return intersectionResult;
}
/// <summary>
/// 找到风管对应的曲线
/// </summary>
/// <param name="duct"></param>
/// <returns></returns>
public Curve FindDuctCurve(Duct duct)
{
//得到风管曲线
IList<XYZ> list = new List<XYZ>();
ConnectorSetIterator csi = duct.ConnectorManager.Connectors.ForwardIterator();
while (csi.MoveNext())
{
Connector conn = csi.Current as Connector;
list.Add(conn.Origin);
}
Curve curve = Line.get_Bound(list.ElementAt(0), list.ElementAt(1)) as Curve;
curve.MakeUnbound();
return curve;
}
/// <summary>
/// 找到墙的正面
/// </summary>
/// <param name="wall"></param>
/// <returns></returns>
public Face FindWallFace(Wall wall)
{
Face normalFace = null;
//
Options opt = new Options();
opt.ComputeReferences = true;
opt.DetailLevel = Autodesk.Revit.DB.DetailLevels.Medium;
//
GeometryElement e = wall.get_Geometry(opt);
/*下版改进
IEnumerator<GeometryObject> enm = e.GetEnumerator();
while (enm.MoveNext())
{
Solid solid = enm.Current as Solid;
}*/
foreach (GeometryObject obj in e.Objects)//待改2013
{
Solid solid = obj as Solid;
if (solid != null && solid.Faces.Size > 0)
{
foreach (Face face in solid.Faces)
{
PlanarFace pf = face as PlanarFace;
if (pf != null)
{
if (pf.Normal.AngleTo(wall.Orientation) < 0.01)//数值在0到PI之间
{
normalFace = face;
}
}
}
}
}
return normalFace;
}
/// <summary>
/// 取得链接文件路径
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public List<string> GetLinkFilePaths(Document doc)
{
List<string> listPath = new List<string>();
foreach (ElementId elId in ExternalFileUtils.GetAllExternalFileReferences(doc))
{
if (doc.get_Element(elId).IsExternalFileReference())
{
ExternalFileReference fileRef = doc.get_Element(elId).GetExternalFileReference();
if (ExternalFileReferenceType.RevitLink == fileRef.ExternalFileReferenceType)
listPath.Add(ModelPathUtils.ConvertModelPathToUserVisiblePath(fileRef.GetAbsolutePath()));
}
}
return listPath;
}
/// <summary>
/// 根据链接文件名称找到对应链接路径,模糊匹配,待改进
/// </summary>
/// <param name="listPath"></param>
/// <param name="strKey"></param>
/// <returns></returns>
private string GetPath(List<string> listPath, string strKey)
{
foreach (string strPath in listPath)
{
if (strPath.Contains(strKey))
return strPath;
}
return "";
}
}
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class cmdOpening : IExternalCommand
{
public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
{
UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
Selection sel = uiDoc.Selection;
Transaction ts = new Transaction(doc, "http://revit.5d6d.com");
ts.Start();
string strPath = @"C:\Users\HongYe\Desktop\OpeningInfo.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(strPath);
foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
{
//;
Wall wall = doc.get_Element(new ElementId(Convert.ToInt32(node.Attributes["WallId"].Value))) as Wall;
XmlNode nodePt1 = node.SelectSingleNode("PT1");
XYZ pt1 = new XYZ(double.Parse(nodePt1.Attributes["X"].Value), double.Parse(nodePt1.Attributes["Y"].Value), double.Parse(nodePt1.Attributes["Z"].Value));
XmlNode nodePt2 = node.SelectSingleNode("PT2");
XYZ pt2 = new XYZ(double.Parse(nodePt2.Attributes["X"].Value), double.Parse(nodePt2.Attributes["Y"].Value), double.Parse(nodePt2.Attributes["Z"].Value));
doc.Create.NewOpening(wall, pt1, pt2);
}
ts.Commit();
return Result.Succeeded;
}
}
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
//导出开洞信息
public class cmd : IExternalCommand
{
/// <summary>
/// 找到链接文档中与风管相交的墙
/// </summary>
/// <param name="doc"></param>
/// <param name="duct"></param>
/// <returns></returns>
public static List<Wall> FindDuctWall(Document doc, Duct duct)
{
List<Wall> listWall = new List<Wall>();
//找到outLine
BoundingBoxXYZ bb = duct.get_BoundingBox(doc.ActiveView);
Outline outline = new Outline(bb.Min, bb.Max);
//
FilteredElementCollector collector = new FilteredElementCollector(doc);
BoundingBoxIntersectsFilter invertFilter = new BoundingBoxIntersectsFilter(outline, false);
IList<Element> noIntersectWalls = collector.OfClass(typeof(Wall)).WherePasses(invertFilter).ToElements();
foreach (Element el in noIntersectWalls)
{
Wall wall = el as Wall;
if (wall != null)
listWall.Add(wall);
}
return listWall;
}
public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
{
UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
UIApplication uiApp = cmdData.Application;
Document doc = uiDoc.Document;
Selection selection = uiDoc.Selection;
try
{
Transaction ts = new Transaction(doc, "http://revit.5d6d.com");
ts.Start();
string strPath = @"C:\Users\HongYe\Desktop\OpeningInfo.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(strPath);
List<string> listPath = GetLinkFilePaths(doc);
Document docLink = uiApp.Application.OpenDocumentFile(listPath[0]);
//
FilteredElementCollector collIns = new FilteredElementCollector(doc);//
collIns.OfClass(typeof(Instance)).OfCategory(BuiltInCategory.OST_RvtLinks);//RevitLinkType
Transform transForm = null;
foreach (Element elDoc in collIns)
{
Instance ins = elDoc as Instance;
if (ins != null)
{
transForm = ins.GetTransform();
}
}
//风管
FilteredElementCollector collDuct = new FilteredElementCollector(doc);
collDuct.OfClass(typeof(Duct)).OfCategory(BuiltInCategory.OST_DuctCurves);
foreach (Element elDuct in collDuct)
{
Duct duct = elDuct as Duct;
List<Wall> listWall = FindDuctWall(docLink, duct);//找到链接文档中与风管相交的墙
foreach (Wall wall in listWall)
{
//求面和线的交点
Face face = FindWallFace(wall);
Curve curve = FindDuctCurve(duct);
XYZ xyz = FindFaceCurve(face, curve);
//墙线的向量
XYZ wallVector = FindWallVector(wall);
//找到风管的宽和高
double dWidth = GetDuctWidth(duct);
double dHeigh = GetDuctHeight(duct);
int iUp = 100;
int iDown = 100;
int iLeft = 100;
int iRight = 100;
//左上角
XYZ pt1 = xyz + new XYZ(0, 0, 1) * (dHeigh / 2 + iUp) / 304.8;
pt1 = pt1 - wallVector.Normalize() * (dWidth / 2 + iLeft) / 304.8;
pt1 = pt1 - transForm.Origin;
//右下角
XYZ pt2 = xyz + new XYZ(0, 0, -1) * (dHeigh / 2 + iDown) / 304.8;
pt2 = pt2 + wallVector.Normalize() * (dWidth / 2 + iRight) / 304.8;
pt2 = pt2 - transForm.Origin;
//开洞
//doc.Create.NewOpening(wall, pt1, pt2);
//wall.Id.IntegerValue.ToString();
//pt1.X;
XmlElement xmlEl = xmlDoc.CreateElement("Opening");
xmlEl.SetAttribute("WallId", wall.Id.IntegerValue.ToString());
XmlElement elPt1 = xmlDoc.CreateElement("PT1");
elPt1.SetAttribute("X", pt1.X.ToString());
elPt1.SetAttribute("Y", pt1.Y.ToString());
elPt1.SetAttribute("Z", pt1.Z.ToString());
xmlEl.AppendChild(elPt1);
XmlElement elPt2 = xmlDoc.CreateElement("PT2");
elPt2.SetAttribute("X", pt2.X.ToString());
elPt2.SetAttribute("Y", pt2.Y.ToString());
elPt2.SetAttribute("Z", pt2.Z.ToString());
xmlEl.AppendChild(elPt2);
xmlDoc.DocumentElement.AppendChild(xmlEl);
}
}
ts.Commit();
xmlDoc.Save(strPath);
}
catch (Exception ex)
{
WinFormTools.MsgBox(ex.ToString());
}
return Result.Succeeded;
}
//找到风管宽度
public static double GetDuctWidth(Duct duct)
{
double dWidth = 0;
foreach (Parameter p in duct.Parameters)
{
if (p.Definition.Name == "宽度")
{
dWidth = double.Parse(p.AsValueString());
break;
}
}
return dWidth;
}
//找到风管高度
public static double GetDuctHeight(Duct duct)
{
double dHeigh = 0;
foreach (Parameter p in duct.Parameters)
{
if (p.Definition.Name == "高度")
{
dHeigh = double.Parse(p.AsValueString());
break;
}
}
return dHeigh;
}
/// <summary>
/// 找到墙线的向量
/// </summary>
/// <param name="wall"></param>
/// <returns></returns>
public static XYZ FindWallVector(Wall wall)
{
LocationCurve lCurve = wall.Location as LocationCurve;
XYZ xyz = lCurve.Curve.get_EndPoint(1) - lCurve.Curve.get_EndPoint(0);
return xyz;
}
/// <summary>
/// 求线和面的交点
/// </summary>
/// <param name="face"></param>
/// <param name="curve"></param>
/// <returns></returns>
public static XYZ FindFaceCurve(Face face, Curve curve)
{
//求交点
IntersectionResultArray intersectionR = new IntersectionResultArray();//交点集合
SetComparisonResult comparisonR;//Comparison比较
comparisonR = face.Intersect(curve, out intersectionR);
XYZ intersectionResult = null;//交点坐标
if (SetComparisonResult.Disjoint != comparisonR)//Disjoint不交
{
if (!intersectionR.IsEmpty)
{
intersectionResult = intersectionR.get_Item(0).XYZPoint;
}
}
return intersectionResult;
}
/// <summary>
/// 找到风管对应的曲线
/// </summary>
/// <param name="duct"></param>
/// <returns></returns>
public Curve FindDuctCurve(Duct duct)
{
//得到风管曲线
IList<XYZ> list = new List<XYZ>();
ConnectorSetIterator csi = duct.ConnectorManager.Connectors.ForwardIterator();
while (csi.MoveNext())
{
Connector conn = csi.Current as Connector;
list.Add(conn.Origin);
}
Curve curve = Line.get_Bound(list.ElementAt(0), list.ElementAt(1)) as Curve;
curve.MakeUnbound();
return curve;
}
/// <summary>
/// 找到墙的正面
/// </summary>
/// <param name="wall"></param>
/// <returns></returns>
public Face FindWallFace(Wall wall)
{
Face normalFace = null;
//
Options opt = new Options();
opt.ComputeReferences = true;
opt.DetailLevel = Autodesk.Revit.DB.DetailLevels.Medium;
//
GeometryElement e = wall.get_Geometry(opt);
/*下版改进
IEnumerator<GeometryObject> enm = e.GetEnumerator();
while (enm.MoveNext())
{
Solid solid = enm.Current as Solid;
}*/
foreach (GeometryObject obj in e.Objects)//待改2013
{
Solid solid = obj as Solid;
if (solid != null && solid.Faces.Size > 0)
{
foreach (Face face in solid.Faces)
{
PlanarFace pf = face as PlanarFace;
if (pf != null)
{
if (pf.Normal.AngleTo(wall.Orientation) < 0.01)//数值在0到PI之间
{
normalFace = face;
}
}
}
}
}
return normalFace;
}
/// <summary>
/// 取得链接文件路径
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public List<string> GetLinkFilePaths(Document doc)
{
List<string> listPath = new List<string>();
foreach (ElementId elId in ExternalFileUtils.GetAllExternalFileReferences(doc))
{
if (doc.get_Element(elId).IsExternalFileReference())
{
ExternalFileReference fileRef = doc.get_Element(elId).GetExternalFileReference();
if (ExternalFileReferenceType.RevitLink == fileRef.ExternalFileReferenceType)
listPath.Add(ModelPathUtils.ConvertModelPathToUserVisiblePath(fileRef.GetAbsolutePath()));
}
}
return listPath;
}
/// <summary>
/// 根据链接文件名称找到对应链接路径,模糊匹配,待改进
/// </summary>
/// <param name="listPath"></param>
/// <param name="strKey"></param>
/// <returns></returns>
private string GetPath(List<string> listPath, string strKey)
{
foreach (string strPath in listPath)
{
if (strPath.Contains(strKey))
return strPath;
}
return "";
}
}
我这个博客废弃不用了,今天想寻找外链的时候,突然想到这个博客权重很高。
有需要免费外链的,留言即可,我准备把这个博客变成免费的友情链接站点。