博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Revit Family API 添加对齐
阅读量:7008 次
发布时间:2019-06-28

本文共 8399 字,大约阅读时间需要 27 分钟。

没测试成功,留待以后研究。
[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.0
0.0
1.0), 
"
Upper Ref Level
");
        AddAlignment_Level(doc, pSolid, 
new XYZ(
0.0
0.0, -
1.0), 
"
Lower Ref. Level
");
        AddAlignment_ReferencePlane(app, doc, pSolid, 
new XYZ(
1.0
0.0
0.0), 
"
Right
");
        AddAlignment_ReferencePlane(app, doc, pSolid, 
new XYZ(-
1.0
0.0
0.0), 
"
Left
");
        AddAlignment_ReferencePlane(app, doc, pSolid, 
new XYZ(
0.0, -
1.0
0.0), 
"
Front
");
        AddAlignment_ReferencePlane(app, doc, pSolid, 
new XYZ(
0.0
1.0
0.0), 
"
Back
");
        AddAlignment_ReferencePlane(app, doc, pSolid, 
new XYZ(
1.0
0.0
0.0), 
"
OffsetV
");
        AddAlignment_ReferencePlane(app, doc, pSolid, 
new XYZ(
0.0
1.0
0.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.0
0.0),
new XYZ(w / 
2.0, -d / 
2.0
0.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.0
0.0),
new XYZ(-w / 
2.0, d / 
2.0
0.0),
new XYZ(-w / 
2.0, -d / 
2.0
0.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:

转载于:https://www.cnblogs.com/greatverve/p/revit-family-api-add-alignment.html

你可能感兴趣的文章
memcached 异常 : 单数据项超过默认值1m
查看>>
mysql创建登录报错ERROR1045(28000)
查看>>
virtualbox(windows环境下)centos虚拟机安装增强工具
查看>>
Fragment(碎片)的静态创建
查看>>
Domino 服务器定时重启
查看>>
安装java及环境配置
查看>>
NFS和SAMBA服务备忘录
查看>>
android 短信发送器
查看>>
Logan:美团点评的开源移动端基础日志库
查看>>
获取Java类中所有Field
查看>>
机器学习需要的数学基础
查看>>
puppet自动化运维之类
查看>>
Python在Linux下的Tab补齐
查看>>
部署搭建 Saltstack
查看>>
多备份亮相安卓开发者大会聚焦全球App数据保护
查看>>
sata盘,SSD盘,fusion-IO卡 对比
查看>>
NFS文件服务器使用简介
查看>>
linux文件名通配
查看>>
Laravel 5.2 教程 - 数据填充
查看>>
C++11之右值引用(二):右值引用与移动语义
查看>>