WblockCloneObjects causes error in destination DWG

WblockCloneObjects causes error in destination DWG

jhdempsey
Advocate Advocate
204 Views
0 Replies
Message 1 of 1

WblockCloneObjects causes error in destination DWG

jhdempsey
Advocate
Advocate

I am copying over all the baselines and offset baselines used within a Civil 3D corridor to a new DWG file

The code I have written below works and runs without any errors.

 

When I open up the DWG file, everything looks like it has worked, and I can see some alignments and featurelines that have been copied over. 

 

But when I open up the produced DWG file and try to select one of the alignments, Civil 3D briefly pauses and then exits back to the desktop with no errors (not even a fatal error)

 

If I do an audit on the drawing before I try and select one of the alignments, it usually comes back with a lot of errors that need fixing.

 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.DatabaseServices.Styles;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CorridorSolidsAndDataExtractor
{
    public static class CorridorSolidsExtractor
    {
        public static void ExtractSolids(Document corridorDocument, bool deleteZeroVolumeSolids, string solidsFilePath, List<string> corridorsToExtract = null)
        {
            // Get corridor document so we can write out to the command line
            var corridorDatabase = corridorDocument.Database;

            // Create a new database to store the extracted solids in                      
            using (var solidsDb = new Database(false,true))
            {
                solidsDb.ReadDwgFile(@"C:\Users\DempseyJH\OneDrive - Jacobs\Documents\_autocad civil 3d 2020_jeuk_gg184 model base.dwt",
                    System.IO.FileShare.ReadWrite,
                    true,
                    "");
                solidsDb.CloseInput(true);
                
                using (var trs = solidsDb.TransactionManager.StartTransaction())
                using (var tr = corridorDatabase.TransactionManager.StartTransaction())
                {
                    var corridorCivilDoc = CivilDocument.GetCivilDocument(corridorDatabase);
                    var solidsCivilDoc = CivilDocument.GetCivilDocument(solidsDb);

                    // Open up the model space of the solidDb so we can copy the baseline objects to it later on
                    var solidsDbBlockTable = (BlockTable)trs.GetObject(solidsDb.BlockTableId, OpenMode.ForRead);
                    var solidsDbModelSpace = (BlockTableRecord)trs.GetObject(solidsDbBlockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                    // Collection for all baselines we will copy over to the solids database
                    var baselineColl = new ObjectIdCollection();                    

                    // If corridorsToExtract is null, then we will extract solids from all the corridors in the database
                    foreach (var corObjId in corridorCivilDoc.CorridorCollection)
                    {
                        var corridor = (Corridor)tr.GetObject(corObjId, OpenMode.ForRead);

                        if (corridorsToExtract == null || corridorsToExtract.Count == 0 || corridorsToExtract.Contains(corridor.Name))
                        {                           
                            // Copy across any baselines from the corridor database to the solids database
                            // Get the list of ObjectIds to copy now
                            // Do the copy in one go after all corrdiors have been processed                                                        
                            foreach(var baseline in corridor.Baselines)
                            {
                                if(baseline.IsFeatureLineBased())
                                {
                                    if (!baselineColl.Contains(baseline.FeatureLineId)) { baselineColl.Add(baseline.FeatureLineId); }
                                }
                                else
                                {
                                    if (!baselineColl.Contains(baseline.AlignmentId)) { baselineColl.Add(baseline.AlignmentId); }
                                }

                                // Now get all the offset baselines. These are stored in the regions
                                foreach(var region in baseline.BaselineRegions)
                                {
                                    foreach(var offsetBaseline in region.OffsetBaselines)
                                    {
                                        if (offsetBaseline.IsFeatureLineBased())
                                        {
                                            if (!baselineColl.Contains(offsetBaseline.FeatureLineId)){ baselineColl.Add(offsetBaseline.FeatureLineId); }
                                        }
                                        else
                                        {
                                            if (!baselineColl.Contains(offsetBaseline.AlignmentId)) { baselineColl.Add(offsetBaseline.AlignmentId); }
                                        }
                                    }
                                }
                            }                           
                        }
                    }

                    // Clone the objects to the new database
                    
                    IdMapping acIdMap = new IdMapping();
                    corridorDatabase.WblockCloneObjects(baselineColl, solidsDbModelSpace.ObjectId, acIdMap,
                                               DuplicateRecordCloning.Ignore, false);

                    // Commit the transactions
                    tr.Commit(); // Commit even though no changes made, as quicker than aborting
                    trs.Commit();
                }

                solidsDb.SaveAs(solidsFilePath, DwgVersion.Current);

                return;
            }  
        }
    }
}

 

 

The above method is called from within a command that has no special flags set (so is acting in the document context)

 

 

public class Commands
{
	[CommandMethod("CORRIDORSOLIDSANDDATAEXTRACTOR")]
	public void Test()
	{
		var doc = Application.DocumentManager.MdiActiveDocument;
		var db = doc.Database;
		Editor ed = doc.Editor;

		ed.WriteMessage($"Running CORRIDORSOLIDSANDDATAEXTRACTOR command{Environment.NewLine}");      
		
		try
		{
			// EXCLUDED CODE HERE THAT READS A CONFIG FILE TO GET SOME OF THE INPUTS INTO BELOW METHOD
				
			CorridorSolidsExtractor.ExtractSolids(doc, config.DeleteZeroVolumeSolids, solidsDwgPath, config.CorridorList);
			
		}
		catch (System.Exception ex)
		{
			ed.WriteMessage($"{ex.Message}{Environment.NewLine}{ex.StackTrace}{Environment.NewLine}", "Error" , MessageBoxButtons.OK, MessageBoxIcon.Error);
		}

		ed.WriteMessage($"FINSIHED CORRIDORSOLIDSANDDATAEXTRACTOR command{Environment.NewLine}");
	}
}

 

 

Am I doing anything obviously wrong? 

0 Likes
205 Views
0 Replies
Replies (0)