WblockCloneObjects causes error in destination DWG
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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?