/// <summary>
/// Retrieve all structural elements that we are
/// interested in using to define setout points.
/// We are looking at concrete for the moment.
/// This includes: columns, framing, floors,
/// foundations, ramps, walls.
/// </summary>
FilteredElementCollector GetStructuralElements( Document doc )
{
BuiltInCategory[] bics = new BuiltInCategory[]
{
BuiltInCategory.OST_StructuralColumns,
BuiltInCategory.OST_StructuralFraming,
BuiltInCategory.OST_StructuralFoundation,
BuiltInCategory.OST_Floors,
BuiltInCategory.OST_Ramps
};
IList<ElementFilter> a = new List<ElementFilter>( bics.Length );
foreach( BuiltInCategory bic in bics )
{
a.Add( new ElementCategoryFilter( bic ) );
}
LogicalOrFilter categoryFilter = new LogicalOrFilter( a );
// 使用材质过滤器添加混凝土或者预制混凝土的条件
List<ElementFilter> b = new List<ElementFilter>( 2 );
b.Add( new StructuralMaterialTypeFilter( StructuralMaterialType.Concrete ) );
b.Add( new StructuralMaterialTypeFilter( StructuralMaterialType.PrecastConcrete ) );
LogicalOrFilter structuralMaterialFilter = new LogicalOrFilter( b );
List<ElementFilter> c = new List<ElementFilter>( 3 );
c.Add( new ElementClassFilter( typeof( FamilyInstance ) ) );
c.Add( structuralMaterialFilter );
c.Add( categoryFilter );
LogicalAndFilter familyInstanceFilter = new LogicalAndFilter( c );
IList<ElementFilter> d = new List<ElementFilter>( 6 );
d.Add( new ElementClassFilter( typeof( Wall ) ) );
d.Add( new ElementClassFilter( typeof( Floor ) ) );
#if NEED_LOADS
d.Add( new ElementClassFilter(typeof( PointLoad ) ) );
d.Add( new ElementClassFilter(typeof( LineLoad ) ) );
d.Add( new ElementClassFilter(typeof( AreaLoad ) ) );
#endif
d.Add( familyInstanceFilter );
LogicalOrFilter classFilter = new LogicalOrFilter( d );
FilteredElementCollector col = new FilteredElementCollector( doc )
.WhereElementIsNotElementType()
.WherePasses( classFilter );
return col;
}
访问几何数据获取顶点
class XyzEqualityComparer : IEqualityComparer<XYZ> { const double _sixteenthInchInFeet = 1.0 / ( 16.0 * 12.0 ); public bool Equals( XYZ p, XYZ q ) { return p.IsAlmostEqualTo( q, _sixteenthInchInFeet ); } public int GetHashCode( XYZ p ) { return PointString( p ).GetHashCode(); } }
/// <summary> /// 在 Revit 中,一个圆由两段弧组成,每段弧的两个顶点中只会返回一个。 /// </summary> Dictionary<XYZ,int> GetCorners( Solid solid ) { Dictionary<XYZ, int> corners = new Dictionary<XYZ, int>( new XyzEqualityComparer() ); foreach( Face f in solid.Faces ) { foreach( EdgeArray ea in f.EdgeLoops ) { foreach( Edge e in ea ) { XYZ p = e.AsCurveFollowingFace( f ).get_EndPoint( 0 ); if( !corners.ContainsKey( p ) ) { corners[p] = 0; } ++corners[p]; } } } return corners; }
遍历元素的几何数据,并且将第一个非空的几何数据作为 Solid 对象。
Solid GetSolid( Element e, Options opt ) { GeometryElement geo = e.get_Geometry( opt ); Solid solid = null; GeometryInstance inst = null; Transform t = Transform.Identity; // 有些柱子没有几何实体,我们必须从族类型中获取 // 有些有族实例本身有实体,但是没有几何实体 foreach( GeometryObject obj in geo ) { solid = obj as Solid; if( null != solid && 0 < solid.Faces.Size ) { break; } inst = obj as GeometryInstance; } if( null == solid && null != inst ) { geo = inst.GetSymbolGeometry(); t = inst.Transform; foreach( GeometryObject obj in geo ) { solid = obj as Solid; if( null != solid && 0 < solid.Faces.Size ) { break; } } } return solid; }
Transform GetProjectLocationTransform( Document doc ) { // 获取项目原点位置 ProjectPosition projectPosition = doc.ActiveProjectLocation.get_ProjectPosition( XYZ.Zero ); // 项目原点对应向量 XYZ translationVector = new XYZ( projectPosition.EastWest, projectPosition.NorthSouth, projectPosition.Elevation ); Transform translationTransform = Transform.get_Translation( translationVector ); // 项目旋转转换 Transform rotationTransform = Transform.get_Rotation( XYZ.Zero, XYZ.BasisZ, projectPosition.Angle ); // 组合项目原点转换和旋转转换 Transform finalTransform = translationTransform.Multiply( rotationTransform ); return finalTransform; }
Transform projectLocationTransform = GetProjectLocationTransform( doc ); for each concrete corner point XYZ p: { XYZ r2 = projectLocationTransform.OfPoint( p ); }