Announcements
Welcome to the Revit Ideas Board! Before posting, please read the helpful tips here. Thank you for your Ideas!
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Make the "Publish settings" tool functions available in the API

Make the "Publish settings" tool functions available in the API

In Revit, we can use the "Publish Settings" tool to select which views/sheets of the model will be published to the cloud : https://knowledge.autodesk.com/support/revit-products/learn-explore/caas/CloudHelp/cloudhelp/2019/EN...

 

It would be very useful for us, developers, to be able to do the same thing from the code.

We need the same functionalities to be added to the Revit API.

18 Comments
Anonymous
Not applicable

We need this functionality ASAP.

Anonymous
Not applicable

Is this functionality available from rest API? I am trying to translate a RVT file which contain multiple 3D views but after translation in Forge I am getting only the default one ({3D}). I am using Forge C# library to do this translation. How can I get multiple 3D views from forge translation by using Forge C# library or Rest API?

josh_moore
Enthusiast

I agree with this request.  Right now, if you want to do anything with the Publish settings (for example, add a view / sheet set or remove one) you can only access this with UI automation, which isn't the greatest.

ABertzouanis9F98Y
Enthusiast

Any update with this feature?

peter_hirn
Enthusiast

The published ViewSheetSets are stored as ExtensibleStorage on the Project Information Element, see https://fieldofviewblog.wordpress.com/2016/04/02/selecting-views-to-publish-revit-project-on-a360/

 

For my current project I required a list of all published views

 

private static IEnumerable<View> PublishedViews(Document document)
{
    var schemaId = new Guid("57c66e83-4651-496b-aebb-69d085752c1b");

    var schema =
        Schema.ListSchemas().FirstOrDefault(schema => schema.GUID == schemaId)
        ?? throw new InvalidOperationException("Schema ExportViewSheetSetListSchema not found");

    var field =
        schema.GetField("ExportViewViewSheetSetIdList")
        ?? throw new InvalidOperationException("Field ExportViewViewSheetSetIdList not found");

    var entity = document.ProjectInformation.GetEntity(schema);

    var viewSheetSetIds = entity.Get<IList<int>>(field);
    var viewSheetSets = viewSheetSetIds.Select(id => document.GetElement(new ElementId(id))).Cast<ViewSheetSet>();

    return viewSheetSets.SelectMany(viewSheetSet => viewSheetSet.Views.Cast<View>());
}

 

 

I didn't test this any further but assume you should be able to add additional ViewSheetSets to this schema and/or modify existing sets.

CharlesCiro
Explorer

@peter_hirn That approach doesn't work because that entity is not editable, as the vendor is ASDK.

peter_hirn
Enthusiast
Well, that is unfortunate. Does it work when setting ADSK as VendorId in your manifest? This is not a proper fix of course, just wondering if it works at all.
CharlesCiro
Explorer

Hi @peter_hirn, a very late update on this: Yes, if you put ADSK like vendor, the script works. Thank you!

peter_hirn
Enthusiast

Nice. So you are able to edit the published views? If so this could be material for @jeremy_tammik blog. 😁

CharlesCiro
Explorer

Yes, first I am editing/creating the viewset with the PrintManager, ViewSheetSet, and ViewSheetSetting classes, and then I move on to publishing with the code you showed. The detail is that you must put ADSK as the vendorId, which is not elegant, but it can be useful for internal tools.

 

public static void PublishedViews(Document document)
        {
            ViewSheetSet existingViewSet = new FilteredElementCollector(document)
                .OfClass(typeof(ViewSheetSet))
                .Cast<ViewSheetSet>()
                .FirstOrDefault(vs => vs.Name == "existingViewSetName");

            var schemaId = new Guid("57c66e83-4651-496b-aebb-69d085752c1b");

            var schema =
                Schema.ListSchemas().FirstOrDefault(schemaVS => schemaVS.GUID == schemaId)
                ?? throw new InvalidOperationException("Schema ExportViewSheetSetListSchema not found");

            var field =
                schema.GetField("ExportViewViewSheetSetIdList")
                ?? throw new InvalidOperationException("Field ExportViewViewSheetSetIdList not found");

            var entity = document.ProjectInformation.GetEntity(schema);

            var viewSheetSetIds = entity.Get<IList<int>>(field);
            var viewSheetSets = viewSheetSetIds.Select(id => document.GetElement(new ElementId(id))).Cast<ViewSheetSet>();
            var views = viewSheetSets.SelectMany(viewSheetSet => viewSheetSet.Views.Cast<View>());

            //Add the additional ViewSheetSet
            viewSheetSetIds.Add(existingViewSet.Id.IntegerValue);
            entity.Set(field, viewSheetSetIds);
            document.ProjectInformation.SetEntity(entity);
            
        }

 

 

jeremy_tammik
Alumni

Thank you for sharing the solution. I added a pointer to this to the blog as well:

 

https://thebuildingcoder.typepad.com/blog/2024/02/net-core-c4r-views-and-interactive-hot-reload.html...

khagesh_mahajan
Participant

Thank you for your previous answer.
I am trying to publish views to the cloud, and to do so, I need to create a view set in the publish settings and assign views to it. After creating and assigning views to the set, I save it so that I can view those views in the Autodesk viewer. While I am able to create a new set and assign views to it via the API, I am facing difficulties including and saving the set through the API.

I have attempted to create a publish set using the code above, but I encountered an exception: "Requested type does not match the field type" for the line

var viewSheetSetIds = entity.Get<IList<long>>(field);


