Revit API C# Вставить и повернуть семейство - PullRequest
0 голосов
/ 20 апреля 2020

Я пытаюсь вставить элемент и повернуть его на 90 градусов, но у меня возникают проблемы с получением ElementId для использования ElementTransformUtils.RotateElement, я пытался выполнить https://thebuildingcoder.typepad.com/blog/2010/06/place-family-instance.html для установить обработчик событий до того, как я вставлю элемент и получу идентификатор элемента через GetAddedElementIds, но я не могу заставить его работать на меня: (

Буду признателен за любую помощь в этом отношении.

Ниже мой код, я запускаю транзакцию, чтобы поместить семейство (символ), и я делаю для l oop, чтобы вставить 5 раз, я хотел бы повернуть вставленные элементы на 90 градусов, я пытался с RotateElement внутри для l oop чтобы повернуть каждый элемент по мере его вставки, но, возможно, было бы лучше повернуть все вставленные всего за 1 инструкцию?

using (Transaction trans = new Transaction(doc, "Place Family"))
            {
                trans.Start();
                if (!symbol.IsActive)
                {
                    symbol.Activate();
                }
                for (int x = 0; x < 5; x++)
                {
                    doc.Create.NewFamilyInstance(new XYZ(x, 0, 0), symbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                }

                    trans.Commit();
            }

Большое спасибо.

- EDIT--

Я действительно предполагал, что код для работы будет следующим, однако, когда я пытаюсь выполнить его, он сообщает: «Ошибка: последовательность не содержит элементов»

код:

                    if (!symbol4.IsActive)
                {
                    symbol4.Activate();
                }
                for (int x = 0; x < 4; x++)
                {
                    double xloc = x * BayLength / 304.8;
                    _added_element_ids.Clear();
                    app.DocumentChanged += new EventHandler<DocumentChangedEventArgs>(OnDocumentChanged);
                    doc.Create.NewFamilyInstance(new XYZ(xloc, 0, 1.021), symbol4, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                    app.DocumentChanged -= new EventHandler<DocumentChangedEventArgs>(OnDocumentChanged);
                    ElementId LastModifiedElementId = _added_element_ids.Last();
                    XYZ p1= new XYZ(xloc, 0.0, 1.021);
                    XYZ p2 = new XYZ(xloc, 0.0, 2.021);
                    Line Axis = Line.CreateBound(p1, p2);
                    double angle = -90 * Math.PI / 180;
                    ElementTransformUtils.RotateElement(doc, LastModifiedElementId, Axis, angle);
                }
                void OnDocumentChanged(object sender, DocumentChangedEventArgs e)
                {
                    _added_element_ids.AddRange(e.GetAddedElementIds());
                }

Буду признателен за любую помощь, спасибо

1 Ответ

1 голос
/ 22 апреля 2020

Есть два способа решения этой проблемы, и нет необходимости использовать DocumentChanged Event. Трудная часть этого будет выяснить, что использовать для оси вращения. Первый метод использует RotateElement сразу после создания:

    public void PlaceAndRotateFamilyMethod1()
    {
        Document doc = this.ActiveUIDocument.Document;

        FamilySymbol symbol = GetFamilySymbolToPlace(doc);

        using (Transaction trans = new Transaction(doc, "Place Family"))
        {
            trans.Start();
            if (!symbol.IsActive)
            {
                symbol.Activate();
            }
            for (int x = 0; x < 5; x++)
            {
                FamilyInstance fi = doc.Create.NewFamilyInstance(new XYZ(x, 0, 0), symbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);

                XYZ point1 = new XYZ(0, 10, 0);
                XYZ point2 = new XYZ(0, 10, 10);
                Line axis = Line.CreateBound(point1, point2);

                double angleToRotate = 45;

                ElementTransformUtils.RotateElement(doc, fi.Id, axis, ConvertToRadians(angleToRotate));
            }

            trans.Commit();
        }
    }

Второй метод использует вторую транзакцию для поворота элемента, потому что в этом методе я использовал BoundingBox элемента, чтобы получить его центр. Транзакция для создания должна быть сначала завершена, чтобы получить ее BoundingBox.

    public void PlaceAndRotateFamilyMethod2()
    {
        Document doc = this.ActiveUIDocument.Document;

        FamilySymbol symbol = GetFamilySymbolToPlace(doc);

        List<FamilyInstance> newFamInstToRotate = new List<FamilyInstance>();

        using (Transaction trans = new Transaction(doc, "Place Family"))
        {
            trans.Start();
            if (!symbol.IsActive)
            {
                symbol.Activate();
            }
            for (int x = 0; x < 5; x++)
            {
                FamilyInstance fi = doc.Create.NewFamilyInstance(new XYZ(x, 0, 0), symbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                newFamInstToRotate.Add(fi);
            }

            trans.Commit();
        }

        using (Transaction trans = new Transaction(doc, "Rotate Families"))
        {
            trans.Start();
            foreach (FamilyInstance fi in newFamInstToRotate)
            {
                XYZ center = (fi.get_BoundingBox(doc.ActiveView).Max + fi.get_BoundingBox(doc.ActiveView).Min) * 0.5;
                Line axis = Line.CreateBound(center, center + XYZ.BasisZ);
                double angleToRotate = 45;

                ElementTransformUtils.RotateElement(doc, fi.Id, axis, ConvertToRadians(angleToRotate));
            }
            trans.Commit();
        }
    }

Вспомогательные методы:

    private FamilySymbol GetFamilySymbolToPlace(Document doc)
    {
        FamilySymbol symbol = null;
        foreach (FamilySymbol fSym in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Furniture)) 
        {
            if (fSym.FamilyName == "Desk" && fSym.Name == "60\" x 30\"") 
            {
                symbol = fSym;
                break;
            }
        }
        return symbol;
    }

    private double ConvertToRadians(double angle)
    {
        return (Math.PI / 180) * angle;
    }
...