I am trying to create an add-in. Rotate multiple elements with their own axis.
But element rotates angle increasing within foreach loop. I even tried constant value by ignoring user input.
The rotation angle increasing by applied elements.
double RotateAngle; using (Rotating_Form thisForm = new Rotating_Form()) { // Determine the position of form thisForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; // Show the form thisForm.ShowDialog(); // Convert Radian to Degree RotateAngle = thisForm.Get_Angle()*Math.PI/180; if (thisForm.DialogResult == System.Windows.Forms.DialogResult.Cancel) { return Result.Cancelled; } using (Transaction t = new Transaction(doc)) { //Provide access to make change in document t.Start("Rotate Element"); // Collect selected elements ElementSet selection = new ElementSet(); // Select element references ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds(); foreach (ElementId elementId in selectedIds) { selection.Insert(uidoc.Document.GetElement(elementId)); foreach (Element e in selection) { //Get the location curve Location location = e.Location; LocationCurve locationCurve = location as LocationCurve; Curve curve = locationCurve.Curve;
// Get the end point of curve XYZ point1 = curve.GetEndPoint(0); XYZ point2 = curve.GetEndPoint(1); // Get the mid point of curve XYZ midPoint = (point1 + point2) / 2; XYZ midHigh = midPoint.Add(XYZ.BasisZ); Line axisLine = Line.CreateBound(midPoint, midHigh); //Rotate elements on their axis bool rotated = locationCurve.Rotate(axisLine, RotateAngle); rotated = true; } } // Nothings selected if (selection.IsEmpty) { message = "Please select at least one element"; return Result.Failed; } t.Commit(); } }
Solved! Go to Solution.
Solved by BardiaJahan. Go to Solution.
I think the inner Foreach loop is redundant. For each selected element, you would need to retrieve the location curve and rotate it - the is only one Foreach. Your current snippet keeps adding elements to ElementSet selection, which means the first element is rotated once, the second element is rotated twice, etc.
Try:
foreach (ElementId elementId in selectedIds) { Element e = doc.GetElement(elementId); //Get the location curve Location location = e.Location; LocationCurve locationCurve = location as LocationCurve; Curve curve = locationCurve.Curve; // Get the end point of curve XYZ point1 = curve.GetEndPoint(0); XYZ point2 = curve.GetEndPoint(1); // Get the mid point of curve XYZ midPoint = (point1 + point2) / 2; XYZ midHigh = midPoint.Add(XYZ.BasisZ); Line axisLine = Line.CreateBound(midPoint, midHigh); //Rotate elements on their axis bool rotated = locationCurve.Rotate(axisLine, RotateAngle); rotated = true; }