简体   繁体   English

Revit API C# 插入和旋转系列

[英]Revit API C# Insert and Rotate Family

I'm trying to insert an element and rotate it 90 degrees but I'm having problems to get the ElementId in order to use ElementTransformUtils.RotateElement, I've tried follow https://thebuildingcoder.typepad.com/blog/2010/06/place-family-instance.html in order to set an Event Handler before I insert the element and get Element Id through GetAddedElementIds but I can't make it work for me:(我正在尝试插入一个元素并将其旋转 90 度,但我在获取 ElementId 以使用 ElementTransformUtils.RotateElement 时遇到问题,我尝试遵循https://thebuildingcoder.typepad.com/blog/2010/ 06/place-family-instance.html以便在我插入元素并通过 GetAddedElementIds 获取元素 ID 之前设置事件处理程序,但我无法让它为我工作:(

I would appreciate any help in this regard.我将不胜感激在这方面的任何帮助。

Below is my code, I start a transaction to place the family (symbol) and I make a for loop to insert 5 times, I would like to rotate the elements inserted 90 degrees, I tried with the RotateElement inside the for loop to rotate each element as they are inserted, but maybe would be better to rotate all the inserted in just 1 instruction?下面是我的代码,我开始一个事务来放置族(符号),我做了一个 for 循环插入 5 次,我想将插入的元素旋转 90 度,我尝试使用 for 循环内的 RotateElement 旋转每个插入元素,但仅在 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();
            }

Thanks very much.非常感谢。

--EDIT-- - 编辑 -

I did suppose that the code to work would be the below, however, when I try to execute it it states: "Error: Sequence contains no elements"我确实认为要工作的代码如下,但是,当我尝试执行它时,它指出:“错误:序列不包含元素”

code:代码:

                    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());
                }

I would appreciate any help, thanks我会很感激任何帮助,谢谢

There's two ways you can solve this and neither need to use DocumentChanged Event.有两种方法可以解决这个问题,并且不需要使用 DocumentChanged 事件。 The hard part of this is going to be figuring out what to use for the axis of rotation.最难的部分是弄清楚旋转轴使用什么。 First method uses RotateElement right after creation:第一种方法在创建后立即使用 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();
        }
    }

Second method uses a second transaction to rotate the element, because in this method I've used the BoundingBox of the element to get the center of it.第二种方法使用第二个事务来旋转元素,因为在这个方法中我使用了元素的 BoundingBox 来获取它的中心。 The transaction for creation must be finished first in order to get its 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();
        }
    }

Helper Methods:辅助方法:

    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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM