Author Topic: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)  (Read 3326 times)

0 Members and 1 Guest are viewing this topic.

kiki

  • Mosquito
  • Posts: 7
.NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« on: January 09, 2018, 03:40:35 PM »
Hi,

Bellow is typical part of code to import block from other DWG.
It is working perfect also with dynamic blocks using BricsCAD V13, V14 and AutoCAD.
I was very surprised that it doesn't work with BricsCAD V15 to V18.

What is the reason?  How to solve it?

ObjectId ImportBlock(Database targetDb, string sourceFileName, string blockName)
        {
            using (var sourceDb = new Database(false, true))
            {
                sourceDb.ReadDwgFile(sourceFileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                var id = ObjectId.Null;
                using (var tr = sourceDb.TransactionManager.StartTransaction())
                {
                    var bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(blockName))
                        return ObjectId.Null;
                    id = bt[blockName];
                    tr.Commit();
                }
                var ids = new ObjectIdCollection();
                ids.Add(id);
                var mapping = new IdMapping();
                sourceDb.WblockCloneObjects(ids, targetDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                return mapping[id].Value;
            }
        }

The same situation is when I tried following code:
http://through-the-interface.typepad.com/through_the_interface/2006/08/import_blocks_f.html

In attachment you can find sample source DWG with dynamic block.

Thanks you in advance.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #1 on: January 09, 2018, 04:17:55 PM »

What is the reason?  How to solve it?


Hi kiki,

What are the errors?

I don't like to be picky but posting code that apparently used to work without giving us any error reports or clues will not get you much help.
Without this information you are basically asking us to create a project to use your code then test it on a drawing that could come from anywhere and I know I don't have that spare time.

With some error messages, someone might be able to see the problem without having to do any further work other than read your snippet.

Let us know what you have tried and what happened, that will help us help you :)

cheers
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

kiki

  • Mosquito
  • Posts: 7
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #2 on: January 09, 2018, 05:07:19 PM »
Hi MickD,

BricsCAD V15 - V18 just can't see block name in blocktable.

There is no error message. Block isn't imported to targetDb.
Also Kean's code doesn't work in these BricsCAD versions.

I'm very surprised, because BricsCAD V18 working quite well with dynamic blocks.
All AutoCAD 2009 - 2018 and BricsCAD V13 - V14 work with no problem.


MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #3 on: January 09, 2018, 05:29:00 PM »
Ok

Can you select and inspect these entities in the source drawing? This may give more of a clue on how to obtain them for cloning. Also try this with the earlier versions and compare to see if there is a subtle difference.

hth
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Atook

  • Swamp Rat
  • Posts: 1029
  • AKA Tim
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #4 on: January 09, 2018, 09:29:26 PM »
My understanding is that Bricscad doesn't play nice with dynamic blocks.

I'm surprised 13 and 14 had no problems, curious to see if you can get it to work.

Bricscad 18 can see the sourceblock in the blocktable, so the block should show up there.

kiki

  • Mosquito
  • Posts: 7
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #5 on: January 10, 2018, 08:28:04 AM »
There is a problem with importing block using WblockCloneObjects.

I have tested sourceDWG.dwg in AutoCAD ArxDbg tool. Please see attachment.

Then I iterate through Block Table. Please see btr.Name results in following programs:

AutoCAD and BricsCAD V13, V14:
*Model_Space
*Paper_Space
*Paper_Space0
*U2
AD_8GK4851-5KK00i

BricsCAD V15 - V18:
*Model_Space
*Paper_Space
*Paper_Space0
*U
*U2

This is main reason, that block isn't imported.

Atook

  • Swamp Rat
  • Posts: 1029
  • AKA Tim
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #6 on: January 10, 2018, 01:28:25 PM »
I remember having to tweak my code for WblockCloneObjects when implementing Bricscad. If I remember I changed how I implemented the DocumentLock, as well as the DuplicateRecordCloning parameter.

Take a look at this code and see if anything in it helps you.

