RevitAPI: Align 2 pipes through center lines

By Aaron Lu

A customer wants to use RevitAPI to align 2 pipes through their centerlines, I think it is feasible, here is what I plan to do:

  1. Get center line geomerty objects from pipes via Element.get_Geometry()
  2. Create the alignment via RevitDoc.Create.NewAlignment()

But however, I got an ArgumentException saying: One of the conditions for the inputs was not satisfied. Consult the documentation for requirements for each argument.

Headache…

With the help of Phil from development team in China, I made it work, the key point is that I should first move the pipe to align with the other physically. Just like what documentation says:

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

I did so, and it works, happy!

Here are the keys of the achievement:

  1. Make sure geometry options’s ComputeReferences property is set to true, this ensures we can get the reference of the geometry objects retrieved.
  2. Make sure geometry options’s IncludeNonVisibleObjects is set to true and View property is set to plan view, this ensures we can get the geometry of the hidden centerline.
  3. Make sure the pipes are geometrically aligned, e.g. by calling ElementTransformUtils.MoveElement() method.

Here is the whole code:

//Assume the 2 pipes are parallel
//Assume the ActiveView is a plan view
private static Dimension
Align2PipesViaCenterline(Pipe pipeBase, Pipe pipe)
{
Dimension dimension = null;
Document doc = pipeBase.Document;
View view = doc.ActiveView;
Line baseLine = GetCenterline(pipeBase);
if (baseLine == null) return null;
Line line = GetCenterline(pipe);
if (line == null) return null;
var clone = line.Clone();
clone.MakeUnbound();
IntersectionResult result = clone.Project(baseLine.Origin);
if (result != null)
{
var point = result.XYZPoint;
var translate = baseLine.Origin - point;
using (Transaction transaction = new Transaction(doc))
{
try
{
transaction.Start("Align pipes");
ElementTransformUtils.MoveElement(
doc, pipe.Id, translate);
dimension = doc.Create.NewAlignment(view,
baseLine.Reference, line.Reference);
transaction.Commit();
}
catch (Exception ex)
{
Trace.WriteLine(ex.ToString());
transaction.RollBack();
}
}
}
return dimension;
}
private static Line GetCenterline(Pipe pipe)
{
Options options = new Options();
options.ComputeReferences = true; //!!!
options.IncludeNonVisibleObjects = true; //!!!
if (pipe.Document.ActiveView != null)
options.View = pipe.Document.ActiveView;
else
options.DetailLevel = ViewDetailLevel.Fine;
var geoElem = pipe.get_Geometry(options);
foreach (var item in geoElem)
{
Line lineObj = item as Line;
if (lineObj != null)
{
return lineObj;
}
}
return null;
}

Comments

3 responses to “RevitAPI: Align 2 pipes through center lines”

  1. Best Corporate web design company sharjah aims towards customized web design. We offer designs at a competitive rate. web design sharjah

  2. Aaron, thanks for this in-depth tutorial. Still useful in 2021.

  3. ning zhou Avatar
    ning zhou

    tried using pipe location (curve), don’t know why it’s not working?

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading