Trouble Inserting a Drawing Into my Drawing - Answered
I'm using this code to insert a drawing into my current drawing like a block. This worked in AutoCAD.
The drawing file exists, all the values that are passed check out good.
It crashes on the line:
Dim BlkId As ObjectId = podDB.Insert(BlockName, db, True)
If anyone has an answer, please let me know. This is getting very frustrating.
`Public Sub InsertBlock(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal basename As String, ByVal explode As Boolean, ByVal blkRot As Double, ByVal scale As Double)
Dim podDWG As Document = Application.DocumentManager.MdiActiveDocument Dim podDB As Database = podDWG.Database Using insBlkTrans As Transaction = podDB.TransactionManager.StartTransaction Try Dim podBT As BlockTable = TryCast(insBlkTrans.GetObject(podDB.BlockTableId, OpenMode.ForRead), BlockTable) Dim podBTR As BlockTableRecord = TryCast(insBlkTrans.GetObject(podBT(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord) If podBT.Has(basename) Then Dim myBlockRef As New BlockReference(InsPt, podBT(basename)) myBlockRef.Rotation = blkRot myBlockRef.ScaleFactors = New Scale3d(scale, scale, scale) podBTR.AppendEntity(myBlockRef) insBlkTrans.AddNewlyCreatedDBObject(myBlockRef, True) If explode Then myBlockRef.ExplodeToOwnerSpace() myBlockRef.Erase() myBlockRef.DisableUndoRecording(False) myBlockRef.DowngradeOpen() End If insBlkTrans.Commit() Else Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, FileShare.Read, True, Nothing) Dim BlkId As ObjectId = podDB.Insert(BlockName, db, True) **'<-- Crashes here --** Dim bt As BlockTable = insBlkTrans.GetObject(podDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = TryCast(insBlkTrans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, True), BlockTableRecord) Dim bref As BlockReference = New BlockReference(InsPt, BlkId) With { .Rotation = blkRot, .ScaleFactors = New Scale3d(scale, scale, scale) } btr.AppendEntity(bref) insBlkTrans.AddNewlyCreatedDBObject(bref, True) If explode Then bref.ExplodeToOwnerSpace() bref.Erase() bref.DisableUndoRecording(False) bref.DowngradeOpen() End If If bt.Has("") And Not bt.Has(basename) Then Dim bad As BlockTableRecord = insBlkTrans.GetObject(bt(""), OpenMode.ForWrite, True) bad.Name = basename bad.Dispose() End If insBlkTrans.Commit() End Using Catch ex As Exception MsgBox(ex.ToString) End Try End If insBlkTrans.Dispose() Catch ex As Exception MsgBox(ex.ToString, MsgBoxStyle.Information) End Try End Using End Sub`
Comments
-
I ran into the same thing. I reported it and think its still a bug. I'll review my support request on this.
0 -
Hi James,
Thanks for looking.0 -
I can't seem to find that support request, I must not have done it.
I need that ability bad too.0 -
Hi James,
I believe I have an answer. It comes from a very smart man named Norman Yuan.
I was sending the entire path and drawing name (including ".dwg") to the line that crashed. It only wants the drawing name without the ".dwg".
Since the ReadDwgFile(BlockName....) gets the full path and drawing name, you only need to use the drawing name for the Dim BlkId line as shown below.
The basename is just the drawing name without the ".dwg"Else Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, FileShare.Read, True, Nothing) Dim BlkId As ObjectId = podDB.Insert(basename, db, True)
I hope that also works for your code. Please let me know if it did.
Best regards,
Mark0 -
oh, Norman Yuan. Yes, he helped me figure out my template for "long processing progress dialog". I literally was just working on a function using that!
I'll test some things right now, I would love to discover I am the problem.0 -
I looked into my code, and I may have a different issue.
Your problem was the block was not in the drawing yet.
Mine is actually worse because I can't get bcad to pull the definition in.
I'll do the support request.0 -
ignore this post, the formatting won't behave
0 -
ok, so two issue I found, and I would say both are bugs you must work around.
You already found the "base name" issue, but may run into more later.First, when you do this:
Database tmpDb = new Database(false, true);
you do need false, true.
It works with true, true for acad, but not for bcad.
Turns out false, true works for both.Second, it seems bcad does not like this when block name is same as dwg name.
db.Insert(bName, tmpDb, true);
What I mean is when you have a symbol called "bub.dwg" and want to insert it as the block "bub".It only likes this for such a case:
db.Insert(bName, bName, tmpDb, true);so I have code like this now to switch between acad and bcad in same code file:
(pound sign)if ACAD
db.Insert(bName, tmpDb, true);
(pound sign)endif
(pound sign)if BCAD
db.Insert(bName, bName, tmpDb, true);
(pound sign)endifif you have not used project vars like ACAD and BCAD, look into them as you can have one code file with different statements depending on the project. You will have one project for acad and bcad, but same .cs code file in each.
There is no comparison to maintaining multiple full .cs files, that would be crazy.
thx0 -
Hi James,
Thanks for the info. I had some additional trouble with bringing a dwg into the drawing. Here is the updated code that works pretty well.`Public Sub InsertBlock(ByVal InsPt As Point3d, ByVal BlockName As String, ByVal basename As String, ByVal explode As Boolean, ByVal rotation As Double, ByVal scale As Double) Dim podDwg As Document = Application.DocumentManager.MdiActiveDocument Dim podDB As Database = podDwg.Database Dim podED As Editor = podDwg.Editor Dim podBT As BlockTable Dim podBTR As BlockTableRecord Using podDwg.LockDocument() Using myTrans As Transaction = podDB.TransactionManager.StartTransaction() podBT = TryCast(podDwg.Database.BlockTableId.GetObject(OpenMode.ForRead), BlockTable) If podBT.Has(basename) Then podBTR = TryCast(podBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite), BlockTableRecord) Dim myBlockRef As New BlockReference(InsPt, podBT(basename)) myBlockRef.Rotation = rotation myBlockRef.ScaleFactors = New Scale3d(scale, scale, scale) podBTR.AppendEntity(myBlockRef) myTrans.AddNewlyCreatedDBObject(myBlockRef, True) If explode Then myBlockRef.ExplodeToOwnerSpace() myBlockRef.Erase() myBlockRef.DisableUndoRecording(False) myBlockRef.DowngradeOpen() End If Else Try Using db As Database = New Database(False, True) db.ReadDwgFile(BlockName, FileShare.Read, True, Nothing) Using tr As Transaction = podDwg.TransactionManager.StartTransaction() -----The next 6 lines helped ----- Dim blkName As String = SymbolUtilityServices.GetBlockNameFromInsertPathName(BlockName) Dim BlkId As ObjectId = podDB.Insert(blkName, db, True) If BlkId.IsNull Then podED.WriteMessage(vbLf & "Failed to insert block") Return End If Dim bt As BlockTable = myTrans.GetObject(podDB.BlockTableId, OpenMode.ForRead, True) Dim btr As BlockTableRecord = CType(tr.GetObject(podDB.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord) Dim bref As BlockReference bref = New BlockReference(InsPt, BlkId) bref.Rotation = rotation bref.ScaleFactors = New Scale3d(scale, scale, scale) btr.AppendEntity(bref) tr.AddNewlyCreatedDBObject(bref, True) If explode Then bref.ExplodeToOwnerSpace() bref.Erase() bref.DisableUndoRecording(False) bref.DowngradeOpen() End If If bt.Has("") And Not bt.Has(basename) Then Dim bad As BlockTableRecord = myTrans.GetObject(bt(""), OpenMode.ForWrite, True) bad.Name = basename bad.Dispose() End If tr.Commit() End Using End Using Catch ex As Exception MsgBox(ex.ToString) End Try End If myTrans.Commit() End Using End Using End Sub'
0 -
@MGorecki
nice, some stuff in there I never use like DisableUndoRecording.
Handy dandy.0