Zero touch FamilyInstance.ByCoordinates and MultiReturn

I’m trying to return three familyInstances by MulitReturn and I’m getting only one of them. I have also tried just creating them in this method by FamilyInstance.ByCoordinates without returning any, and result was pretty much the same, only one output. Right now I made workaround by splitting this method to 3 separate, but I would like to know why it didnt work. Here is the code:


And the result:

A bit of a guess but its probably Dynamo’s element binding when you call the FamilyInstance.ByCoordinates method. Each anonymous call deletes the last element from the document, so only the last family instance you create is output and all of them are pointing to the same memory address, which may explain why only 1 seemingly gets output. One way to check would be to assign each instance to a variable and pass these into your dictionary value keys.

Ideally though you should avoid calls to Dynamos libraries completely as its adding an unnecessary overhead to your program and gives you no control over say, element binding and the vast array of methods available in the Revit API.

I have tried returning it as variable before:


Didn’t work, I think I will follow your advice and re write it to Revit API library but I found it more difficult than Dynamo libraries. I will let you know if i made it.

@Thomas_Mahon Following your advice I re-wrote the code. It took me whole day to learn basics of Revit API library, but I think it was worth it. From here I would like to recommend this Lab, it covered almost everything what I needed to write this. I’m also leaving here the code.

    //Create plate sections
    [MultiReturn(new[] { "BaseFamilyinstance", "NegativeFamilyInstance", "PositiveFamilyInstance" })]
    public static Dictionary<string,object> CreatePlateSection(double negativeDistance,double positiveDistance)
    {
        //Set document as current document
        Document document = RevitServices.Persistence.DocumentManager.Instance.CurrentDBDocument;
        //Collect FamilySymbols
        var symbolCollector = new FilteredElementCollector(document)
            .OfClass(typeof(FamilySymbol));
        //Get BaseSection FamilySymbol
        FamilySymbol baseSectionSymbol = symbolCollector
            .Where(x => ((FamilySymbol)x).Name.Equals("BaseSection"))
            .Cast<FamilySymbol>()
            .FirstOrDefault();
        //Get NegativeSection FamilySymbol
        FamilySymbol negativeSectionSymbol = symbolCollector
            .Where(x => ((FamilySymbol)x).Name.Equals("NegativeSection"))
            .Cast<FamilySymbol>()
            .FirstOrDefault();
        //Get PositiveSection FamilySymbol
        FamilySymbol positiveSectionSymbol = symbolCollector
            .Where(x => ((FamilySymbol)x).Name.Equals("PositiveSection"))
            .Cast<FamilySymbol>()
            .FirstOrDefault();
        //Get BaseSection plate and cornice height
        double baseHeight = baseSectionSymbol.LookupParameter("Wysokość").AsDouble();
        double baseCorniceHeight = baseSectionSymbol.LookupParameter("Wysokość gzymsu nad płytą").AsDouble();
        //Calculate NegativeSection plate and cornice height
        double negativeHeight = baseHeight - Math.Abs(mmToFeet(negativeDistance)) * 0.02;
        double negativeCorniceHeight = baseCorniceHeight + Math.Abs(mmToFeet(negativeDistance)) * 0.02;
        //Calculate PositiveSection plate and cornive height
        double positiveHeight = baseHeight - Math.Abs(mmToFeet(positiveDistance)) * 0.02;
        double positiveCorniceHeight = baseCorniceHeight + Math.Abs(mmToFeet(positiveDistance)) * 0.02;
        //Insert location of BaseSection
        XYZ pointBaseSection = new XYZ(0, 0, 0);
        //Insert location of NegativeSection
        XYZ pointNagativeSection = new XYZ(0,mmToFeet(negativeDistance),0);
        //Insert location of PositiveSection
        XYZ pointPositiveSection = new XYZ(0,mmToFeet(positiveDistance),0);
        //Create new transaction
        using (Transaction transaction = new Transaction(document,"Create BaseSEction"))
        {
            transaction.Start();

            //Change NegativeSection FamilySymbol parameters
            negativeSectionSymbol.LookupParameter("Wysokość").Set(negativeHeight);
            negativeSectionSymbol.LookupParameter("Wysokość gzymsu nad płytą").Set(negativeCorniceHeight);
            //Change PositiveSection FamilySymbol parameters
            positiveSectionSymbol.LookupParameter("Wysokość").Set(positiveHeight);
            positiveSectionSymbol.LookupParameter("Wysokość gzymsu nad płytą").Set(positiveCorniceHeight);
            //Create BaseSection FamilyInstance
            FamilyInstance baseSectionFamilyInstance = document.FamilyCreate
                .NewFamilyInstance(pointBaseSection, baseSectionSymbol, Autodesk.Revit.DB.Structure.StructuralType.UnknownFraming);
            //Create NegativeSection FamilyInstance
            FamilyInstance negativeSectionFamilyInstance = document.FamilyCreate
                .NewFamilyInstance(pointNagativeSection, negativeSectionSymbol, Autodesk.Revit.DB.Structure.StructuralType.UnknownFraming);
            //Create PositiveSection FamilyInstance
            FamilyInstance positiveSectionFamilyInstance = document.FamilyCreate
                .NewFamilyInstance(pointPositiveSection, positiveSectionSymbol, Autodesk.Revit.DB.Structure.StructuralType.UnknownFraming);
            transaction.Commit();
            //Retrun FamilyInstances                     
            return new Dictionary<string, object>
            { 
            { "BaseFamilyinstance", baseSectionFamilyInstance},
            { "NegativeFamilyInstance", negativeSectionFamilyInstance },
            { "PositiveFamilyInstance", positiveSectionFamilyInstance }
            };
                          
        }
        
    }

1 Like