Revit API 风管对齐

本文介绍了一个使用Revit API的外部命令实现调整两条风管间距的方法。通过选择两条风管并获取它们的连接器,计算出两风管之间的直接间距,并通过一系列几何运算调整风管位置以达到指定间距。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class cmd : IExternalCommand
{
    /// <summary>
    /// 取得风管两端连接器
    /// </summary>
    /// <param name="duct"></param>
    /// <returns></returns>
    private List<Connector> getConn(Duct duct)
    {
        List<Connector> listConn = new List<Connector>();
        ConnectorSetIterator csi = duct.ConnectorManager.Connectors.ForwardIterator();
        while (csi.MoveNext())
        {
            Connector conn = csi.Current as Connector;
            if (ConnectorType.End == conn.ConnectorType)
            {
                listConn.Add(conn);
            }
            else if (ConnectorType.Curve == conn.ConnectorType)
            {
                //return conn;
            }
        }
        return listConn;
    }
    public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements)
    {
        UIDocument uiDoc = cmdData.Application.ActiveUIDocument;
        UIApplication uiApp = cmdData.Application;
        Document doc = uiDoc.Document;
        Selection sel = uiDoc.Selection;


        Transaction ts = new Transaction(doc, "http://revit.5d6d.com");
        ts.Start();
        try
        {
            Element elDuct0 = doc.GetElement(sel.PickObject(ObjectType.Element, "选择风管1:"));
            Element elDuct1 = doc.GetElement(sel.PickObject(ObjectType.Element, "选择风管2:"));
            Duct duct0 = elDuct0 as Duct;
            Duct duct1 = elDuct1 as Duct;
            List<Connector> listConn0 = getConn(duct0);
            List<Connector> listConn1 = getConn(duct1);
            Line line0 = Line.get_Bound(listConn0[0].Origin, listConn0[1].Origin);
            Line line1 = Line.get_Bound(listConn1[0].Origin, listConn1[1].Origin);
            double dDis = line1.Distance(line0.get_EndPoint(0));//直接间距
            XYZ xyzVector = GetXYVector(line0, line1);
            LocationCurve lc = elDuct1.Location as LocationCurve;
            lc.Move(dDis * xyzVector);
            ts.Commit();
        }
        catch (Autodesk.Revit.Exceptions.OperationCanceledException)
        {
            ts.RollBack();
            return Result.Cancelled;
        }
        catch (Exception ex)
        {
            ts.RollBack();
        }


        return Result.Succeeded;
    }


    /// <summary>
    /// 取得平行线的单位向量
    /// </summary>
    /// <param name="line0"></param>
    /// <param name="line1"></param>
    /// <returns></returns>
    public XYZ GetXYVector(Line line0, Line line1)
    {
        //基准
        XYZ startPoint0 = line0.get_EndPoint(0);
        XYZ endPoint0 = line0.get_EndPoint(1);
        //参照
        XYZ startPoint1 = line1.get_EndPoint(0);
        XYZ endPoint1 = line1.get_EndPoint(1);
        //
        XYZ resultVector = new XYZ(0, 0, 0);


        XYZ zStart = new XYZ(startPoint1.X, startPoint1.Y, 0);
        XYZ zEnd = new XYZ(endPoint1.X, endPoint1.Y, 0);


        Line line = Line.get_Bound(new XYZ(startPoint0.X, startPoint0.Y, 0), new XYZ(endPoint0.X, endPoint0.Y, 0));
        line.MakeUnbound();


        //取得一条直线所在直线相垂直的直线
        XYZ tPoint = zStart - zEnd;
        XYZ zVector = new XYZ(0, 0, 1);
        XYZ nPoint = tPoint.CrossProduct(zVector).Normalize() + zStart;
        Line lineN = Line.get_Bound(zStart, nPoint);
        lineN.MakeUnbound();


        //与另外一条风管的交点
        IntersectionResultArray intersectionR = new IntersectionResultArray();
        SetComparisonResult comparisonR;


        comparisonR = line.Intersect(lineN, out intersectionR);


        if (SetComparisonResult.Disjoint != comparisonR)
        {
            if (!intersectionR.IsEmpty)
            {
                resultVector = intersectionR.get_Item(0).XYZPoint;
            }
        }


        if (!zStart.IsAlmostEqualTo(resultVector))
        {
            resultVector = (resultVector - zStart).Normalize();
        }


        return resultVector;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值