Revit Family API 添加对齐

没测试成功,留待以后研究。
[TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public  class cmdAddAlignment : IExternalCommand
{
     // 创建对齐,把一个面对齐到参考面。
     void AddAlignment_ReferencePlane(Application app, Document doc, Extrusion pSolid, XYZ normal,  string nameRefPlane)
    {
        View pViewPlan = Util.findElement(doc,  typeof(ViewPlan),  " Lower Ref. Level "as View;
        ReferencePlane refPlane = Util.findElement(doc,  typeof(ReferencePlane), nameRefPlane)  as ReferencePlane;
        PlanarFace pFace = findFace(app, pSolid, normal, refPlane);
        doc.FamilyCreate.NewAlignment(pViewPlan, refPlane.Reference, pFace.Reference);
    }
     // 对齐到楼层
     void AddAlignment_Level(Document doc, Extrusion pSolid, XYZ normal,  string nameLevel)
    {
        View pView = Util.findElement(doc,  typeof(View),  " Front "as View;
        Level pLevel = Util.findElement(doc,  typeof(Level), nameLevel)  as Level;
        PlanarFace pFace = Util.findFace(pSolid, normal);
        doc.FamilyCreate.NewAlignment(pView, pLevel.PlaneReference, pFace.Reference);
    }
     void AddAlignments(Application app, Document doc, Extrusion pSolid)
    {
        AddAlignment_Level(doc, pSolid,  new XYZ( 0.00.01.0),  " Upper Ref Level ");
        AddAlignment_Level(doc, pSolid,  new XYZ( 0.00.0, - 1.0),  " Lower Ref. Level ");
        AddAlignment_ReferencePlane(app, doc, pSolid,  new XYZ( 1.00.00.0),  " Right ");
        AddAlignment_ReferencePlane(app, doc, pSolid,  new XYZ(- 1.00.00.0),  " Left ");
        AddAlignment_ReferencePlane(app, doc, pSolid,  new XYZ( 0.0, - 1.00.0),  " Front ");
        AddAlignment_ReferencePlane(app, doc, pSolid,  new XYZ( 0.01.00.0),  " Back ");
        AddAlignment_ReferencePlane(app, doc, pSolid,  new XYZ( 1.00.00.0),  " OffsetV ");
        AddAlignment_ReferencePlane(app, doc, pSolid,  new XYZ( 0.01.00.0),  " OffsetH ");
    }
     //  ===============================================================
    
//  helper function: given a solid, find a planar 
    
// Extrusion实体,给一个实体,给一个方向,找到与此方向一致的面。
    
//  face with the given normal (version 2)
    
//  this is a slightly enhaced version of the previous 
    
//  version and checks if the face is on the given reference plane.
    
//  ===============================================================
    PlanarFace findFace(Application app, Extrusion pBox, XYZ normal, ReferencePlane refPlane)
    {
         //  get the geometry object of the given element
        
//
        Options op =  new Options();
        op.ComputeReferences =  true;
        GeometryObjectArray geomObjs = pBox.get_Geometry(op).Objects;

         //  loop through the array and find a face with the given normal
        
//
         foreach (GeometryObject geomObj  in geomObjs)
        {
             if (geomObj  is Solid)   //  solid is what we are interested in.
            {
                Solid pSolid = geomObj  as Solid;
                FaceArray faces = pSolid.Faces;
                 foreach (Face pFace  in faces)
                {
                    PlanarFace pPlanarFace = (PlanarFace)pFace;
                     //  check to see if they have same normal
                    
// face.Normal是面的向量。IsAlmostEqualTo();
                     if ((pPlanarFace !=  null) && pPlanarFace.Normal.IsAlmostEqualTo(normal))
                    {
                         //  additionally, we want to check if the face is on the reference plane
                        
// 还要判断面是否在参考平面上。
                        XYZ p0 = refPlane.BubbleEnd; // 终点?
                        XYZ p1 = refPlane.FreeEnd; // 起点?
                        Line pCurve = app.Create.NewLineBound(p0, p1);
                         if (pPlanarFace.Intersect(pCurve) == SetComparisonResult.Subset) // 子集
                        {
                             return pPlanarFace;  //  we found the face
                        }
                    }
                }
            }

             //  will come back later as needed.
            
//
            
// else if (geomObj is Instance)
            
// {
            
// }
            
// else if (geomObj is Curve)
            
// {
            
// }
            
// else if (geomObj is Mesh)
            
// {
            
// }
        }

         //  if we come here, we did not find any.
         return  null;
    }
     public Result Execute(ExternalCommandData commandData,  ref  string messages, ElementSet elements)
    {
        UIApplication app = commandData.Application;
        Document doc = app.ActiveUIDocument.Document;

        Transaction ts =  new Transaction(doc,  " http://revit.5d6d.com ");
        ts.Start();

         //
        Extrusion pSolid = CreateSolid(app.Application, doc);
        AddAlignments(app.Application, doc, pSolid);

        ts.Commit();

         return Result.Succeeded;
    }
     // 创建封闭曲线
    CurveArrArray createProfileLShape(Application _rvtApp)
    {
         //
        
//  define a simple L-shape profile
        
//
        
//   5 tw 4
        
//    +-+
        
//    | | 3          h = height
        
//  d | +---+ 2
        
//    +-----+ td
        
//   0        1
        
//   6  w
        
//

        
//  sizes (hard coded for simplicity)
        
//  note: these need to match reference plane. otherwise, alignment won't work.
        
//  as an exercise, try changing those values and see how it behaves.
        
//
         double w = Util.mmToFeet( 600.0);  //  those are hard coded for simplicity here. in practice, you may want to find out from the references)
         double d = Util.mmToFeet( 600.0);
         double tw = Util.mmToFeet( 150.0);  //  thickness added for Lab2
         double td = Util.mmToFeet( 150.0);

         //  define vertices
        
//
         const  int nVerts =  6//  the number of vertices

        XYZ[] pts =  new XYZ[] {
new XYZ(-w /  2.0, -d /  2.00.0),
new XYZ(w /  2.0, -d /  2.00.0),
new XYZ(w /  2.0, (-d /  2.0) + td,  0.0),
new XYZ((-w /  2.0) + tw, (-d /  2.0) + td,  0.0),
new XYZ((-w /  2.0) + tw, d /  2.00.0),
new XYZ(-w /  2.0, d /  2.00.0),
new XYZ(-w /  2.0, -d /  2.00.0) };   //  the last one is to make the loop simple

        
//  define a loop. define individual edges and put them in a curveArray
        
//
        CurveArray pLoop = _rvtApp.Create.NewCurveArray();
         for ( int i =  0; i < nVerts; ++i)
        {
            Line line = _rvtApp.Create.NewLineBound(pts[i], pts[i +  1]);
            pLoop.Append(line);
        }

         //  then, put the loop in the curveArrArray as a profile
        
//
        CurveArrArray pProfile = _rvtApp.Create.NewCurveArrArray();
        pProfile.Append(pLoop);
         //  if we come here, we have a profile now.

         return pProfile;
    }
    Extrusion CreateSolid(Application app, Document doc)
    {
        CurveArrArray pProfile = createProfileLShape(app);
         // 这个参考平面模板中没有,可以切换到Front立面,自己画一个。
        ReferencePlane pRefPlane = Util.findElement(doc,  typeof(ReferencePlane),  " Reference Plane "as ReferencePlane;
        SketchPlane pSketchPlane = doc.FamilyCreate.NewSketchPlane(pRefPlane.Plane);
         double dHeight = Util.mmToFeet( 4000);
         bool bIsSolid =  true;
        Extrusion pSolid = doc.FamilyCreate.NewExtrusion(bIsSolid, pProfile, pSketchPlane, dHeight);
         return pSolid;
    }
}
public  class Util
{
     // Revit内部单位feet转化为mm即毫米
     public  static  double mmToFeet( double val) {  return val /  304.8; }
     public  static  double feetToMm( double val) {  return val *  304.8; }
     // 通过类型与名称找Element
     public  static Element findElement(Document _rvtDoc, Type targetType,  string targetName)
    {
         //  get the elements of the given type
        
//
        FilteredElementCollector collector =  new FilteredElementCollector(_rvtDoc);
        collector.WherePasses( new ElementClassFilter(targetType));

         //  parse the collection for the given name
        
//  using LINQ query here. 
        
//  
         var targetElems =  from element  in collector  where element.Name.Equals(targetName)  select element;
        List<Element> elems = targetElems.ToList<Element>();

         if (elems.Count >  0)
        {   //  we should have only one with the given name. 
             return elems[ 0];
        }

         //  cannot find it.
         return  null;
    }
     //  =============================================================
    
//    helper function: find a planar face with the given normal
    
//  =============================================================
     public  static PlanarFace findFace(Extrusion pBox, XYZ normal)
    {
         //  get the geometry object of the given element
        
//
        Options op =  new Options();
        op.ComputeReferences =  true;
        GeometryObjectArray geomObjs = pBox.get_Geometry(op).Objects;

         //  loop through the array and find a face with the given normal
        
//
         foreach (GeometryObject geomObj  in geomObjs)
        {
             if (geomObj  is Solid)   //  solid is what we are interested in.
            {
                Solid pSolid = geomObj  as Solid;
                FaceArray faces = pSolid.Faces;
                 foreach (Face pFace  in faces)
                {
                    PlanarFace pPlanarFace = (PlanarFace)pFace;
                     if ((pPlanarFace !=  null) && pPlanarFace.Normal.IsAlmostEqualTo(normal))  //  we found the face
                    {
                         return pPlanarFace;
                    }
                }
            }
             //  will come back later as needed.
            
//
            
// else if (geomObj is Instance)
            
// {
            
// }
            
// else if (geomObj is Curve)
            
// {
            
// }
            
// else if (geomObj is Mesh)
            
// {
            
// }
        }

         //  if we come here, we did not find any.
         return  null;
    }
     #region Formatting and message handlers
     public  const  string Caption =  " Revit Family API Labs ";

     ///   <summary>
    
///  MessageBox wrapper for informational message.
    
///   </summary>
     public  static  void InfoMsg( string msg)
    {

        System.Diagnostics.Debug.WriteLine(msg);
        WinForm.MessageBox.Show(msg, Caption, WinForm.MessageBoxButtons.OK, WinForm.MessageBoxIcon.Information);
    }

     ///   <summary>
    
///  MessageBox wrapper for error message.
    
///   </summary>
     public  static  void ErrorMsg( string msg)
    {
        WinForm.MessageBox.Show(msg, Caption, WinForm.MessageBoxButtons.OK, WinForm.MessageBoxIcon.Error);
    }
     #endregion  //  Formatting and message handlers
}
url: http://greatverve.cnblogs.com/p/revit-family-api-add-alignment.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值