kdub 发表于 2016-2-27 02:56:35

Getting and setting the DimBlk ID used for Closed Filled Arrow

this is based on a question here :
http://forums.autodesk.com/t5/net/dimblk-objectid-for-closed-filled-arrow/m-p/6052755#U6052755
I'm posting here because the code pane is "better"
The issue has several parts.
the dim arrow blocks may not be in the database
... so add the block.
the default 'Closed filled' is named with an empty string and the ObjectId will be Null
look at db.Dimblk = ObjectId.Null;for 'Closed filled'
The code is proof of concept because I'm unsure of the intended final usage.
If you're not using C#6+in VS 2015 then the String interpolation used for WriteLine formatting will need to be modified back to the old formatting.
If you're using VB then http://converter.telerik.com/ will be your friend.
// Proof of concept code 2016-02-27
// codehimbelonga kdub @ theSwamp

using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;



namespace DimBlocks {
    public class MyCommands {
      
      public void MyCommand() {
            TM11();
            AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                "\n\n ====================================\n");
            TM12();
      }

      private static void TM11() {
            var doc = AcadApp.DocumentManager.MdiActiveDocument;
            var db = AcadApp.DocumentManager.MdiActiveDocument.Database;
            var ed = doc.Editor;
            var arrowName = string.Empty;

            // Get the current DIMBLK setting
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to '_OPEN
            AcadApp.SetSystemVariable("DIMBLK", "_OPEN");
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to default 'Closed filled'
            db.Dimblk = ObjectId.Null;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to '_DOT
            AcadApp.SetSystemVariable("DIMBLK", "_DOT");
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");
      }

      private static void TM12() {
            var doc = AcadApp.DocumentManager.MdiActiveDocument;
            var db = AcadApp.DocumentManager.MdiActiveDocument.Database;
            var ed = doc.Editor;
            var arrowName = string.Empty;
            var dimBlockId = ObjectId.Null;

            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            dimBlockId = GetDimBlockId("DIMBLK", "_DOTBLANK");
            db.Dimblk = dimBlockId;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {dimBlockId}\n");

            dimBlockId = GetDimBlockId("DIMBLK", "");
            db.Dimblk = dimBlockId;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {dimBlockId}\n");
      }


      private static ObjectId GetDimBlockId(string dimBlkX, string newArrowName) {
            ObjectId arrowObjId = ObjectId.Null;

            if(string.IsNullOrEmpty(newArrowName)) {
                return ObjectId.Null;
            }

            var db = AcadApp.DocumentManager.MdiActiveDocument.Database;
            var originalArrowName = (string)AcadApp.GetSystemVariable(dimBlkX);

            // Force AutoCAD to add the block to the db.
            AcadApp.SetSystemVariable(dimBlkX, newArrowName);

            // Restore the previous setting
            AcadApp.SetSystemVariable(dimBlkX, originalArrowName);

            using(Transaction tr = db.TransactionManager.StartTransaction()) {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                arrowObjId = bt;
                tr.Commit();
            }
            return arrowObjId;
      }
    }

    public class InitMyCommands : Autodesk.AutoCAD.Runtime.IExtensionApplication {
      public void Initialize() {
            AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n\t\t\t*** type DOIT to run test \t***");
      }

      public void Terminate() {
            AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Cleaning up...");
      }
    }
}

re the image:
The empty dimblk names and null ID's are for the default 'Closed filled' arrow.

kdub 发表于 2016-2-27 10:00:03

Not real relevant to the thread but since you mentioned it.The converter over at http://converter.telerik.com does not convert c#6.0 or the new VB stuff.At least that is what I have found since I use it quite often.I code in VB at work and C# at home.

kdub 发表于 2016-2-27 21:41:18


Thanks for the info Keith.
Fortunately I don't need to deal with VB often.
For those who may need one, which converter would you recommend ?

kdub 发表于 2016-2-28 20:09:24

I've cleaned up a subtle bug in theGetDimBlockId method.
If the current DIMBLK value stored in the variable originalArrowName was the default 'Closed filled' the subsequent restoring of the DIMBLK variable may result in a crash.
The revised code is
            // Restore the previous setting
            if(string.IsNullOrEmpty(originalArrowName)) {
                db.Dimblk = ObjectId.Null;
            }
            else {
                AcadApp.SetSystemVariable(dimBlkX, originalArrowName);
            }
I've also allowed for the newArrowName parameter to have the value of "." in line with the AutoCAD command line option.
            if(string.IsNullOrEmpty(newArrowName)
                || newArrowName.Equals(".")) {
                return ObjectId.Null;
            }

Revised code :
// Proof of concept code 2016-02-29
// codehimbelonga kdub @ theSwamp

using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;



namespace DimBlocks {
    public class MyCommands {
      
      public void MyCommand() {
            TM11();
            AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                "\n\n ====================================\n");
            TM12();
      }

      private static void TM11() {
            var doc = AcadApp.DocumentManager.MdiActiveDocument;
            var db = AcadApp.DocumentManager.MdiActiveDocument.Database;
            var ed = doc.Editor;
            var arrowName = string.Empty;

            // Get the current DIMBLK setting
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to '_OPEN'
            AcadApp.SetSystemVariable("DIMBLK", "_OPEN");
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to default 'Closed filled'
            db.Dimblk = ObjectId.Null;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to '_DOT'
            AcadApp.SetSystemVariable("DIMBLK", "_DOT");
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            // Set to '.'
            AcadApp.SetSystemVariable("DIMBLK", ".");
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK '.'is: {arrowName} \nID is: {db.Dimblk}\n");
      }

      private static void TM12() {
            var doc = AcadApp.DocumentManager.MdiActiveDocument;
            var db = AcadApp.DocumentManager.MdiActiveDocument.Database;
            var ed = doc.Editor;
            var arrowName = string.Empty;
            var dimBlockId = ObjectId.Null;

            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {db.Dimblk}\n");

            dimBlockId = GetDimBlockId("DIMBLK", "_DOTBLANK");
            db.Dimblk = dimBlockId;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK is: {arrowName} \nID is: {dimBlockId}\n");

            dimBlockId = GetDimBlockId("DIMBLK", ".");
            db.Dimblk = dimBlockId;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK '.' is: {arrowName} \nID is: {dimBlockId}\n");

            dimBlockId = GetDimBlockId("DIMBLK", "");
            db.Dimblk = dimBlockId;
            arrowName = (string)AcadApp.GetSystemVariable("DIMBLK");
            ed.WriteMessage($"\nDIMBLK '' is: {arrowName} \nID is: {dimBlockId}\n");
      }


      private static ObjectId GetDimBlockId(string dimBlkX, string newArrowName) {
            ObjectId arrowObjId = ObjectId.Null;

            if(string.IsNullOrEmpty(newArrowName)
                || newArrowName.Equals(".")) {
                return ObjectId.Null;
            }

            var db = AcadApp.DocumentManager.MdiActiveDocument.Database;
            var originalArrowName = (string)AcadApp.GetSystemVariable(dimBlkX);

            // Force AutoCAD to add the block to the db.
            AcadApp.SetSystemVariable(dimBlkX, newArrowName);

            // Restore the previous setting
            if(string.IsNullOrEmpty(originalArrowName)) {
                db.Dimblk = ObjectId.Null;
            }
            else {
                AcadApp.SetSystemVariable(dimBlkX, originalArrowName);
            }

            using(Transaction tr = db.TransactionManager.StartTransaction()) {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                arrowObjId = bt;
                tr.Commit();
            }
            return arrowObjId;
      }
    }

    public class InitMyCommands : Autodesk.AutoCAD.Runtime.IExtensionApplication {
      public void Initialize() {
            AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n\t\t\t*** type DOIT to run test \t***");
      }

      public void Terminate() {
            AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Cleaning up...");
      }
    }
}

New piccy attached:
页: [1]
查看完整版本: Getting and setting the DimBlk ID used for Closed Filled Arrow