Code - C#: [Select]
  1. /// <summary>
  2. /// Gets the block from specified drawing and adds it to the blocktable of the active drawing..
  3. /// </summary>
  4. /// <param name="blockName">The Blockname.</param>
  5. /// <param name="path">The path to dwg/dwt to extract block from.</param>
  6. private static bool GetBlockFromDWG(string blockName, string path)
  7. {
  8.   using (Database openDb = new Database(false, true))
  9.   {
  10.     openDb.ReadDwgFile(path,
  11.       System.IO.FileShare.ReadWrite, true, "");
  12.  
  13.     ObjectIdCollection ids = new ObjectIdCollection();
  14.     using (Transaction tr = openDb.TransactionManager.StartTransaction())
  15.     {
  16.       var bt = (BlockTable)tr.GetObject(openDb.BlockTableId, OpenMode.ForRead);
  17.  
  18.       if (bt.Has(blockName))
  19.       {
  20.         ids.Add(bt[blockName]);
  21.       }
  22.       tr.Commit();
  23.     }
  24.  
  25.     //if found, add the block
  26.     if (ids.Count != 0)
  27.     {
  28.       //get the current drawing database
  29.  
  30.       using (DocumentLock acLock = Active.Document.LockDocument())
  31.       {
  32.         IdMapping iMap = new IdMapping();
  33.         Active.Database.WblockCloneObjects(ids, Active.Database.BlockTableId
  34.           , iMap, DuplicateRecordCloning.Ignore, false);
  35.  
  36.       }
  37.       return true;
  38.     }
  39.     else
  40.     {
  41.       Debug.Print($"Can't find block {blockName} in {path}");
  42.       return false;
  43.     }
  44.   }
  45. }
  46.  

kiki

  • Mosquito
  • Posts: 7
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #7 on: January 10, 2018, 02:44:56 PM »
Thank you for response.

You code works well with classic blocks.
Unfortunatelly it is not working importing dynamic blocks (V15-V18).

This condition will be bypassed, because there is no such name in BlockTable:
if (bt.Has(blockName))
{
    ids.Add(bt[blockName]);
}

Even if I remove this condition, dynamic block is not imported...

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #8 on: January 24, 2018, 03:55:17 AM »
Hi,

give this a whirl

Code - C#: [Select]
  1.        [CommandMethod("doit")]
  2.         public void doit()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database destDb = doc.Database;
  7.             using (Database sourceDb = new Database(false, true))
  8.             {
  9.                 try
  10.                 {
  11.                     string sourceFileName = @"C:\Users\Dan\Desktop\D_Block\sourceDWG.dwg";
  12.                     sourceDb.ReadDwgFile(sourceFileName, System.IO.FileShare.Read, true, "");
  13.                     ObjectIdCollection blockIds = new ObjectIdCollection();
  14.  
  15.                     using (BlockTable bt = (BlockTable)sourceDb.BlockTableId.Open(OpenMode.ForRead))
  16.                     {
  17.                         foreach (ObjectId btrId in bt)
  18.                         {
  19.                             using (BlockTableRecord btr = (BlockTableRecord)btrId.Open(OpenMode.ForRead))
  20.                             {
  21.                                 if (btr.IsDynamicBlock)
  22.                                     blockIds.Add(btrId);
  23.                             }
  24.                         }
  25.                     }
  26.                     sourceDb.CloseInput(true);
  27.                     using (IdMapping mapping = new IdMapping())
  28.                     {
  29.                         mapping.DestinationDatabase = destDb;
  30.                         destDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Ignore, false);
  31.                     }
  32.                     ed.WriteMessage("\nCopied "
  33.                                     + blockIds.Count.ToString()
  34.                                     + " block definitions from "
  35.                                     + sourceFileName
  36.                                     + " to the current drawing.");
  37.                 }
  38.                 catch (System.Exception ex)
  39.                 {
  40.                     ed.WriteMessage("\nError during copy: " + ex.Message);
  41.                 }
  42.             }
  43.         }
  44.  

kiki

  • Mosquito
  • Posts: 7
Re: .NET WblockCloneObjects in BricsCAD V15 to V18 (dynamic blocks)
« Reply #9 on: January 24, 2018, 02:15:15 PM »
Wow!

Thank you very much. It's working in V17 & V18!