I have tried various approaches to resolve this issue. Firstly, I modified the code to retrieve the GUID from an existing view set. Secondly, I manually created a set through the UI, added views to it, saved it, and checked the Revit lookup. The ViewSheetSet for the field "ExportViewViewSheetSetIdList" is not empty. However, even after these steps, I still encounter the exception when running the code.

Could you please help me understand why I am encountering this exception? and assist me in solving this problem or identify what I might be missing?I have attached some screenshots for your reference. 

Exception.jpgSelect_set.jpgRevit_lookup.jpg

 

jeremy_tammik
Alumni

Congratulations on making good progress. Would you like tho share the wroking code that your are using for others to benefit? The error message says that the type you supply does not match the field type. The type you supply is IList<long>. That looks weird to me. IList is an interface. Does that work? Maybe List would be better than IList? However, more seriously, you are specifying a list of element ids, not long numbers. So, I would expect List<ElementId> to be a better choice. All that said, I have no idea. I hope this helps anyway and look forward to hearing about your further progress. However, this is the Revit Idea Station and a wish list item, not a discussion forum. So, for discussing problems you encounter, it might be better to raise an issue in the discussion forum instead, and not clutter up this wish list item with irrelevant problems that do not concern the wish per se.

khagesh_mahajan
Participant

Hi @jeremy_tammik ,
Thank you for your reply.
I tried your suggestion by giving List<ElementId>, here List is not working but giving the IList<ElementId> the above exception solved.

But now getting exception at another line

doc.ProjectInformation.SetEntity(entity);


as 

khagesh_mahajan_0-1721916494071.png

 


Apologize for posting my wish list item in this thread. I will post my wish list item in the new thread.

Thank you.

a_cherneha
Enthusiast

Try this

Screenshot_22.png

peter_hirn
Enthusiast

@khagesh_mahajanA late response...

 

The first issue

entity.Get<IList<long>>(field);

vs.

entity.Get<IList<int>>

Autodesk changed the ElementId type from int to long, but didn't migrate data stored in this ExtensibleStorage. This is still a int list regardless of the Revit Version you are running. Using IList<ElementId> will probably not work with the latest Revit version (I think).

 

In the case a View is actually assigned a number which overflows int this whole thing will break. 😁

 

Regarding

doc.ProjectInformation.SetEntity(entity);

If you want to write to this schema you have to set the VendorId of your addin to "ADSK". See above.

garmentroutR46MG
Observer

For Revit 2024 and above change the code to this, the only 2 important changes are highlighted in red. But the big change is to find a schema using this:

schema = Schema.ListSchemas().FirstOrDefault(schemaVS => schemaVS.SchemaName == "ExportViewSheetSetListSchemaWith64BitId")

 

And when you get the viewSheetSetIds. Change IList<int> to IList<ElementId>:

var viewSheetSetIds = entity.Get<IList<ElementId>>(field);

public static void PublishedViews(Document document)
{
          ViewSheetSet existingViewSet = new FilteredElementCollector(document)
             .OfClass(typeof(ViewSheetSet))
             .Cast<ViewSheetSet>()
             .FirstOrDefault(vs => vs.Name == "existingViewSetName");

 

     var schema =
          Schema.ListSchemas().FirstOrDefault(schemaVS => schemaVS.SchemaName ==       "ExportViewSheetSetListSchemaWith64BitId")
     ?? throw new InvalidOperationException("Schema ExportViewSheetSetListSchema not found");

 

     var field =
          schema.GetField("ExportViewViewSheetSetIdList")
          ?? throw new InvalidOperationException("Field ExportViewViewSheetSetIdList not found");

 

     var entity = document.ProjectInformation.GetEntity(schema);

     var viewSheetSetIds = entity.Get<IList<ElementId>>(field);
     var viewSheetSets = viewSheetSetIds.Select(id => document.GetElement(new       ElementId(id))).Cast<ViewSheetSet>();


     var views = viewSheetSets.SelectMany(viewSheetSet => viewSheetSet.Views.Cast<View>());

     //Add the additional ViewSheetSet
     viewSheetSetIds.Add(existingViewSet.Id);
     entity.Set(field, viewSheetSetIds);
     document.ProjectInformation.SetEntity(entity);

}

David_NgDCZ66
Explorer

Was tinkering around with the schema and how it originates. The schema is loaded into memory when the PublishSetting UI triggers and when control returns to Revit. So I set up a dynamo script to test. Before and after the PublishSetting PostableCommand, the schema is not created if I'm within the Dynamo environment but once exiting, the schema is committed to memory.  From there I can just use SetEntity to set it to ProjectInformation and add viewsheetsets as needed.

Since it seems like that would require 2 separate scripts (One to bring the schema into memory and one to set it), it's not optimal. So the only other route it seems would be to impersonate the schema with the inelegant solution of using ADSK as VendorID. One thing that I did found out that tripped me up is the Major and Minor Field Versions must be 2/1 after either setting the schema to Project Information or creating the schema itself, setting it and to Project Information.

My workflow ended up being: If schema doesn't exist in memory, replicate it. If it only exists in memory, set it. If it exists in Project Information, append the ViewSheet Set.


This method actually works both as a Python Script and Dynamo however again it'll require VendorID to be ADSK. If you run the script within a Dynamo session, it acquires ADSK as the VendorID but if you use an addin to run the script, it'll automatically acquire the VendorID of the addin.

We could also clone/fork Revit Batch Processor, amend the VendorID in the Revit add-ins for any batch needs and this seems to work for Revit 2022-2026. Haven't tested it any further.

 

Can't find what you're looking for? Ask the community or share your knowledge.

Submit Idea