Accessing DWG files not open in the AutoCAD editor using .NET

This topic was briefly introduced almost a year ago, in this post. I then looked into the code a little further in a follow-up post. But at the time this topic wasn't the main thrust of the post, it was really more of an implementation detail.

So now it's time to do the topic a little more justice. :-)

Let's start with some terminology. What we're talking about today are often referred to as "side databases" or "external databases". Basically they're DWG files that are not open in the AutoCAD editor, but ones we want to access programmatically to load geometry or settings. You may also hear the term "lazy loaded" - these DWG files are not loaded completely into memory (unless you choose to access all the data stored in them), they are brought in, as needed, making the access very efficient.

Side databases have been available through ObjectARX since it was introduced in R13, but were introduced more recently in COM (the AxDb implementation was introduced several releases back, although I can't remember exactly when... perhaps it was in AutoCAD 2000 but it might have been later) and .NET (when we introduced the managed layer in 2005, I believe). One interesting point to note, is that any code you write using ObjectARX or .NET to access side databases can be used with almost no modification on top of RealDWG to access the same data outside AutoCAD. Although any code that's intermingled which accesses AutoCAD-resident functionality will not work, of course.

The basic technique is to create a Database object, and read a DWG file into it. Please remember to use the appropriate constructor: the standard constructor without arguments creates a Database object that cannot be used in this manner (it creates one that you would typically use to create a new DWG file). When reading a DWG you will need to pass False as the first argument - what you pass as the second depends on your need.

From there you work with the Database object, accessing the header variables and the objects stored in the various dictionaries and symbol tables, just as you would inside AutoCAD.

Let's take a very simple example, where we open a particular file on disk, and iterate through the model-space, listing a little bit of data about each object:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;


namespace ExtractObjects

{

  public class Commands

  {

    [CommandMethod("EOF")]

    static public void ExtractObjectsFromFile()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;


      // Ask the user to select a file

      PromptResult res =

        ed.GetString(

          "/nEnter the path of a DWG or DXF file: "

        );


      if (res.Status == PromptStatus.OK)

      {

        // Create a database and try to load the file

        Database db = new Database(false, true);

        using (db)

        {

          try

          {

            db.ReadDwgFile(

              res.StringResult,

              System.IO.FileShare.Read,

              false,

              ""

            );

          }

          catch (System.Exception)

          {

            ed.WriteMessage(

              "/nUnable to read drawing file."

            );

            return;

          }


          Transaction tr =

            db.TransactionManager.StartTransaction();

          using (tr)

          {

            // Open the blocktable, get the modelspace

            BlockTable bt =

              (BlockTable)tr.GetObject(

                db.BlockTableId,

                OpenMode.ForRead

              );


            BlockTableRecord btr =

              (BlockTableRecord)tr.GetObject(

                bt[BlockTableRecord.ModelSpace],

                OpenMode.ForRead

              );



            // Iterate through it, dumping objects

            foreach (ObjectId objId in btr)

            {

              Entity ent =

                (Entity)tr.GetObject(

                  objId,

                  OpenMode.ForRead

                );


              // Let's get rid of the standard namespace

              const string prefix =

                "Autodesk.AutoCAD.DatabaseServices.";

              string typeString =

                ent.GetType().ToString();

              if (typeString.Contains(prefix))

                typeString =

                  typeString.Substring(prefix.Length);


              ed.WriteMessage(

                "/nEntity " +

                ent.ObjectId.ToString() +

                " of type " +

                typeString +

                " found on layer " +

                ent.Layer +

                " with colour " +

                ent.Color.ToString()

              );

            }

          }

        }

      }

    }

  }

}

Here's what happens when you run the code:

Command: EOF


Enter the path of a DWG or DXF file: "C:/Program Files/Autodesk/AutoCAD

2007/Sample/Sheet Sets/Architectural/S-03.dwg"


Entity (2127693096) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693104) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693112) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693120) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693128) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693224) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693232) of type Line found on layer Struc_Plan_GB_PL with colour

BYLAYER

Entity (2127693368) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693376) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693384) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693392) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693400) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693408) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693416) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127693424) of type Line found on layer Struc_Plan_Ext with colour

BYLAYER

Entity (2127695000) of type Line found on layer 2_Arch_Plan_Dim with colour

BYLAYER

Entity (2127695448) of type BlockReference found on layer 0 with colour BYLAYER

Entity (2127624240) of type BlockReference found on layer Building Section (2)

with colour BYLAYER

Entity (2127656048) of type BlockReference found on layer Structrual Base2 with

colour BYLAYER

Entity (2127656304) of type BlockReference found on layer grid plan with colour

BYLAYER

Entity (2127656560) of type BlockReference found on layer Stair 2 with colour

BYLAYER

I'm interested in looking at more complex scenarios where people might need to access side databases from their code. Please post any suggestions you might have as a comment (or just drop me an email).

 
可从以下几方面排查解决无法访问主数据库、主数据库功能不可用的问题。 首先,若使用的是 Nacos 连接数据库,要确认数据库账号的 Host 属性是否正确修改,且账号具备远程连接条件。例如修改 root 账号的远程连接条件,可使用以下 SQL 语句: ```sql grant all privileges on *.* to 'root'@'%'; flush privileges; ``` 这样能确保账号有相应的远程连接权限,避免因权限问题导致无法连接数据库,影响主数据库功能使用[^1]。 其次,若通过 JDBC 连接数据库,要保证连接代码无误。以下是一个简单示例: ```java import java.sql.Connection; import java.sql.DriverManager; public class DatabaseConnection { public static void main(String[] args) { String mydatabase = "jdbc:mysql://localhost:3306/your_database_name"; String username = "your_username"; String password = "your_password"; try { Connection connection = DriverManager.getConnection(mydatabase, username, password); // 执行后续操作 } catch (Exception e) { e.printStackTrace(); } } } ``` 确保正确传入数据库的 URL、用户名和密码,才能成功连接数据库,保证主数据库功能可用[^2]。 若在 QT 环境下多线程访问 MySQL 数据库,在断开与数据库的链接时,要按正确步骤操作。以下是相应代码示例: ```cpp void MainWindow::arrive_msg_handl(QMQTT::Message msg) { // 在线程中打开数据库的操作 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("localhost"); db.setPort(3306); db.setDatabaseName("your_database_name"); db.setUserName("root"); db.setPassword("your_password"); bool ok = db.open(); if (ok) { qDebug() << "连接成功"; } else { qDebug() << "不能连接" << "connect to mysql error" << db.lastError().text(); } // 在这里写你自己的数据库操作!! // 在线程中关闭数据库的操作 QString connection; connection = db.connectionName(); db.close(); db = QSqlDatabase(); db.removeDatabase(connection); } ``` 正确的断开连接操作能避免因资源未正确释放导致后续无法访问数据库,保证主数据库功能正常使用[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值