.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to include extension dictionary in block inserted using ReadDwgFile

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
cnicholas
862 Views, 14 Replies

How to include extension dictionary in block inserted using ReadDwgFile

Hello,

I'm inserting a block using ReadDwgFile(). The block has an extension dictionary which I want to preserve in the inserted block.

If I do it manually , for example, by dragging it from Design Center into Model Space, when I look at the block definition in the block table (using MgdDbg) the extension dictionary is there, which is what I want. When I try it in code the extension dictionary is not included.

 

Here's the code I am using.

 

using (Database sideDb = new Database(false, true))
{
   sideDb.ReadDwgFile(blkFile,FileOpenMode.OpenForReadAndReadShare, true, "");
   newObjectId = targetDb.Insert(Path.GetFileNameWithoutExtension(blkFile), sideDb, false);
}

 

What can I do to improve it to get the desired result?

Thanks

Craig

 

 

 

14 REPLIES 14
Message 2 of 15
_gile
in reply to: cnicholas

Hi,

 

when you say:

"I'm inserting a block using ReadDwgFile(). The block has an extension dictionary which I want to preserve in the inserted block."

 

Do you mean the Dwg file model space has an extension dictionary or the Dwg file contains a block definition which has an extension dictionary ?

 

The Database.Insert() method copies all the Model Space entities in the source database to a new BlockTableRecord in the target database BlockTable.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 15
Mikko
in reply to: cnicholas

Your not telling the code to return the full path....

maybe something like: IO.Path.GetFullPath(bla bla bla) would work
Message 4 of 15
cnicholas
in reply to: Mikko

The file name was different to the block name so on insert I got two block table entries. One for filename and one for blockname. The entry for blockname had the extension dictionary, the entry for filename did not. The block reference in model space referred to the filename entry so no extension dictionary. (I'm listening for ObjectAppended and copy the extension dictionary from the block table entry to the block reference but the name was not expected so it did not get copied).

 

To overcome this manually using INSERT, I'd select my file, change the block name to blockname and opt to explode then I get a single block table entry, the block reference refers to blockname and my ObjectAppended handler copies the extension dictionary successfully.

 

So how to I replicate that in code?

 

I changed the insert line to use blockname instead of the filename but I get a self-reference error (which also occurs manually if you don't explode).

newObjectId = targetDb.Insert("blockname", sideDb, false);

 

I guess I need to tell it to explode it before calling insert somehow.

 

 

Message 5 of 15
Mikko
in reply to: cnicholas

just a thought that if you have a drawing with a block in it you could do something like this which would insert the block from an external drawing into your current drawing.

Public Sub BlockGrabber(ByVal whatDwg As String, ByVal whichBlock As String)
Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = New Database()
db.ReadDwgFile(whatDwg, System.IO.FileShare.ReadWrite, True, "")
Dim ids As ObjectIdCollection = New ObjectIdCollection()
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim bt As BlockTable
bt = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
Try
ids.Add(bt(whichBlock))
Catch
tr.Commit()
Return
End Try
Dim destdb As Database = ed.Document.Database
Dim iMap As IdMapping = New IdMapping()
db.WblockCloneObjects(ids, destdb.BlockTableId, iMap, DuplicateRecordCloning.Ignore, False)
tr.Commit()
End Using
End Sub
Message 6 of 15
_gile
in reply to: cnicholas

If I don't misundertand you try to import a block which exists in another file.

if so, I do not think Databse.Insert() is the good route. as I said Databse.Insert() creates a new BlockTableRecord in the Database BlockTable which contains all the entites in the model space of the source file, so you block in the source file is a block reference nested in the newly created BlockTablerecord.

 

If you want to import only the block from the external file, you may use WblockCloneObjects().



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 15
_gile
in reply to: _gile

Here's a little sample:

 

        private ObjectId ImportBlock(string fileName, string blockName)
        {
            if (!File.Exists(fileName))
                throw new FileNotFoundException("File not found", fileName);

            Database targetDb = HostApplicationServices.WorkingDatabase;
            ObjectId owner = targetDb.BlockTableId;

            using (Database sourceDb = new Database())
            {
                sourceDb.ReadDwgFile(fileName, System.IO.FileShare.Read, false, "");
                using (Transaction tr = sourceDb.TransactionManager.StartOpenCloseTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(blockName))
                        return ObjectId.Null;

                    ObjectId id = bt[blockName];
                    ObjectIdCollection ids = new ObjectIdCollection();
                    ids.Add(id);
                    IdMapping idMap = new IdMapping();
                    sourceDb.WblockCloneObjects(ids, owner, idMap, DuplicateRecordCloning.Replace, false);
                    return idMap[id].IsCloned ? idMap[id].Value : ObjectId.Null;
                }
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 15
cnicholas
in reply to: _gile

Thank you for the sample. WblockCloneObjects is new to me and I have learnt something useful. 

 

Only one issue I have now is if the source database is created using the default constructor I get eBrokenHandle error from WblockCloneObjects.

 

If I use the alternative constructor, new Database(false, true) , when I add a block reference using the new block it is drawn 25.4 times greater in size. I've checked the units in both the block's drawing and the target drawing; both set to millimeters. If I change both to unitless and set insertion default unit to millimeters I get the same result. When manually using INSERT, scale is left at 1,1,1, it is drawn at the correct size.

 

I tried setting source database Insunits to 0 but that made no difference.

 

There may be more thatn a single issue here.

 

 

 

 

Message 9 of 15
_gile
in reply to: cnicholas

You say you checked the drawings units, but did you checked the block definition units ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 of 15
cnicholas
in reply to: _gile

I have now. It is Milimeters.

Message 11 of 15
_gile
in reply to: cnicholas

Could you post a drawing sample ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 12 of 15
cnicholas
in reply to: _gile

Yes. Block drawing attached.

 

Message 13 of 15
_gile
in reply to: cnicholas

Nothing wrong.

 

In the drawing you posted the block reference is scaled to 0.03937 which is equal to 1 / 25.4 (1" = 25.4 mm).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 15
cnicholas
in reply to: _gile

Yes, indeed, on the block reference. I did make the link between 1 inch = 25.4 mm. 

 

It must be me expecting it to be smaller when imported but the scale factor is not applied and is drawn correctly at 1:1. 

 

I'll look into how to get the scaling back to 1 in the block drawing and see if that cures it.

 

 

Message 15 of 15
cnicholas
in reply to: cnicholas

Gilles and Mikko

Thank you both for making me aware of WblockCloneObjects.

 

I'll mark Gilles post as the answer for the follow through.

 

The scale issue was something else besides.

 

Cheers

Craig

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost