Placing a Pipe Fitting in the middle of a Pipe

Placing a Pipe Fitting in the middle of a Pipe

Bruno_Neves_Pires_Silva
Advocate Advocate
4,003 Views
7 Replies
Message 1 of 8

Placing a Pipe Fitting in the middle of a Pipe

Bruno_Neves_Pires_Silva
Advocate
Advocate

Hello folks, 

 

     I need to place a Pipe Fitting in the middle of a pipe through API, can someone give me an idea ? See the attached image please.

I was thinking in the method uidoc.Document.Create.NewUnionFitting, but it needs two connectors, and I only have one.

 

Thanks in Advance.

 

 

Bruno Neves Pires Silva

4,004 Views
7 Replies
Replies (7)
Message 2 of 8

jeremytammik
Autodesk
Autodesk

Dear Bruno,

 

Thank you for your query.

 

Please look at my exploration on various ways to place pipes and fittings, documented in a whole series of posts on creating a roling offset:

 

http://thebuildingcoder.typepad.com/blog/2014/01/final-rolling-offset-using-pipecreate.html

 

As you can see from there, there are several ways to achieve this.

 

The simplest two are:

 

  • Place the pipes the way you want and then tell Revit to connect them. Fittings will be inserted automatically according to the routing preferences.
  • Place the fittings the way you want and then tell Revit to connect them. Pipes will be inserted automatically between them.

 

In this case, you have a pipe with fittings A and B at each end.

 

You could try to delete the pipe, insert a new fitting C in the middle, and then simply connect A to C and C to B.

 

I hope this helps.

 

Please let us know how it goes, especially if you end up with a nice, simple, interesting, generic, non-confidential code snippet to share.

 

Thank you!

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 3 of 8

Bruno_Neves_Pires_Silva
Advocate
Advocate

Hi, Jeremy.

 

   Thank you for your reply. Sorry for not answering before, I was attending in São Paulo DevDay yesterday.

 

   Jeremy, is not possible to place the fitting as you do in the interface manually? Because If I delete the pipe to draw 2 others as you said, I won't be able to undo the process (I.E: When i delete the fitting, there will be 2 pipes instead of 1). It would be a problem for me if for instance I want to change the spacing and number of fittings in the pipe.

 

 

  

0 Likes
Message 4 of 8

jeremytammik
Autodesk
Autodesk

Dear Bruno,

 

I do not know. Please try it out and let me know.

 

Regarding the two pipes instead of one: you can easily programmatically delete them and connect the fitting A with B again, re-creating your one single original pipe.

 

The rolling offset samples provide a large number of choices for you.

 

One of them will certainly fit your needs.

 

If not, I would suspect your needs require some careful revision  🙂

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 5 of 8

ameer.mansourWAK8Y
Advocate
Advocate

did you manage to solve that?

0 Likes
Message 6 of 8

Songohu_85
Enthusiast
Enthusiast

I had to make something similar. The tool that adds union on vertical pipe. We use a specific annotation tag on floor plans to show vertical pipe flow direction and diameters. The tagged element is not a pipe but pipe fitting so in some cases a dummy 1mm union family must be added. Perhaps you can use it:

 

public class PipeBreaker
{
    Pipe _pipe;
    XYZ _centerPoint;
    Document _document;
    List<Connector> _connectors;

    private PipeBreaker()
    {

    }

    public static PipeBreaker Initialize(ElementId pipeId, Document document)
    {
        PipeBreaker result = new PipeBreaker();
        result._document = document;
        result._pipe = document.GetElement(pipeId) as Pipe;
        result.SetCenterPoint();
        result.SetConnectors();
        return result;
    }

    public void UnionCreate(FamilySymbol familySymbol)
    {
        Level pipeRefLevel = _pipe.ReferenceLevel;
        using (Transaction tx = new Transaction(_document, "Create Union"))
        {
            tx.Start();
            FamilyInstance union = _document.Create.NewFamilyInstance(_centerPoint, familySymbol, pipeRefLevel, StructuralType.NonStructural);
            Parameter offset = union.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
            double offsetValue = _centerPoint.Z - pipeRefLevel.Elevation;
            offset.Set(offsetValue);
            RotateToVertical(union);
            SetDiameter(union);
            foreach (Connector connector in _connectors)
            {
                DrawPipe(connector, union);
            }
            _document.Delete(_pipe.Id);
            tx.Commit();
        }
    }

