Send 3D View to specific Branch (Stairs) using Speckle.Core.Api

  • Objective: I want to send specific 3D View to specific branch from my own plugin.

I am implementing a plugin to automatic, divide my project into relevant group of elements and create a 3D View for each group.

Once this division is achieved, I am sending from the Plugin this 3D View to the speckle server.

  • Issue: The code is working fine, for most of the cases, getting a lot of help from the implementation in ConnectorBindingsRevit.Send.cs, I am successfully finding the elements in the view, converting them to speckle objects, create the Branch in case does not exist yet and send them over to Speckle. BUT there an error that appears when trying to send stairs.

I’m having hard time to solve this because is just happening with the stairs so far, which seam weird, but I do not know… Maybe this is not the most optimal implementation. Here is a screenshot of the error, the description and the function.

Thanks again for any clue in how to solve this!

ErrorSpeckle.Core.Kits.ConversionSkippedException
HResult=0x80131500
Message=StairsRun are handled by the Stairs conversion
Source=Objects.Converter.Revit2024
StackTrace:
at Objects.Converter.Revit.ConverterRevit.ConvertToSpeckle(Object object)
at TopBimManager.Events.SpeckleConnector.d__4.MoveNext() in C:\Users\jairo.picott\source\repos\TopBimManager\TopBimManager\Events\SpeckleConnector.cs:line 63

This is the function that send the data to speckle

public async void SendViewToSpeckle(UIApplication uiApp, View3D view)
{
    //To Get from UI
    //Hardcoded for DEBUG 
    var streamId = "518eadde6b";
    var branchName = view.Name;
    //End To get from UI

    //Get account data
    var defaultAccount = AccountManager.GetDefaultAccount();
    var client = new Client(defaultAccount);
    var transport = new ServerTransport(defaultAccount, streamId);

    //Load Converter
    var kit = KitManager.GetDefaultKit();
    var converter = kit.LoadConverter(Objects.Converter.Revit.ConverterRevit.RevitAppName);
    converter.SetContextDocument(uiApp.ActiveUIDocument.Document);
    var docProvider = new UIDocumentProvider(uiApp);
    var cache = new RevitDocumentAggregateCache(docProvider);
    converter.SetContextDocument(cache);

    //Collect Elements to send from the View
    FilteredElementCollector c = new FilteredElementCollector(uiApp.ActiveUIDocument.Document, view.Id);
    var selection = c.WhereElementIsNotElementType()
        .WhereElementIsViewIndependent()
        .ToList();

    //Process the selected elements and convert to Speckle Base
    converter.SetContextDocument(view);
    selection = HandleSelectedObjectDescendants(selection).ToList();
    converter.SetContextDocument(cache);
    converter.SetContextObjects(
        selection
        .Select(x => new ApplicationObject(x.UniqueId, x.GetType().ToString()) { applicationId = x.UniqueId })
        .ToList());
    IList<Base> speckleObjs = new List<Base>();
    foreach (var item in selection)
    {
        if (converter.CanConvertToSpeckle(item))
        {
            speckleObjs.Add(converter.ConvertToSpeckle(item)); //Line that throw the Exception
        }
    }

    //Create Commit Object and add the Speckle Base Objects
    var commitObject = new Base();
    commitObject["name"] = view.Name;
    commitObject["children"] = speckleObjs;

    //Send commit object to transport
    var hash = Operations.Send(commitObject, new List<ITransport> { transport}).Result;

    //Check if Branch exist, if NOT create new branch
    var branch = await client.BranchGet(streamId, view.Name.ToLower());
    string branchId;
    if (branch == null)
    {
        BranchCreateInput bci = new BranchCreateInput();
        bci.streamId = streamId;
        bci.name = view.Name.ToLower();
        branchId = await client.BranchCreate(bci);
    }

    //Create the Commit
    var commitId = client.CommitCreate(new CommitCreateInput()
    {
        branchName = branchName.ToLower(),
        message = "Created from TBM",
        objectId = hash,
        streamId = streamId,
        sourceApplication = "TBM"
    }).Result;
    
    //Dispose the Client
    client. Dispose();
}

Ok I solved, by just adding a "continue;" for those classes that throw the exception in the ConverterRevit.cs. I suppose yesterday I could not see this.

1 Like

Nice! I think that error is thrown by our code, since we have logic that traverses nested elements (such as StairRuns), and you’re not expected to directly convert them.

Curious about what you’re building tho! Maybe something to Showcase! - Speckle Community?

1 Like

Yes, it is indeed thrown by your code, and I was able to understand it just today. I guess my brain was off yesterday afternoon :laughing:!!

Sure, will do, I was preparing a post for my LinkedIn today, I will share it also here!

1 Like