Placing element between two other elements

Hello everyone,

I would like to make dynamo that place one element between two other elements. This will be a weld located between pipe and pipe fitting. I prepared something but it doesn’t work how it was supposed to.

Please help !

Welcome!

If you haven’t already, I would highly suggest working through the Dynamo Primer, getting familiar with all the basics (don’t skip anything!), and practicing with some of the examples. You’ll want to pay particular attention to the sections dealing with Revit element interactions and geometry.

Your process should end up looking roughly something like this:

  1. Get pipe and fitting locations (geometry)
  2. Locate intersection of geometry (point)
  3. Place weld element at point

If this sounds like the graph you’ve already built, then it would be helpful if you shared an image of your graph in action, with all the node preview bubbles pinned so we can see your data, and any errors or warnings that you’re getting. (I’ve escalated your user level to ensure that you can upload screenshots.)

I’ll also add that this may actually be more complicated than you would think if you’re expecting fully connected pipe systems. Assuming your pipe and fitting are already connected, you would have to disconnect and offset the pipe enough to place the new weld instance and reconnect the network. Adding an embedded weld family to your fittings might be an easier solution.

Hi !

Thank you for your response. Yes, I’ve already build a dynamo but I have a few problems:

  • weld shoud have appropriate dimension and should be connected to the whole installation. My dynamo only place element in the right location. The right dimension is necessary for this project.
  • Welds are duplicated becaue in the connection between pipe and pipe fitting dynamo place welds comming from both elements. I tried to delete duplicate welds but it seems like it doesn’t work how it should every time.

I attach my dynamo.

Add_weld.dyn (77.2 KB)

Please help!

When taking screenshots, make sure you use Export as Image so that we can see everything. Right now you’re zoomed so far out that the node titles are missing. You’re also missing a few preview bubbles.

If you have a small test file for us to test your graph with, that would be very helpful. I’d also recommend including an example of what “good” looks like in that file so we can compare.

Hi!

This is exactly how I took the screenshot. When I open it seems to be readable.

I attach my test file. It’s too big so please find wetransfer link:

Thank you

Hello,

I’ve clean up my dynamo and decided to solve problems one by one. I’ve started by setting up the right diameter. It’s working correcly but only if I select a few elements. If I choose all the elements from my model it’s not working properly. Can you have a look at this?

Add_weld.dyn (69.0 KB)

I also don’t remember if I attached the family I’m working with.

EMEP_Weld.rfa (444 KB)

Thank you.

Hi
It’s not really advisable to place a fitting between another fitting and a pipe (the slightest change to the pipe will cause the fitting to disappear)

Nevertheless, here’s a solution using Python (need to adapt to your project)

import clr
import sys
import System
from System import Array
from System.Collections.Generic import List, IList, Dictionary, HashSet

#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Structure import *

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc: DB.Document = DocumentManager.Instance.CurrentDBDocument 

    
def get_FamilyInstance_direction(elem):
    connectors = [c for c in elem.MEPModel.ConnectorManager.Connectors if c.Domain in [Domain.DomainPiping, Domain.DomainHvac]]
    pta, ptb = sorted([c.Origin for c in connectors], key = lambda p : p.X)
    pta, ptb = [c.Origin for c in connectors]
    return DB.Line.CreateBound(pta, ptb).Direction.Normalize(), connectors
    
toList = lambda x : x if hasattr(x, "__iter__") and not isinstance(x, (str, System.String)) else [x]

#Preparing input from dynamo to revit
lst_fittings = toList(UnwrapElement(IN[0]))
fitting_type = UnwrapElement(IN[1])
radius_name_para = IN[2]

out = []
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for elem  in lst_fittings:
    level = doc.GetElement(elem.LevelId)
    for con in elem.MEPModel.ConnectorManager.Connectors:
        con: DB.Connector 
        radius = con.Radius 
        c_system = con.CoordinateSystem
        flow_direction = c_system.BasisZ
        #
        try :
            v_axis = flow_direction.CrossProduct(XYZ.BasisX)
            axis = Line.CreateUnbound(con.Origin, v_axis)
        except:
            v_axis = flow_direction.CrossProduct(XYZ.BasisY)
            axis = Line.CreateUnbound(con.Origin, v_axis)
        #
        if con.IsConnected:
            for conref in con.AllRefs:
                conref: DB.Connector 
                if conref.ConnectorType == ConnectorType.End and conref.Owner.Category.Id == ElementId(BuiltInCategory.OST_PipeCurves):
                    fitting_conA = con
                    fitting_conB = conref
                    fitting_conA.DisconnectFrom(fitting_conB)
                    # create instance
                    if not fitting_type.IsActive:
                        fitting_type.Activate()
                    #
                    newfam = doc.Create.NewFamilyInstance(fitting_conA.Origin, fitting_type, level, StructuralType.NonStructural)
                    newfam.LookupParameter(radius_name_para).Set(radius)
                    doc.Regenerate()
                    # get direction of familyInstance by connectors position
                    v1, new_connectors = get_FamilyInstance_direction(newfam)
                    print(f"v1={v1.ToString()}")
                    if v1 is not None:
                        # check if vectors are Clockwise
                        factor = 1 if v1.CrossProduct(flow_direction).Z > 0.01 else -1
                        angle = v1.AngleTo(flow_direction)
                        # align direction of familyinstance
                        ## rotate if verticale
                        if abs(c_system.BasisZ.Z) > 0.99 :
                            DB.ElementTransformUtils.RotateElement(doc, newfam.Id, axis, factor * angle )
                        ## if horizontal redifine the axis 
                        else:
                            axis = Line.CreateBound(fitting_conA.Origin, fitting_conA.Origin + XYZ(0,0,1))
                            DB.ElementTransformUtils.RotateElement(doc, newfam.Id, axis, factor * angle )
                        #
                        doc.Regenerate()
                        # connect connectors to pipes/ducts 
                        # sort connectors by direction of connector Connector.CoordinateSystem.BasisZ
                        order_new_connectors = sorted(new_connectors, 
                                                    key = lambda c :  
                                                        c.CoordinateSystem.BasisZ.DotProduct(fitting_conA.CoordinateSystem.BasisZ))
                        #
                        new_closest_connA, new_closest_connB = order_new_connectors
                        # move new fitting correctly
                        DB.ElementTransformUtils.MoveElement(doc, newfam.Id, fitting_conA.Origin - new_closest_connA.Origin)
                        #
                        doc.Regenerate()
                        # connect
                        fitting_conA.ConnectTo(new_closest_connA)
                        fitting_conB.ConnectTo(new_closest_connB)
                        # move the end connector of pipe to the new fiiting
                        fitting_conB.Origin = new_closest_connB.Origin
                    
                    out.append(newfam)

TransactionManager.Instance.TransactionTaskDone()

OUT = out

It might be wiser to modify your pipe fitting families to include the weld element.

2 Likes