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 :(
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?
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. 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:
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. The transaction for creation must be finished first in order to get its 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;
}