Using C# to create revit element in dynamo issue

Hi!
I’m using Revit 2017 and Dynamo 1.3.2. I tried to add some grids in revit by C# codes. My code is like this:

using Autodesk.DesignScript.Geometry;
using Revit.Elements;
using System;
using System.Collections.Generic;
using System.Linq;

namespace DynamoDLLTest
{
    public static class DLLTest
    {
        public static List<double> GetHorizontalSpace()
        {
            List<double> results = new List<double>();
            results.Add(0);
            results.Add(5000);
            results.Add(6200);
            results.Add(5000);
            results.Add(7700);
            results.Add(8000);
            results.Add(4000);
            return results;
        }

        public static List<Grid> AddGrids()
        {
            List<double> results = GetHorizontalSpace();
            double x = 0 - results.Sum() / 2;
            double y = -10000;
            double length = 20000;
            List<Grid> grids = new List<Grid>();

            foreach (double space in results)
            {
                x += space;
                Point start = Point.ByCoordinates(x, y);
                Point end = Point.ByCoordinates(x, y + length);

                grids.Add(Grid.ByStartPointEndPoint(start, end));

                start.Dispose();
                end.Dispose();
            }
            return grids;
        }
    }
}

My issue is since the second time when the grids.Add() was called, the last grid was added becomes null.
The code should add seven grids, but when the method return, the first six are all null, only the last one has been created successfully.
Could anyone tell me where am I wrong? Thanks!

I fail to understand why you are using C# nodes to duplicate Dynamo’s functionality inside of Dynamo.

image

If you don’t like the built in nodes, and instead want to do this on your own, I would probably recommend to use the Revit API calls instead of the wrapped up DynamoRevit methods. I mean, using those you are incurring all of the overhead that comes with wrapping all of these elements into Dynamo library.

Ps. Try not disposing of the two points inside of the loop. I have a feeling you are disposing of their references there and that kills the Grid.

4 Likes

Thank you for your reply!
I simply try to use different ways to generate elements. I did tried to use C# code to return points, then use the Grid.ByStartPointEndPoint node to generate grids, it worked fine. I also tested using C# code to return lines and using Grid.ByLine node instead, it worked too.
I don’t think those disposing statements caused this problem, the method is almost the same to the method that I used to return lines, I simply changed the List to List and Line.ByStartPointEndPoint to Grid.ByStartPointEndPoint, and the problem occured.
It look like I better not to code in this way.
Thanks again!

Looking quickly at your code without testing I think you’re missing a “Transaction” start and commit. The API will not let you make changes in Revit without a transaction.

Example of creating a simple gridline.
http://www.revitapidocs.com/2016/bd1e69e9-961e-1c07-f70a-a29b90c6eb97.htm

public bool CreateGrid(Autodesk.Revit.DB.Document document, XYZ p1, XYZ p2)
{
// All and any transaction should be enclosed in a 'using'
// block or guarded within a try-catch-finally blocks
// to guarantee that a transaction does not out-live its scope.
using (Transaction transaction = new Transaction(document, "Creating Grid"))
{
  // Must start a transaction to be able to modify a document
  if (TransactionStatus.Started == transaction.Start())
  {
     // We create a line and use it as an argument to create a grid
     Line gridLine = Line.CreateBound(p1, p2);

     if ((null != gridLine) && (null != Grid.Create(document, gridLine)))
     {
         if (TransactionStatus.Committed == transaction.Commit())
         {
            return true;
         }
     }

     // For we were unable to create the grid, we will roll the transaction back
     // (although on this simplified case we know there weren't any other changes)

     transaction.RollBack();
  }

}
return false;
}

Best.

@Danny_Bentley I don’t think that’s the issue here since he’s using the DynamoRevit methods to do the creation and they already wrap everything into transactions. Here’s the reference class https://github.com/DynamoDS/DynamoRevit/blob/8e254612f9be6bdf72cb4a04a6de746ea31c6aa4/src/Libraries/RevitNodes/Elements/Grid.cs

2 Likes

Thanks Danny!
I haven’t try the example yet, but if because of the transaction, shouldn’t it failed completely? But the last one was added successfully.
And I just tried to add some levels, this time was different, I didn’t get null references anymore. Everytime the Level.ByElevationAndName is called, the levels added before become the new one. So I get 4 same level when the method returned. And then only one has been added in Revit.

very likely is that element binding is occurring - I think you’ll have to call the revit API methods yourself here.

1 Like