Automating PLANTPROJECTCOLLABORATION: Seamless Plant Project Sharing to ACC

AutoCAD Plant 3D provides a command to share a plant project to the ACC cloud: PLANTPROJECTCOLLABORATION.

For more details, refer to To Share a Plant Project to the Cloud.

However, this command poses a challenge for automation, as it requires user interaction. To overcome this limitation, we can use the Plant 3D API to automate the process of sharing the plant project to the cloud.

The code snippet below demonstrates how to upload a Plant3D project to Collaboration for Plant3D asynchronously. The code emits a CLI progress indicator. It takes the hub name, project ID, and folder ID as input parameters.


/// 
/// Uploads a Plant3D project to Collaboration for Plant3D asynchronously
/// Emits a CLI progress indicator
/// 
/// 
/// 
/// 
/// 
public static async Task UploadProjectAsync(
    string hubName, string projectId, string folderId)
{
    using CancellationTokenSource cts = new();
    try
    {
        // TODO: Add support for Vault and SQL Server projects
        PlantProject plantPrj = PlantApplication.CurrentProject;
        string projPath = plantPrj.ProjectFolderPath;
        
        // Server login
        DocLogIn login = Commands.ServiceLogIn(Commands.CloudServiceName);
        if (login == null)
        {
            Commands.PlantCloudLogin();
            login = Commands.ServiceLogIn(Commands.CloudServiceName);
            if (login == null) return;
        }
        
        // Select Docs Hub and Project
        DocA360Project docProject = await Task.Run(() =>
        {
            var hubs = login.SelectA360Hubs(null, cts.Token);
            var hub = hubs?.FirstOrDefault(x => x.A360HubId == hubName);
            var projects = hub != null
                ? login.SelectA360ProjectsFromHub(hub, cts.Token)
                : null;
            var proj = projects?.FirstOrDefault(x => x.A360ProjectId == projectId);
            
            // Check if the project root is the target folder
            if (proj != null && proj.RootFolderUrn == folderId) 
                return proj; // Return the project itself
            
            // Otherwise, search subfolders
            return login.SelectA360ProjectSubFolders(proj, cts.Token)
                ?.FirstOrDefault(x => x.RootFolderUrn == folderId) ?? proj;
        }, cts.Token);
        
        if (docProject == null) return;
        
        // Copy project to CollaborationCache
        string destPath = Path.Combine(
            Commands.P360WorkingFolder.Trim(), plantPrj.Name);
        Utils.BackupProjectFiles(
            new DirectoryInfo(projPath), new DirectoryInfo(destPath));
        
        // Convert SQL Server project to SQLite if necessary
        var pid = plantPrj.ProjectParts["PnId"];
        if (pid?.DataLinksManager.GetPnPDatabase().DBEngine.ToString()
            != PnPDatabase.SQLiteEngineClass)
        {
            ConvertSQLServerProjectToSQLiteProject(
                destPath, plantPrj.Username, plantPrj.Password, cts.Token);
        }
        plantPrj.Close();
        
        // Load new project
        PlantProject prj = PlantProject.LoadProject(
            Path.Combine(destPath, "Project.xml"), true, null, null);
        
        // Ensure project structure and collect XRefs
        EnsureProjectFoldersExist(prj);
        var assoc = CollectXrefs(prj);
        
        // Share project
        PnPDocumentServerFactory factory =
            PnPDocumentServerFactoryRegistry.GetFactory(
                Commands.CloudServiceName);
        DocumentServer docsrv = factory.CreateInstance(Guid.NewGuid().ToString());
        docsrv.SignIn(login, null);
        
        // Start progress indicator
        Task progressTask = ShowProgressAsync(cts.Token);
        try
        {
            PrintMsg("Starting EnableDocumentManagement...");
            await Task.Run(() =>
            {
                prj.EnableDocumentManagement(
                    docsrv, string.Empty, string.Empty, docProject, assoc, cts.Token);
                cts.Token.ThrowIfCancellationRequested();
            }, cts.Token);
            PrintMsg("EnableDocumentManagement completed successfully.");
        }
        catch (OperationCanceledException ex)
        {
            PrintMsg($"Upload canceled: {ex.Message}");
            throw;
        }
        catch (Exception ex)
        {
            PrintExceptionDetails(ex);
            throw;
        }
        finally
        {
            cts.Cancel(); // Stop progress
            await progressTask;
            prj.Close();
        }
    }
    catch (OperationCanceledException)
    {
        PrintMsg("Upload operation was canceled.");
        throw;
    }
    catch (Exception ex)
    {
        PrintExceptionDetails(ex);
        throw;
    }
}

