Community
I am creating a command for selecting elements out of a drawing and inserting them into a new drawing. I am using WblockCloneObjects to do so. The command seems to work okay except that in the new drawing, the draworder of the objects does not match the source. Below is the code. I need assistance in correcting the draworder.
[CommandMethod("ISOLATE", CommandFlags.Session)]
public void ISOLATE()
{
// Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
//create a new collection for the object id's that will be moved
ObjectIdCollection objIds = new ObjectIdCollection();
//prompt user to select the obojects
acDoc.Editor.WriteMessage("\nPlease select drawings elements.");
// Lock the document
using (DocumentLock acLckDocCur = acDoc.LockDocument())
{
//Start transaction
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
//Request for objects to be selected
PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
//check if input is okay
if (acSSPrompt.Status == PromptStatus.OK)
{
//get an array of the selected object id's
ObjectId[] objIdArray = acSSPrompt.Value.GetObjectIds();
//add the selected objects into the previously created object collection
objIds = new ObjectIdCollection(objIdArray);
//check if command was cancelled, if so escape
}
else if (acSSPrompt.Status == PromptStatus.Cancel)
{
acDoc.Editor.WriteMessage("\nCommand Cancelled");
return;
}
}
}
// create a new drawing with the standard template file
string sLocalRoot = Application.GetSystemVariable("LOCALROOTPREFIX") as string;
string sTemplatePath = sLocalRoot + "Template\\acad.dwt";
DocumentCollection acNewDocMgr = Application.DocumentManager;
Document acNewDoc = acNewDocMgr.Add(sTemplatePath);
Database acDbNewDoc = acNewDoc.Database;
Editor newEd = acNewDoc.Editor;
using (DocumentLock acLckDoc = acNewDoc.LockDocument())
{
using (Transaction acTrans = acDbNewDoc.TransactionManager.StartTransaction())
{
// Open the Block table for read
BlockTable acBlkTblNewDoc;
acBlkTblNewDoc = acTrans.GetObject(acDbNewDoc.BlockTableId, OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for read
BlockTableRecord acBlkTblRecNewDoc;
acBlkTblRecNewDoc = acTrans.GetObject(acBlkTblNewDoc[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
// Clone the objects to the new database
IdMapping acIdMap = new IdMapping();
acCurDb.WblockCloneObjects(objIds, acBlkTblRecNewDoc.ObjectId, acIdMap, DuplicateRecordCloning.Ignore, false);
/**
*
* Correct Draw Order of Cloned Objects to match source
*
**/
// Save the copied objects to the database
acTrans.Commit();
}
}
acNewDocMgr.MdiActiveDocument = acNewDoc;
}
Solved! Go to Solution.
One way I've found to maintain the same draw order of objects is to add them to an ObjectIdCollection in the same order as they are found in the DrawOrderTable. After getting the object Ids from the prompt you could do the following:
ObjectIdCollection orderedIds = new ObjectCollection();
// Grab the DrawOrderTable of the document you're cloning from
BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
DrawOrderTable acDrawOrderTable = acTrans.GetObject(acBlkTblRec.DrawOrderTableId, OpenMode.ForRead) as DrawOrderTable;
// Get all Ids in the order they are drawn
ObjectIdCollection drawOrderIds = acDrawOrderTable.GetFullDrawOrder(0);
// Add the selected Ids to orderedIds in the order they are found in the DrawOrderTable
foreach (ObjectId drawId in drawOrderIds)
{
if (objIds.Contains(drawId))
{
orderedIds.Add(drawId);
}
}
Can't find what you're looking for? Ask the community or share your knowledge.