Author Topic: Autocad .NET API - Hatches not copying correctly from side loaded dwgs  (Read 1426 times)

0 Members and 1 Guest are viewing this topic.

ruben

  • Mosquito
  • Posts: 2
Hi All,

Has anybody ever encountered an issue in AutoCAD where hatches created via the .NET API give an 'Object Permanently Erased' error or cause a fatal crash when edited?

As part of a tool I'm working on for work I am side loading a .dwg and creating a copy of each entity in that .dwg into the file the command is executed in. It seems that all object types are coming through fine, save for hatches. The hatch appears blacked out in the new file and causes errors/crashes when interacted with.

I would be grateful for any insights on why it might behave like this, or general advice to better the code below. Thank you!

Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.IO;
  7. using System.Windows.Forms;
  8. using Autodesk.AutoCAD.ApplicationServices;
  9. using Autodesk.AutoCAD.DatabaseServices;
  10. using Autodesk.AutoCAD.EditorInput;
  11. using Autodesk.AutoCAD.Runtime;
  12. using Autodesk.AutoCAD.Geometry;
  13. using Autodesk.AutoCAD.GraphicsSystem;
  14. using Autodesk.AutoCAD.Colors;
  15. using ALD_DetailTools;
  16.  
  17. namespace ALD_DetailTools
  18. {
  19.     internal class ConvertDetailGeometry
  20.     {
  21.         public static string SelectBlockFilePath()
  22.         {
  23.             using (OpenFileDialog openFileDialog = new OpenFileDialog())
  24.             {
  25.                 var workingFolder = Path.GetDirectoryName(Active.Document.Name);
  26.                 openFileDialog.InitialDirectory = workingFolder;
  27.                 openFileDialog.Filter = ".dwg files (*.dwg)|*.dwg";
  28.                 openFileDialog.FilterIndex = 1;
  29.                 openFileDialog.RestoreDirectory = true;
  30.  
  31.                 if (openFileDialog.ShowDialog() == DialogResult.OK)
  32.                 {
  33.                     Active.Editor.WriteMessage("\nPath: " + openFileDialog.FileName);
  34.                     return (openFileDialog.FileName);
  35.  
  36.                 }
  37.                 else
  38.                 {
  39.                     return null;
  40.                 }
  41.  
  42.  
  43.             }
  44.         }
  45.         public static void InsertDetailBlock(string filePath)
  46.         {
  47.             using (Active.Document.LockDocument())
  48.             {
  49.                 using (var sourceDb = new Database(false, true))
  50.                 {
  51.                     sourceDb.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndAllShare, true, null);
  52.                     sourceDb.CloseInput(true);
  53.  
  54.                     using (var tr = Active.Document.TransactionManager.StartOpenCloseTransaction())
  55.                     {
  56.  
  57.                         var sourceBlockTable = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
  58.                         var sourceBlockTableRecord = (BlockTableRecord)tr.GetObject(sourceBlockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  59.  
  60.                         var currentBlockTable = (BlockTable)tr.GetObject(Active.Database.BlockTableId, OpenMode.ForWrite);
  61.                         var currentBlockTableRecord = (BlockTableRecord)tr.GetObject(currentBlockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  62.  
  63.  
  64.  
  65.                         foreach (ObjectId id in sourceBlockTableRecord)
  66.                         {
  67.                             var retrievedObject = tr.GetObject(id, OpenMode.ForRead);
  68.  
  69.                             Entity retrievedEntity = (Entity)retrievedObject.Clone();
  70.  
  71.                             try
  72.                             {
  73.                                 currentBlockTableRecord.AppendEntity(retrievedEntity);
  74.                                 tr.AddNewlyCreatedDBObject(retrievedEntity, true);
  75.                             }
  76.                             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  77.                             {
  78.                                 Active.Editor.WriteMessage("\nFailed to append" +
  79.                                     retrievedEntity.ObjectId +
  80.                                     " " +
  81.                                     ex.Message);
  82.                             }
  83.  
  84.                         }
  85.  
  86.                         tr.Commit();
  87.                     }
  88.                    
  89.                 }
  90.             }
  91.         }
  92.  
  93.     }
  94. }
  95.  

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Hi,

You should use WBlockCloneObjects instead of Clone.
Code - C#: [Select]
  1.         public static void InsertDetailBlock(string filePath)
  2.         {
  3.             var targetId = SymbolUtilityServices.GetBlockModelSpaceId(Active.Database);
  4.             using (var sourceDb = new Database(false, true))
  5.             {
  6.                 sourceDb.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndAllShare, true, null);
  7.                 using (var tr = sourceDb.TransactionManager.StartTransaction())
  8.                 {
  9.                     var sourceModelSpace = (BlockTableRecord)tr.GetObject(
  10.                         SymbolUtilityServices.GetBlockModelSpaceId(sourceDb), OpenMode.ForRead);
  11.                     var ids = new ObjectIdCollection(sourceModelSpace.Cast<ObjectId>().ToArray());
  12.                     var mapping = new IdMapping();
  13.                     sourceDb.WblockCloneObjects(ids, targetId, mapping, DuplicateRecordCloning.Ignore, false);
  14.                     tr.Commit();
  15.                 }
  16.             }
  17.         }

Or, even simpler, Database.Insert.
Code - C#: [Select]
  1.         public static void InsertDetailBlock(string filePath)
  2.         {
  3.             using (var sourceDb = new Database(false, true))
  4.             {
  5.                 sourceDb.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndAllShare, true, null);
  6.                 Active.Database.Insert(Matrix3d.Identity, sourceDb, true);
  7.             }
  8.         }
« Last Edit: April 10, 2022, 04:24:30 AM by gile »
Speaking English as a French Frog

ruben

  • Mosquito
  • Posts: 2
That works perfectly, thank you so much! Always nice to turn 50 lines of broken code into 5 good ones