    private void RotateToVertical(FamilyInstance union)
    {
        Line axis = Line.CreateBound(_centerPoint, new XYZ(_centerPoint.X, _centerPoint.Y + 1, _centerPoint.Z));
        double angle = Math.PI / 180 * 90;
        ElementTransformUtils.RotateElement(_document, union.Id, axis, angle);
    }

    private void SetDiameter(FamilyInstance union)
    {
        Parameter diameter = union.LookupParameter("DN_connector1");
        diameter.Set(_pipe.Diameter);
    }

    private void SetCenterPoint()
    {
        LocationCurve lc = _pipe.Location as LocationCurve;
        Line line = lc.Curve as Line;
        IList<XYZ> points = line.Tessellate();
        XYZ point1 = points[0];
        XYZ point2 = points[1];
        _centerPoint = new XYZ((point1.X + point2.X) * 0.5, (point1.Y + point2.Y) * 0.5, (point1.Z + point2.Z) * 0.5);
    }

    private void SetConnectors()
    {
        _connectors = new List<Connector>();
        ConnectorManager cm = _pipe.ConnectorManager;
        ConnectorSet cSet = cm.Connectors;
        foreach (Connector c in cSet)
        {
            _connectors.Add(c);
        }
    }

    private void DrawPipe(Connector connector, FamilyInstance union)
    {
        ConnectorSet unionConnectors = (union.MEPModel as MechanicalFitting).ConnectorManager.Connectors;
        ElementId pipeTypeId = _pipe.GetTypeId();
        ElementId levelId = _pipe.ReferenceLevel.Id;
        if (connector.IsConnected)
        {
            Connector refElConnector = FindRefConnector(connector);
            Connector unionConnector = GetClosestConnector(connector.Origin, unionConnectors);
            Pipe pipe = Pipe.Create(_document, pipeTypeId, levelId, unionConnector, refElConnector);
            Parameter pipeDN = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
            pipeDN.Set(_pipe.Diameter);
        }
        else
        {
            XYZ endPoint = connector.Origin;
            Connector unionConnector = GetClosestConnector(endPoint, unionConnectors);
            Pipe pipe = Pipe.Create(_document, pipeTypeId, levelId, unionConnector, endPoint);
            Parameter pipeDN = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
            pipeDN.Set(_pipe.Diameter);
        }
    }

    private Connector GetClosestConnector(XYZ endPoint, ConnectorSet unionConectors)
    {
        Connector result = null;
        double distance = 0;
        foreach (Connector c in unionConectors)
        {
            if (result == null)
            {
                result = c;
                distance = c.Origin.DistanceTo(endPoint);
            }
            else
            {
                if (c.Origin.DistanceTo(endPoint) < distance) result = c;
            }
        }
        return result;
    }

    private Connector FindRefConnector(Connector connector)
    {
        Connector result = null;
        ConnectorSet cSet = connector.AllRefs;
        foreach (Connector c in cSet)
        {
            if (c.Owner.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeFitting
                || c.Owner.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeAccessory
                    || c.Owner.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PlumbingFixtures)
            {
                result = c;
            }
        }
        return result;
    }
}
Message 7 of 8

jeremytammik
Autodesk
Autodesk

Dear Marek @Songohu_85,

 

Thank you very much for your very nice solution.

 

It looks very useful indeed. I would like to try it out and maybe clean it up a bit.

 

What family symbol do you use when calling `UnionCreate`?

 

If it is special, could you share it with us, maybe in the form of a complete minimal reproducible case?

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#1b

 

Thank you!

 

Cheers,

 

Jeremy

 

P.S. I read your profile and other very helpful contributions since March this year. Thank you for your appreciation in those, and a warm welcome to the Revit API community!

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 8 of 8

Songohu_85
Enthusiast
Enthusiast

Dear Jeremy,

 

Thank you for warm welcome.

You will find example attached (R2019). It works only with vertical pipes though.

RotateToVertical() method could be replaced with method that adjusts the direction of a fitting to pipe direction.

 

Whenever I have time I will publish other parts of my solutions.

Many thanks again for your blog and contributions of others.

 

Kind regards

Marek Trawczynski