天天看點

Revit API風管對齊

Revit API風管對齊

start

[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)

        return Result.Succeeded;

    /// 取得平行線的機關向量

    /// <param name="line0"></param>

    /// <param name="line1"></param>

    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;

}