Revit API根据链接文件开洞


开洞信息数据:
<? 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 >
start
// 根据导出开洞信息开洞
[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( 001) * (dHeigh /  2 + iUp) /  304.8;
                    pt1 = pt1 - wallVector.Normalize() * (dWidth /  2 + iLeft) /  304.8;
                    pt1 = pt1 - transForm.Origin;
                     // 右下角
                    XYZ pt2 = xyz +  new XYZ( 00, - 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  "";
    }
}
url:http://greatverve.cnblogs.com/p/revit-api-opening-info.html


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM