Hypar.MEP is a library of Elements to help create connected networks of fittings for MEP systems. It provides support for creating sized networks connecting equipment together with the Tree class, as well as creating dimensionally accurate and well-connected fittings using the FittingTree. Additionally, it provides a utility for building a Tree from automatic routing created from an AdaptiveGrid in the Elements library.
The library currently supports connecting terminal points with networks of components where the components have round profiles. To date, this has mostly been piping, but there is an example of conduit in this repository, and round ducts should work just the same.

API highlights

Connecting terminal points together has two high level concepts, a Tree and a FittingTree. The Tree represents the path and rough size of the network that connects the terminal points, and the FittingTree represents the specific fittings that are used to connect the terminal points. Conceptually, you should think of making a Tree that represents the path your system should take, and then the FittingTree will be generated from that according to the rules of the FittingTreeRouting, which can be customized.


Often called Flow Tree, Tree is a relatively simple graph that focuses on always maintaining internal connectivity. Systems on Hypar emphasize always being connected as a first principle, so there should be no orphaned terminals once they are added to a Tree. The Tree is also responsible for maintaining the rough size of the network, which is used to determine the size of the fittings that will be used to connect the terminals.


  • Node - points in the graph
    • Trunk - The (normally) singular start point
    • Leaf - The endpoints of the graph
  • Connection - an edge in the graph that connects two nodes
  • Section - a collection of connections that are all in a line with no "branching" at any of the nodes

Key methods

  • AddInlet
  • SetOutletPosition
  • Simplify
Data access method
  • GetOutgoingConnection
  • GetIncomingConnections
The following methods let you modify a Tree in various useful ways while maintaining connectivity:
  • ChamferAtNode
  • ConnectVertically
  • NormalizeConnectionPath
  • MergeConnectionsAtPoint
  • ShiftConnectionToNode
  • SplitConnectionThroughPoint


The FittingTree is what manages the actual fittings that make up a real-world connected system. FittingTrees are created from the FittingTreeRouting class which provides a number of ways to customize how the FittingTree is created. The customizations are almost all at the individual fitting level, and the FittingTree/Routing objects handle stitching the individual fitting behaviors into a comprehensive system. You customize a FittingTreeRouting to have the settings you want and then call the BuildFittingTree method to create the FittingTree. You can either pass in a Tree to that method or have a Tree assigned to the FittingTreeRouting and it will use that when building the FittingTree.


ComponentBase - Base class for items in a FittingTree
Port - The endpoints of fittings, where they can be connected to each other or connected by StraightSegments
Fitting - Items in a FittingTree that occur at Nodes in a Tree
StraightSegment - An element that connects two spatially separated Fittings. They generally reference the Ports on Fittings although this may not always persist through serialization.
Assembly - contains multiple Fitting and StraightSegment elements internal to itself. It’s internal components are treated as top level objects in the FittingTree for most operations.
There are whole system customizations and Fitting creation customizations.

System Wide Customizations

  • PressureCalculator - Implements pressure drop calculations for each of the fittings.
  • FlowCalculator - Implements flow calculations for the whole system. By default, it assumes full flow, but there are other implementations that seek to increase accuracy for some use cases.
  • FittingCatalog - an optional catalog of fittings that will be used when choosing parts for the FittingTree. Intended to help avoid needing to customize the individual fitting creation methods listed below.

Fitting Creation Methods

For deep customization you can override any/all of the methods below to customize how fittings are created:
  • BranchPipe
  • ReduceOrJoin
  • ManifoldPipe
  • TerminatePipe
  • ChangeDirection
  • ChangePipe

Sample Tree And Fitting Creation

using Elements.Flow; using Elements.Fittings; var tree= new Tree(new[] {"Room-101"}); tree.SetOutletPosition((0,-1,0)); var inlet1 = tree.AddInlet((-1,1,0), 1); var inlet2 = tree.AddInlet((-1,5,0), 2); var inlet3 = tree.AddInlet((1,2,0), 3); var connection1 = tree.GetOutgoingConnection(inlet1); var connection2 = tree.GetOutgoingConnection(inlet2); var node= tree.MergeConnectionsAtPoint(new List<Connection> {connection1, connection2}, (0,1,0)); // connection1 is a new connection after the previous change connection2 = tree.GetOutgoingConnection(inlet2); var connection3 = tree.GetOutgoingConnection(inlet3); tree.ShiftConnectionToNode(connection3, node); tree.MergeConnectionsAtPoint(new List<Connection> {connection2, connection3}, (0,2,0)); connection2 = tree.GetOutgoingConnection(inlet2); tree.NormalizeConnectionPath(connection2, Vector3.ZAxis, Vector3.XAxis, 90, Tree.NormalizationType.End); // Create fittings using the default routing options. var fittings = new FittingTreeRouting(tree).BuildFittingTree(out var errors);

Powered by Notaku