Full source code and a demo working sample Run is provided in Github Project


View Program.cs on GitHub


Comments

One response to “Automating PLANTPROJECTCOLLABORATION: Seamless Plant Project Sharing to ACC”

  1. lis ten Avatar
    lis ten

    Hello,
    I want to use the Plant 3D API to create a project, but it keeps throwing a NullReferenceException. I’m not sure where I went wrong.
    Can you help me?
    Thank you.
    var a1 = new Dictionary<string, string>();
    a1.Add(“PnId”, “D:\Project\MyNewProject\PID DWG”);
    a1.Add(“Piping”, “D:\Project\MyNewProject\Plant 3D 模型”);
    a1.Add(“Iso”, “D:\Project\MyNewProject\等级库工作表”);
    a1.Add(“Ortho”, “D:\Project\MyNewProject\DWGs”);
    a1.Add(“Misc”, “D:\Project\MyNewProject\相关文件”);
    var a2 = new Dictionary<string, PnPDatabaseLink>();
    var pnidDbLink = new PnPDatabaseLink() { Name = “D:\Project\MyNewProject\ProcessPower.dcf”, DatabaseEngine = “Autodesk.ProcessPower.DataObjects.DbEngine.PnPSQLiteEngine” };
    pnidDbLink.Add(“Data Source”, “D:\Project\MyNewProject\ProcessPower.dcf”);
    a2.Add(“PnId”, pnidDbLink);
    var pipingDbLink = new PnPDatabaseLink() { Name = “D:\Project\MyNewProject\Piping.dcf”, DatabaseEngine = “Autodesk.ProcessPower.DataObjects.DbEngine.PnPSQLiteEngine” };
    pipingDbLink.Add(“Data Source”, “D:\Project\MyNewProject\Piping.dcf”);
    a2.Add(“Piping”, pipingDbLink);
    var IsoDbLink = new PnPDatabaseLink() { Name = “D:\Project\MyNewProject\Iso.dcf”, DatabaseEngine = “Autodesk.ProcessPower.DataObjects.DbEngine.PnPSQLiteEngine” };
    IsoDbLink.Add(“Data Source”, “D:\Project\MyNewProject\Iso.dcf”);
    a2.Add(“Iso”, IsoDbLink);
    var OrthoDbLink = new PnPDatabaseLink() { Name = “D:\Project\MyNewProject\Ortho.dcf”, DatabaseEngine = “Autodesk.ProcessPower.DataObjects.DbEngine.PnPSQLiteEngine” };
    OrthoDbLink.Add(“Data Source”, “D:\Project\MyNewProject\Ortho.dcf”);
    a2.Add(“Ortho”, OrthoDbLink);
    var MiscDbLink = new PnPDatabaseLink() { Name = “D:\Project\MyNewProject\Misc.dcf”, DatabaseEngine = “Autodesk.ProcessPower.DataObjects.DbEngine.PnPSQLiteEngine” };
    MiscDbLink.Add(“Data Source”, “D:\Project\MyNewProject\Misc.dcf”);
    a2.Add(“Misc”, MiscDbLink);
    var a = Autodesk.ProcessPower.ProjectManager.PlantProject.CreateProject(projectName, projectDescription, projectPath, false, a1, a2, currProject);

Leave a Reply to lis tenCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading