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:
- Get center line geomerty objects from pipes via Element.get_Geometry()
- 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:
- Make sure geometry options's ComputeReferences property is set to true, this ensures we can get the reference of the geometry objects retrieved.
- 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.
- 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; }