Assembly Origin Not Setting Correctly After Rotation and Translation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
private void AlignAssemblyToWall(Document doc, AssemblyInstance assembly)
{
if (assembly == null)
{
TaskDialog.Show("Error", "Assembly instance is null.");
return;
}
// Step 1: Retrieve all walls in the assembly
ICollection<ElementId> memberIds = assembly.GetMemberIds();
XYZ rotationMidPoint = null;
double rotationAngle = 0;
foreach (ElementId id in memberIds)
{
Element element = doc.GetElement(id);
if (element is Wall wall)
{
LocationCurve locationCurve = wall.Location as LocationCurve;
if (locationCurve != null)
{
Curve curve = locationCurve.Curve;
// Step 2: Calculate wall angle with respect to the X-axis
double wallAngle = GetAngleWithXAxis(curve);
wallAngle = Math.Round(wallAngle, 2); // Round to 2 decimal places
// Calculate minimal rotation angle
if (wallAngle > 180)
{
rotationAngle = 360 - wallAngle;
}
else
{
rotationAngle = wallAngle;
}
// Get the midpoint of the wall for translation and rotation
rotationMidPoint = (curve.GetEndPoint(0) + curve.GetEndPoint(1)) / 2;
// Break after processing the first wall
break;
}
}
}
// Step 3: Check if a valid wall was found
if (rotationMidPoint == null)
{
TaskDialog.Show("Error", "No walls found in the assembly.");
return;
}
// Step 4: Apply rotation and move origin
using (Transaction tx = new Transaction(doc, "Align Assembly"))
{
tx.Start();
// Get the current transform of the assembly
Transform currentTransform = assembly.GetTransform();
// Create a rotation transform
Transform rotationTransform = Transform.CreateRotationAtPoint(
XYZ.BasisZ,
rotationAngle * Math.PI / 180,
rotationMidPoint
);
// Apply the rotation to the assembly
Transform rotatedTransform = currentTransform.Multiply(rotationTransform);
assembly.SetTransform(rotatedTransform);
// Adjust the origin of the assembly to match the midpoint of the wall
XYZ translationVector = rotationMidPoint - assembly.GetTransform().Origin;
Transform translationTransform = Transform.CreateTranslation(translationVector);
// Combine the rotation and translation transforms
Transform finalTransform = rotatedTransform.Multiply(translationTransform);
assembly.SetTransform(finalTransform);
tx.Commit();
}
TaskDialog.Show("Success", $"Assembly '{assembly.Name}' aligned to wall. Rotation: {rotationAngle}°");
}
// Helper function to calculate the angle with the X-axis
private double GetAngleWithXAxis(Curve curve)
{
XYZ start = curve.GetEndPoint(0);
XYZ end = curve.GetEndPoint(1);
XYZ direction = (end - start).Normalize();
double angle = Math.Atan2(direction.Y, direction.X) * (180 / Math.PI);
if (angle < 0)
{
angle += 360; // Ensure angle is positive
}
return angle; // Return the angle in degrees
}
Hello everyone,
I’m working on aligning an assembly’s origin with a specific wall's midpoint in Revit using the Revit API. My current process involves rotating the assembly based on the angle of the wall and then translating its origin to the midpoint of the wall's location curve. However, I’m facing an issue where:
- The rotation works inconsistently: For some assemblies, the calculated rotation doesn’t align the assembly correctly with the wall.
- The translation fails for certain walls: The assembly’s origin doesn’t align with the wall’s midpoint after the transformation.
Here’s what I’m doing in my code:- I calculate the wall's angle with respect to the X-axis using the location curve of the wall.
- I create a rotation transform at the wall's midpoint using this angle.
- After applying the rotation, I calculate a translation vector to move the assembly’s origin to the midpoint of the wall.
- I combine the rotation and translation transforms and apply them to the assembly.
My Goal:- Align the assembly with the wall using the minimal angle of rotation.
- Set the assembly’s origin to the wall’s midpoint after alignment.
I’d appreciate any suggestions or insights into resolving these issues.
Thank you!