How to use the Alignment method Using # for family Instance

How to use the Alignment method Using # for family Instance

ahmadkhalaf7892
Advocate Advocate
3,813 Views
9 Replies
Message 1 of 10

How to use the Alignment method Using # for family Instance

ahmadkhalaf7892
Advocate
Advocate

Hi Guys .
I Need to align a FamilyInstance in which I created using C# to a Line that I also Created Via C# in Revit 2023. For example the First Picture would show a structural column and a ModelCurve which are not aligned together. 

Not Aligned.PNG

 The second picture would Show How I want my column to be aligned to a ModelCurve. 

Aligned.PNG

I would greatly apricate if someone can show me just the method of how can I use the alignment method in C# . Here is just a sample code for my script :


Line line = Line.CreateBound(startPoint, endPoint);
Element newPile = doc.Create.NewFamilyInstance(point, symbol, Level, structuralType);



Accepted solutions (1)
3,814 Views
9 Replies
Replies (9)
Message 2 of 10

jeremy_tammik
Alumni
Alumni

Well, first of all you need to understand how to implement such a constraint manually in the end user interface. I believe you define a dimension between the two objects to do so, and constrain it to a zero distance. The Family API samples may demonstrate how such a constraint can be set up programmatically:

  

  

Reading that myself, I discover that the NewAlignment method might come in handy:

  

  

Searching this forum for NewAlignment ought to turn up something useful for you.

  

Good luck!

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 10

ahmadkhalaf7892
Advocate
Advocate

Hi Jeremy . 
Thanks a  lot for introducing this method for me .  I am trying to align the family instance called newPile to the model Curve however I am getting this error under :
Autodesk.Revit.Exceptions.ArgumentException: 'The two references are not geometrically aligned so the Alignment cannot be created.
Parameter name: reference2'

I have created both the model Curve and the familyinstance in the same level.

This is the code that I am using : 

// Create a list of curves
List<Curve> curves = new List<Curve>();
foreach (Floor floor in tunnelFloors.Floors)
{
Sketch sketch = doc.GetElement(floor.SketchId) as Sketch;
foreach (CurveArray curveArray in sketch.Profile)
{
foreach (Curve curve in curveArray)
{
XYZ p0 = (new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, 0));
XYZ p1 = (new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, 0));
Curve c1 = Line.CreateBound(p0, p1);
curves.Add(c1);
}

}
}

foreach (Curve curve in curves)
{

ModelCurve m1 = doc.Create.NewModelCurve(curve, sketchPlane);
// Move the family instance along the curve by the distance variable
double length = curve.Length;
int count = (int)(length / x);
for (int j = 1; j <= count; j++)
{
XYZ point = curve.Evaluate((double)j * x / length, true);
FamilyInstance newPile = doc.Create.NewFamilyInstance(point, symbol, Level, structuralType);
Reference s= newPile.GetReferenceByName("SS");
// Get the reference plane named "SS" from the family instance

//uidoc.Selection.PickObject(ObjectType.PointOnElement);
Dimension alignToLine3 = doc.Create.NewAlignment(viewPlan, m1.GeometryCurve.Reference, s);

}
}

0 Likes
Message 4 of 10

ahmadkhalaf7892
Advocate
Advocate

here is the full constructor in case needed : 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Document = Autodesk.Revit.DB.Document;

namespace Tunnel
{
public class SheetPile
{
double meters = 3.28084;

public SheetPile(Document doc, double x, String PileName, Level Level, TunnelFloors tunnelFloors)
{

Options options = new Options();
Plane plane = Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 0));
SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
// Create a new view plan for Level 1
// Get the floor plan view family type
ViewFamilyType viewFamilyType = new FilteredElementCollector(doc)
.OfClass(typeof(ViewFamilyType))
.Cast<ViewFamilyType>()
.FirstOrDefault(v => v.ViewFamily == ViewFamily.StructuralPlan);
// Create a new view plan for Level 1

ViewPlan viewPlan = ViewPlan.Create(doc, viewFamilyType.Id, Level.Id);
// Convert input values from feet to meters
x = x * meters;

// Define the family symbol and structural type
FamilySymbol symbol = new FilteredElementCollector(doc)
.OfClass(typeof(FamilySymbol))
.OfCategory(BuiltInCategory.OST_StructuralColumns)
.FirstOrDefault(e => e.Name == PileName) as FamilySymbol;
StructuralType structuralType = StructuralType.Column;

// Create a list of curves
List<Curve> curves = new List<Curve>();
foreach (Floor floor in tunnelFloors.Floors)
{
Sketch sketch = doc.GetElement(floor.SketchId) as Sketch;
foreach (CurveArray curveArray in sketch.Profile)
{
foreach (Curve curve in curveArray)
{
XYZ p0 = (new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, 0));
XYZ p1 = (new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, 0));
Curve c1 = Line.CreateBound(p0, p1);
curves.Add(curve);
}

}
}

foreach (Curve curve in curves)
{

ModelCurve m1 = doc.Create.NewModelCurve(curve, sketchPlane);
// Move the family instance along the curve by the distance variable
double length = curve.Length;
int count = (int)(length / x);
for (int j = 1; j <= count; j++)
{
XYZ point = curve.Evaluate((double)j * x / length, true);
FamilyInstance newPile = doc.Create.NewFamilyInstance(point, symbol, Level, structuralType);
newPile.LookupParameter("Top Level").Set("Level 2");
Reference s = newPile.GetReferenceByName("SS");
// Get the reference plane named "SS" from the family instance

//uidoc.Selection.PickObject(ObjectType.PointOnElement);
doc.Create.NewAlignment(viewPlan, s, curve.Reference);

}
}
}

}
}

Message 5 of 10

jeremy_tammik
Alumni
Alumni

Did you read the remarks in the Revit API docs?

  

  

> These references must be already geometrically aligned (this function will not force them to become aligned).

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 6 of 10

ahmadkhalaf7892
Advocate
Advocate
Ah Sorry , I have been working on this for hours . I'm loosing my concentration , I didn't pay attention to it .
Is there any way I can force Them to be aligned using the Revit API?
I have been trying for the past 4 hours. If it is a dead end please inform me .
Thanks very much.
0 Likes
Message 7 of 10

jeremy_tammik
Alumni
Alumni

Take a rest! Go for a walk!

  

The easiest way to ensure they are aligned is to create them accordingly in the first place, if they are being generated from scratch. Otherwise, you can use the standard translation and rotation functionality provided by ElementTransformUtils. Or, you can set the location curve via the Location property.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 8 of 10

ahmadkhalaf7892
Advocate
Advocate
I will rest for a few then see which approach fits better. I am using a family which is already loaded in the Project and I am placing them on a line with a specific distance . However I want them to rotate according to the Curve or Line they are placed on. I haven't been able to do such thing. I will see what I can do .
I should use the ElementTransformUtils.Rotate in this case ?
I really appreciate the help Jeremy
0 Likes
Message 9 of 10

jeremy_tammik
Alumni
Alumni
Accepted solution

Either ElementTransformUtils.Rotate or just manipulate the LocationPoint or LocationCurve via Rotate, e.g.:

  

  

Enjoy your break.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 10 of 10

jeremy_tammik
Alumni
Alumni

Thank you for this chat. I hope you got it sorted now and are well rested and satisfied. I shared our conversation on the blog for future reference:

  

https://thebuildingcoder.typepad.com/blog/2023/05/aligning-elements-finding-and-visualising-wires.ht...

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes