Author Topic: Walking a DGN Reference  (Read 2062 times)

0 Members and 1 Guest are viewing this topic.

sinc

  • Guest
Walking a DGN Reference
« on: August 07, 2010, 11:52:17 AM »
Does anyone know how DgnReference items work?  I can't seem to find much info in the API, and searching the web hasn't turned anything up, either.

It looks like a DgnReference has a Transform object, much like blocks, so I think that part looks simple enough.  But from there, I get lost.  How would I, for example, get to the ObjectIds of the objects in the DgnReference?  It looks like the DgnReference.DefinitionId can be used to get to the DgnDefinition...  That might be part of it.  But I can't figure out how to use that DgnDefinition to get to the objects in the DGN.

LE3

  • Guest
Re: Walking a DGN Reference
« Reply #1 on: August 07, 2010, 03:16:54 PM »
Hi Sinc,

I found this url link, no idea if can be of some help for you, they have several code samples:

http://www.la-solutions.co.uk/content/publications-MVBA.htm

maybe...


kaefer

  • Guest
Re: Walking a DGN Reference
« Reply #2 on: January 02, 2011, 08:10:07 PM »
[...] How would I, for example, get to the ObjectIds of the objects in the DgnReference?  It looks like the DgnReference.DefinitionId can be used to get to the DgnDefinition...  That might be part of it.  But I can't figure out how to use that DgnDefinition to get to the objects in the DGN.

Me neither. Poking around, i.e. selecting nested entities interactively, reveals that the Underlay is actually held in a separate Database.

While there aren't any exposed members accessible from the Underlay paraphernalia, this Database can also be obtained by listening to the DatabaseConstructed event, which fires when an Underlay is attached. This should suffice for automatic processing, while the manual approach with an existing Underlay would require the selection of a nested entity.

Demo in F#; asks for a DGN file name (as string), attaches it, captures the database and prints type and handle of all objects in its ModelSpace.

Code: [Select]
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Runtime

type acApp = Autodesk.AutoCAD.ApplicationServices.Application

let dgnAttach dgnSourceFile =
    if System.IO.File.Exists dgnSourceFile then
        let dgnName = SymbolUtilityServices.GetSymbolNameFromPathName(dgnSourceFile, "*")

        let db = acApp.DocumentManager.MdiActiveDocument.Database
        use tr = db.TransactionManager.StartTransaction()
        let nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite) :?> DBDictionary
        let defDictKey = UnderlayDefinition.GetDictionaryKey(typeof<DgnDefinition>)

        if not(nod.Contains defDictKey) then
            let dict = new DBDictionary()
            nod.SetAt(defDictKey, dict) |> ignore
            tr.AddNewlyCreatedDBObject(dict, true)
 
        let dgnDict = tr.GetObject(nod.GetAt(defDictKey), OpenMode.ForWrite) :?> DBDictionary
        let dgnDef = new DgnDefinition(SourceFileName = dgnSourceFile)
        let dgnDefId = dgnDict.SetAt(dgnName, dgnDef)                   
        tr.AddNewlyCreatedDBObject(dgnDef, true)

        let btr = tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId db, OpenMode.ForWrite) :?> BlockTableRecord
        let dgnRef = new DgnReference(DefinitionId = dgnDefId)
        btr.AppendEntity dgnRef |> ignore
        tr.AddNewlyCreatedDBObject(dgnRef, true)
                   
        tr.Commit()
    else
        raise <| new System.IO.FileNotFoundException(dgnSourceFile)

let mutable newDb = None

let databaseConstructedHandler =
    new System.EventHandler(
        fun sender _ -> newDb <- Some(sender :?> Database) )
 
[<CommandMethod "MyDgnAttach">]
let myDgnAttachCmd() =
    let doc = acApp.DocumentManager.MdiActiveDocument
    let ed = doc.Editor
    let pstrr = ed.GetString("\nDGN file to attach: ")
    if pstrr.Status = PromptStatus.OK then
        Database.DatabaseConstructed.AddHandler databaseConstructedHandler
        dgnAttach pstrr.StringResult
        Database.DatabaseConstructed.RemoveHandler databaseConstructedHandler

        if newDb.IsSome then
            let dbx = newDb.Value
            use tr = dbx.TransactionManager.StartTransaction()
            let btrId = SymbolUtilityServices.GetBlockModelSpaceId dbx
            let btr = tr.GetObject(btrId, OpenMode.ForRead) :?> BlockTableRecord
            for oid in btr do
                let dbo = tr.GetObject(oid, OpenMode.ForRead)
                ed.WriteMessage(
                    "\n{0} {1} ",
                    dbo.GetType(),
                    string dbo.Handle )
            tr.Commit()

Cheers, Thorsten

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Walking a DGN Reference
« Reply #3 on: January 05, 2011, 12:35:24 PM »
There are DGN libraries available from http://www.opendesign.com/the_oda_platform/tg
I haven't worked with them.
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions