MEPSystem Id From Element C#

MEPSystem Id From Element C#

smarente1
Enthusiast Enthusiast
2,909 Views
6 Replies
Message 1 of 7

MEPSystem Id From Element C#

smarente1
Enthusiast
Enthusiast

Hi, 

 

In python this works: 

 

 

 

picked = uidoc.Selection.PickObject(ObjectType.Element)
element = doc.GetElement(picked)
element_systemId = element.MEPSystem.GetTypeId() 

 

 

Now I am trying to replicate this in C#:

 

 

Reference selection1 = uidoc.Selection.PickObject(ObjectType.Element,p); 
Element element1 = doc.GetElement(selection1) as Element;
MEPSystem element_sys = element1 as MEPSystem; 
ElementId system_id = element_sys.GetTypeId();

 

 

And am getting an error of "object reference not set to an instance of an object" 

 

Any suggestions? 

0 Likes
Accepted solutions (1)
2,910 Views
6 Replies
Replies (6)
Message 2 of 7

jeremy_tammik
Alumni
Alumni

Step through this in the debugger and the error will become obvious.

 

In the code you have implemented, the C# variable element_sys is guaranteed to be null.

 

You can also navigate through your model using RevitLookup and the error will also become obvious.

 

So, what is the error?

 

In Python, you are selecting a duct or pipe element or fitting or something and querying it for its MEP system element using its MEPSystem property.

 

Your C# code is attempting to cast the same element to an MEPSystem object.

 

That is doomed to fail, I'm afraid.

 

Simply reference its property, just like you did in Python:

 

  MEPSystem element_sys = element1.MEPSystem;

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 7

smarente1
Enthusiast
Enthusiast

Thank you Jeremey for your detailed response! 

 

This still gives me an error: 

 

"MEPSystem does not contain a definition for 'MEPSystem' "

 

smarente1_0-1616000194524.png

 

 

 

0 Likes
Message 4 of 7

smarente1
Enthusiast
Enthusiast
Accepted solution

Figured out a solution. Casted the element to a MEP Curve before referencing its property MEPSystem. 

 

MEPCurve mepcurve = element1 as MEPCurve;
MEPSystem e1_sys = mepcurve.MEPSystem;
ElementId system_Id = e1_sys.GetTypeId();

 

If anyone has a simpler way please let me know.  

Message 5 of 7

Kevin.Lawson.PE
Advocate
Advocate

Hi Steve,

 

I think that probably works in Python because python will do some implicit type conversions (automatically convert the Element into a MEPCurve if possible).  I’m not a huge fan of that because I like to know what I am working with, it makes the code easier to read.

 

https://github.com/jeremytammik/RevitLookup and https://www.revitapidocs.com/ will be helpful as you convert from python to C#.

 

If you look at https://www.revitapidocs.com/ and type MEPSystem into the search bar you’ll see that only the MEPCurve and Connector class have the property MEPsystem.   That means you need to convert your element into a MEPCurve or get its Connector before calling the MEPSystem property.

 

So your solution will work as long as the selection can be converted to an MEPCurve, if the user selects a fitting, or a piece of mechanical equipment, your plugin will throw an error.   So first you can check if it’s an MEPcurve and if it is, convert it and get the system.

 

If you us RevitLookup to “Snoop” a fitting or a piece of mechanical equipment, you can see that fittings are FamilyInstances and if you click around the properties of a fitting you’ll be able to find how to get to the connectors through the MEPModel and ConnectionManager.

 

This is a lot of code to put inline with your main method, so you’ll probably want to make a second method that returns an MEPSystem given an Element.  This way you get the MEPSystem from and element anywhere in your code you need to without having to copy and paste.

 

Even after all that work, the user might make a selection that doesn’t have an MEPSystem, so you’ll still want to check for null.

 

 

 

public static void MainFunction(Document doc, ElementId selection1)
{
    Element element1 = doc.GetElement(selection1);
    MEPSystem mepSystem = FindFirstMEPSystem(element1);
    if(mepSystem == null)
    {
        MessageBox.Show("Select a pipe!", "Warning");
        return;
    }
    else
    {
        //complete your transaction. 
    }
}

public static MEPSystem FindFirstMEPSystem(Element element)
{
    MEPSystem mepSystem = null; //initialize an MEPSystem variable to return.
    if(element is MEPCurve) //check if the element is an MEPCurve
    {
        MEPCurve mepCurve = element as MEPCurve; //convert element to MEP curve
        mepSystem = mepCurve.MEPSystem; //get MEPSystem
        return mepSystem; //return MEPSystem. 
    }
    else if(element is FamilyInstance) //else check if the element is a family instance
    {
        FamilyInstance familyInstance = element as FamilyInstance;
        //a family instance may not have and MEPModel or a connector manager, so check those
        if(familyInstance.MEPModel != null && familyInstance.MEPModel.ConnectorManager!= null)
        {
            ConnectorSet connectorSet = familyInstance.MEPModel.ConnectorManager.Connectors;
            //cycle through each connector and return the first MEPSystem
            foreach (Connector connector in connectorSet)
            {
                mepSystem = connector.MEPSystem;
                return mepSystem;
                //if you're looking for a specific type of connector, you can check here.
                //for example if you want the first connector that is DomesticColdWater do:
                //if(connector.PipeSystemType == Autodesk.Revit.DB.Plumbing.PipeSystemType.DomesticColdWater)
                //{
                //    mepSystem = connector.MEPSystem;
                //    return mepSystem;
                //}
            }
        }
    }
    //If the element wasn't an MEPCurve or a FamilyInstance, or the family Instance didn't have connectors
    //we will return mepSystem which is still null. 
    return mepSystem;
}

 

 

 

Hopefully this helps makes up for the fact that you can’t debug your software while our software is installed 😊 We’re still working on that by the way!


Faster Heating and Cooling Load Calculations with Fewer Errors:
https://RippleEngineeringSoftware.com
-Kevin Lawson, PE
www.rippleengineeringsoftware.com
Revit heating and cooling load calculations in one click!
Message 6 of 7

Lee_Hammarback_x3001
Explorer
Explorer
amazing thanks!
0 Likes
Message 7 of 7

lukasz_koc2
Contributor
Contributor

Hi,

@Kevin.Lawson.PE 
Can we somehow access the first element of connector set?
Similiar to python by adding [0] at the end? 
the only way i found was to rewrite this to List<connector> and than access but maybe there is a simpler way ? 

0 Likes