Issue API - How to Change Fitting Diameter

Issue API - How to Change Fitting Diameter

ricaun
Advisor Advisor
3,862 Views
5 Replies
Message 1 of 6

Issue API - How to Change Fitting Diameter

ricaun
Advisor
Advisor

Hello,

 

I'm trying to create a code to change the size of the conduit and the fittings connected.

To change the size of the conduit is easy, this code do the job.

 

Parameter parameter = ele.get_Parameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM);

 

 

The problem is on the fitting family, don't have any BuiltInParameter...

So I try to select the Connector and change the Radius value.

Kinda works but only with round values... When I try to apply a unround number I receive a ArgumentOutOfRangeException.

 

I'm using Revit 2018 and I don't if this ArgumentOutOfRangeException is a bug or has a better way to change Connector size.

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes
Accepted solutions (1)
3,863 Views
5 Replies
Replies (5)
Message 2 of 6

MarryTookMyCoffe
Collaborator
Collaborator

are you sure you use right units? Remember that every thing is in feet.

-------------------------------------------------------------
--------------------------------|\/\/|------------------------
do not worry it only gonna take Autodesk 5 years to fix bug
0 Likes
Message 3 of 6

ricaun
Advisor
Advisor

I know the unit is feet. (1 = 609.600 mm)

 

