套管问题

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpeningFromWall
{
[Transaction(TransactionMode.Manual)]
public class Class1 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//启动插件
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
//【0】载入族文件
FamilySymbol familySymbol = FindSymbol(doc, “圆形套管族”, “圆形套管族”);
if (familySymbol == null)
{
try
{
Transaction transaction = new Transaction(doc, “载入族文件”); transaction.Start();
string file = @“C:\Ribbon\FamilySymbol\圆形套管族.rfa”;
doc.LoadFamily(file);
familySymbol = FindSymbol(doc, “圆形套管族”, “圆形套管族”);
transaction.Commit();
}
catch
{

                TaskDialog.Show("提示", "未找到合适的族文件");
            }

        }
        //[1]获取墙
        Reference reference = uidoc.Selection.PickObject(ObjectType.Element, "选择墙");
        Element wallele = doc.GetElement(reference);
        Wall wall = wallele as Wall;
        //[2]选择与墙相交的管道
        IList<ElementId> pipeListid = PipeIntersectElement(doc, wallele);

        //【3】获取墙的表面
        Face face = GetWallFaces(wall).First();

        XYZ point = null;
        XYZ dir = wall.Orientation.CrossProduct(XYZ.BasisZ);
        //【4】获取管线与墙的交点
        Transaction transaction1 = new Transaction(doc, "放置管道族");
        transaction1.Start();
        foreach (ElementId pipeid in pipeListid)
        {
            Pipe pipe = doc.GetElement(pipeid) as Pipe;
            Curve curve = (pipe.Location as LocationCurve).Curve;
            point = IntersectPointOfFaceAndCurve(face, curve);
            double fswidth = 1000 / 308.4;
            //激活族
            if (!familySymbol.IsActive)
            {
                familySymbol.Activate();
            }
            FamilyInstance fi = doc.Create.NewFamilyInstance(face, point, dir, familySymbol);
            //设置相关参数
            fi.LookupParameter("实体厚度").Set(wall.Width);
            fi.LookupParameter("外直径").Set(fswidth);
        }
        transaction1.Commit();
        return Result.Succeeded;
    }
    #region GetWallFaces_获取墙面
    /// <summary>
    /// 取得墙侧面
    /// </summary>
    /// <param name="wall"></param>
    /// <returns></returns>
    public List<Face> GetWallFaces(Wall wall)
    {
        List<Face> faces = new List<Face>();
        Options options = new Options();
        //打开computeReferences选项
        options.ComputeReferences = true;
        GeometryElement geoEle = wall.get_Geometry(options);
        foreach (GeometryObject geometryObject in geoEle)
        {
            if (geometryObject == null || (geometryObject as Solid).Faces.Size <= 1)
                continue;
            foreach (Face face in (geometryObject as Solid).Faces)
            {
                XYZ normal = (face as PlanarFace).FaceNormal;
                //比较向量夹角获取墙侧角,wall.orientation为墙的正方向
                if (normal.AngleTo(wall.Orientation) < 0.01 || normal.AngleTo(-wall.Orientation) < 0.01)
                {
                    faces.Add(face);
                }
            }
        }
        return faces;
    }
    #endregion

    #region PipeIntersectElement——获取与墙相交管线的id
    public IList<ElementId> PipeIntersectElement(Document doc, Element e)
    {
        IList<ElementId> eleids = new List<ElementId>();

        //求element的boundingBox,限制范围以提高效率
        BoundingBoxXYZ box = e.get_BoundingBox(doc.ActiveView);
        Outline outline = new Outline(box.Min, box.Max);
        //建立收集器
        FilteredElementCollector collector = new FilteredElementCollector(doc);
        //相交过滤
        ElementIntersectsElementFilter eleFilter = new ElementIntersectsElementFilter(e);
        //BoundingBox相交过滤
        BoundingBoxIntersectsFilter bbFilter = new BoundingBoxIntersectsFilter(outline);
        collector.WherePasses(eleFilter).WherePasses(bbFilter);
        //类别过滤
        //由于已通过相交过滤,肯定是实体,因此无需考虑去掉族类型
        collector.OfCategory(BuiltInCategory.OST_PipeCurves);
        //加入集合
        foreach (ElementId id in collector.ToElementIds())
        {
            if (!eleids.Contains(id))
            {
                eleids.Add(id);
            }
        }
        return eleids;
    }
    #endregion

    #region IntersectPointOfFaceAndCurve:求面与线的交点
    public XYZ IntersectPointOfFaceAndCurve(Face face, Curve curve)
    {
        //交点数组
        IntersectionResultArray result = new IntersectionResultArray();
        //枚举,用于判断相交类型
        SetComparisonResult setResult = face.Intersect(curve, out result);
        XYZ interResult = null;
        //Disjoint为不相交
        if (SetComparisonResult.Disjoint != setResult)
        {
            //isEmpty判断是否为空
            if (!result.IsEmpty)

                interResult = result.get_Item(0).XYZPoint;

        }
        return interResult;
    }
    #endregion

    #region FindSymbol_ 名称查找族文件
    public FamilySymbol FindSymbol(Document doc, string familyName, string symbolName)
    {
        //声明变量
        Family family = null;
        FamilySymbol symbol = null;
        //用类型过滤器查找所有族
        FilteredElementCollector familyCol = new FilteredElementCollector(doc);
        familyCol.OfClass(typeof(Family));
        //按组名称查找族
        foreach (Family f in familyCol)
        {
            if (f.Name == familyName)
            {
                family = f;
                break;
            }
        }
        //如果没有该族则返回
        if (family == null)
            return null;
        //用family.GetFamilySymbol()取得该族所有类型ID,再遍历
        foreach (ElementId fsid in family.GetFamilySymbolIds())
        {
            FamilySymbol fs = doc.GetElement(fsid) as FamilySymbol;
            if (fs.Name == symbolName)
            {
                symbol = fs;
                break;
            }
        }
        return symbol;
    }
    #endregion

}

}

猜你喜欢

转载自blog.csdn.net/waiting233/article/details/117354863