This is my macro code, but is only works when I put the Radius to 1, 2, 3 etc.

 

 

 /*
 * Created by SharpDevelop.
 * User: ricau
 * Date: 13/03/2019
 * Time: 11:14
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;

namespace ChangeSize
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("1B7B8078-5C56-4D16-A6C4-D0C7370EAFA9")]
    public partial class ThisApplication
    {

        public void SelectConduitSize(){
            Document doc = ActiveUIDocument.Document;
            Selection sec = ActiveUIDocument.Selection;
            ICollection<ElementId> selectedIds = sec.GetElementIds();
            
            List<Element> list = new List<Element>();
            
            if (selectedIds.Count == 0){
                Reference obj = sec.PickObject(ObjectType.Element);
                if (obj != null) {
                    Element e = doc.GetElement(obj.ElementId);
                       list.Add(e);
                }
            }
            else
            {
                foreach (ElementId id in selectedIds)
                {
                   Element e = doc.GetElement(id);
                   list.Add(e);
                }
            }
            
            if (list.Count > 0){
                                
                Transaction trans = new Transaction(doc);
                trans.Start("SelectConduitSize");
                
                foreach (Element e in list) {
                    ConnectorSet conns = GetConnectors(e);
                    if (conns != null)
                    {
                        foreach (Connector conn in conns)
                        {
                            if (conn.Shape == ConnectorProfileType.Round)
                            {
                                conn.Radius = 0.1;
                            }
                        }
                    }
                    
                }
                trans.Commit();
            }
            
        }
        
        private static ConnectorSet GetConnectors(Element element)
        {
            if (element == nullreturn null;
            try { 
                FamilyInstance fi = element as FamilyInstance;
                if (fi != null && fi.MEPModel != null)
                {
                    return fi.MEPModel.ConnectorManager.Connectors;
                }
                MEPSystem system = element as MEPSystem;
                if (system != null)
                {
                    return system.ConnectorManager.Connectors;
                }
                MEPCurve duct = element as MEPCurve;
                if (duct != null)
                {
                    return duct.ConnectorManager.Connectors;
                }
            }
            catch (Exception)
            {
                
            }
            return null;
        }
        
        private void Module_Startup(object sender, EventArgs e)
        {

        }

        private void Module_Shutdown(object sender, EventArgs e)
        {

        }

        #region Revit Macros generated code
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(Module_Startup);
            this.Shutdown += new System.EventHandler(Module_Shutdown);
        }
        #endregion
    }
}

 

 

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes
Message 4 of 6

warnerjonn
Community Visitor
Community Visitor

The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method. Indexing an empty list will always throw an exception. Use a method like Add to append the item to the end of the list, or Insert to place the item in the middle of the list somewhere, etc. You cannot index into a list if that offset doesn't exist.

 

Typically, an ArgumentOutOfRangeException results from developer error. Instead of handling the exception in a try/catch block, you should eliminate the cause of the exception or, if the argument is returned by a method call or input by the user before being passed to the method that throws the exception, you should validate arguments before passing them to the method.

 

0 Likes
Message 5 of 6

aignatovich
Advisor
Advisor
Accepted solution

Hi!

Fittings are user families, so, element connector diameter is usually associated with a family parameter. You need to identify it:

private Parameter GetAssociatedParameter(BuiltInParameter connectorParameter)
{
	var connectorInfo = (MEPFamilyConnectorInfo) connector.GetMEPConnectorInfo();

	var associatedFamilyParameterId = connectorInfo.GetAssociateFamilyParameterId(new ElementId(connectorParameter));

	if (associatedFamilyParameterId == ElementId.InvalidElementId)
		return null;

	var document = accessory.Document;

	var parameterElement = document.GetElement(associatedFamilyParameterId) as ParameterElement;

	if (parameterElement == null)
		return null;

	var paramterDefinition = parameterElement.GetDefinition();

	return accessory.get_Parameter(paramterDefinition);
}

 

Then get associated diameter parameter:

var diameterParameter = GetAssociatedParameter(BuiltInParameter.CONNECTOR_DIAMETER);

This parameter could be null in case when radius parameter is used instead:

var radiusParameter = GetAssociatedParameter(BuiltInParameter.CONNECTOR_RADIUS);

In all cases you need to perform some checks. First of all both parameters could be null. Secondly parameter could be read only. These issues should be addressed to the fitting family author.

 

P.S. I use connector in the first piece of code. You can get it from project family instance using MEPModel property:

var connector = fitting.MEPModel?.ConnectorManager.Connectors.Cast<Connector>().FirstOrDefault(x => x.ConnectorType == ConnectorType.End);
 
Message 6 of 6

ricaun
Advisor
Advisor

@aignatovich Great solution, I was trying to solve this problem and I didn't know the 'GetAssociateFamilyParameterId' function.

 

It probably makes more sense to me if the 'GetAssociatedParameter' has the Element and Connector parameter.

 

The full sample to select the parameter associated with the connector.

public void SelectConduitSize()
        {
            Document doc = ActiveUIDocument.Document;
            Selection sec = ActiveUIDocument.Selection;
            ICollection<ElementId> selectedIds = sec.GetElementIds();

            List<Element> elements = new List<Element>();

            if (selectedIds.Count == 0)
            {
                Reference obj = sec.PickObject(ObjectType.Element);
                if (obj != null)
                {
                    Element e = doc.GetElement(obj.ElementId);
                    elements.Add(e);
                }
            }
            else
            {
                foreach (ElementId id in selectedIds)
                {
                    Element e = doc.GetElement(id);
                    elements.Add(e);
                }
            }

            if (elements.Count > 0)
            {
                string str = "";
                foreach (Element element in elements)
                {
                    ConnectorSet connectors = GetConnectors(element);
                    if (connectors != null)
                    {
                        str += $"Element: {element.Id}\n";
                        foreach (Connector connector in connectors)
                        {
                            var parDId = GetAssociatedParameter(element, connector, BuiltInParameter.CONNECTOR_DIAMETER);
                            if (parDId != null)
                            {
                                str += $"\t Diameter: {parDId.Id}\n";
                            }
                            var parRId = GetAssociatedParameter(element, connector, BuiltInParameter.CONNECTOR_RADIUS);
                            if (parRId != null)
                            {
                                str += $"\t Radius: {parRId.Id}\n";
                            }
                        }

                    }
                }
                TaskDialog.Show("GetAssociatedParameter", str);
            }

        }

        private Parameter GetAssociatedParameter(Element element, Connector connector, BuiltInParameter connectorParameter)
        {
            var connectorInfo = connector.GetMEPConnectorInfo() as MEPFamilyConnectorInfo;

            if (connectorInfo == null)
                return null;

            var associatedFamilyParameterId = connectorInfo.GetAssociateFamilyParameterId(new ElementId(connectorParameter));

            if (associatedFamilyParameterId == ElementId.InvalidElementId)
                return null;

            var document = element.Document;

            var parameterElement = document.GetElement(associatedFamilyParameterId) as ParameterElement;

            if (parameterElement == null)
                return null;

            var paramterDefinition = parameterElement.GetDefinition();

            return element.get_Parameter(paramterDefinition);
        }

        private static ConnectorSet GetConnectors(Element element)
        {
            if (element == null) return null;
            try
            {
                FamilyInstance fi = element as FamilyInstance;
                if (fi != null && fi.MEPModel != null)
                {
                    return fi.MEPModel.ConnectorManager.Connectors;
                }
                MEPSystem system = element as MEPSystem;
                if (system != null)
                {
                    return system.ConnectorManager.Connectors;
                }
                MEPCurve duct = element as MEPCurve;
                if (duct != null)
                {
                    return duct.ConnectorManager.Connectors;
                }
            }
            catch (Exception)
            {

            }
            return null;
        }

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes