Inserting a dynamic block with c#

Inserting a dynamic block with c#

Anonymous
Not applicable
4,723 Views
3 Replies
Message 1 of 4

Inserting a dynamic block with c#

Anonymous
Not applicable

Hi Guys!

 

This would be my first time writing in a forum.

 

So, I have been reading guides and copying codes to insert a block into current model space but unfortunately, none of it has worked. There is no error but the block was not inserted into the model space.

 

If you can direct me to any link that I can make as a reference or study, it would be a big help.

 

Here are some of my codes.

 


private void InsertBlock(string blockPath, string blockName)
{
var dm = AcApplication.DocumentManager;
var doc = dm.MdiActiveDocument;
var ed = doc.Editor;
using (var lockDoc = doc.LockDocument())
{
Database db = AcApplication.DocumentManager.MdiActiveDocument.Database;
ImportBlock(blockPath, blockName);

using (Transaction trans = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);

var blockBtr = bt.Cast<ObjectId>().Select(s => (BlockTableRecord)trans.GetObject(s, OpenMode.ForRead)).
Where(s => s.IsDynamicBlock && s.Name == blockName).FirstOrDefault();

BlockTableRecord blockDef = bt[blockName].GetObject(OpenMode.ForRead) as BlockTableRecord;
BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite) as BlockTableRecord;
//ms = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

var point = new Point3d(0, 0, 0);

BlockReference blockRef = new BlockReference(point, blockBtr.ObjectId);

JigBlockMove jig = new JigBlockMove(blockRef);
var pr = ed.Drag(jig);

var entity = jig.GetEntity();
ms.AppendEntity(entity);
trans.AddNewlyCreatedDBObject(entity, true);

trans.Commit();
}
}
}

private void ImportBlock(string sourceFileName, string blockName)
{
if (!File.Exists(sourceFileName)) return;
DocumentCollection dm = AcApplication.DocumentManager;
var ed = dm.MdiActiveDocument.Editor;
Database destDb = dm.MdiActiveDocument.Database;
using (Database sourceDb = new Database(false, true))
{
try
{
// Read the DWG into a side database
sourceDb.ReadDwgFile(sourceFileName, FileOpenMode.OpenForReadAndAllShare, true, "");

// Create a variable to store the list of block identifiers
ObjectIdCollection blockIds = new ObjectIdCollection();
Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = sourceDb.TransactionManager;

using (Transaction myT = tm.StartTransaction())
{
// Open the block table
BlockTable bt = (BlockTable)tm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);

// if the block table contains 'blockName', add its ObjectId to the collection
if (bt.Has(blockName))
blockIds.Add(bt[blockName]);
}

// Copy the block from source to destination database
if (blockIds.Count > 0)
{
IdMapping mapping = new IdMapping();
sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
}

//ed.WriteMessage("\nCopied 1 block definitions from "+ sourceFileName+ " to the current drawing.");
}

catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\nError during copy: " + ex.Message + "\n" + ex.StackTrace);
}
}
}

 

0 Likes
4,724 Views
3 Replies
Replies (3)
Message 2 of 4

_gile
Consultant
Consultant

Hi,

 

You did not show the JigBlockMove class and your code is not very robust.

You could get some inspiration from this example:

 

        private static void InsertBlock(string blockPath, string blockName)
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                ObjectId btrId = bt.Has(blockName) ? 
                    bt[blockName] : 
                    ImportBlock(db, blockName, blockPath);
                if (btrId.IsNull)
                {
                    ed.WriteMessage($"\nBlock '{blockName}' not found.");
                    return;
                }
                using (var br = new BlockReference(Point3d.Origin, btrId))
                {
                    var jig = new InsertBlockJig(br);
                    var pr = ed.Drag(jig);
                    if (pr.Status == PromptStatus.OK)
                    {
                        var cSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                        cSpace.AppendEntity(br);
                        tr.AddNewlyCreatedDBObject(br, true);
                    }
                }
                tr.Commit();
            }
        }

        private static ObjectId ImportBlock(Database destDb, string blockName, string sourceFileName)
        {
            if (System.IO.File.Exists(sourceFileName))
            {
                using (var sourceDb = new Database(false, true))
                {
                    try
                    {
                        // Read the DWG into a side database
                        sourceDb.ReadDwgFile(sourceFileName, FileOpenMode.OpenForReadAndAllShare, true, "");

                        // Create a variable to store the block identifier
                        var id = ObjectId.Null;
                        using (var tr = new OpenCloseTransaction())
                        {
                            // Open the block table
                            var bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);

                            // if the block table contains 'blockName', store it into the variable
                            if (bt.Has(blockName))
                                id = bt[blockName];
                        }
                        // if the variable is not null (i.e. the block was found)
                        if (!id.IsNull)
                        {
                            // Copy the block deinition from source to destination database
                            var blockIds = new ObjectIdCollection();
                            blockIds.Add(id);
                            var mapping = new IdMapping();
                            sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                            // if the copy succeeded, return the ObjectId of the clone
                            if (mapping[id].IsCloned)
                                return mapping[id].Value;
                        }
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        var ed = AcApplication.DocumentManager.MdiActiveDocument.Editor;
                        ed.WriteMessage("\nError during copy: " + ex.Message + "\n" + ex.StackTrace);
                    }
                }
            }
            return ObjectId.Null;
        }

        class InsertBlockJig : EntityJig
        {
            BlockReference br;
            Point3d pt;

            public InsertBlockJig(BlockReference br) : base(br)
            {
                this.br = br;
            }

            protected override SamplerStatus Sampler(JigPrompts prompts)
            {
                var options = new JigPromptPointOptions("\nSpecify insertion point: ");
                options.UserInputControls = UserInputControls.Accept3dCoordinates;
                var result = prompts.AcquirePoint(options);
                if (result.Value.IsEqualTo(pt))
                    return SamplerStatus.NoChange;
                pt = result.Value;
                return SamplerStatus.OK;
            }

            protected override bool Update()
            {
                br.Position = pt;
                return true;
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 4

Anonymous
Not applicable

Hi Gilles!

 

Thanks for your quick response.

 

JibBlockMove class was just basically from here

https://www.keanw.com/2015/05/jigging-an-autocad-block-with-attributes-using-net-redux.html

 

So I tested your code and I am having an 'eLockViolation' error so have to wrap your code with doc.LockDcument(). 

Still, the block doesn't show on the model space. Am I missing something? I'm testing it in AutoCAD2019 by the way.

 

private void InsertBlock(string blockPath, string blockName)
{
var doc = AcApplication.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
using (var docLock = doc.LockDocument())
{
using (var tr = db.TransactionManager.StartTransaction())
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
ObjectId btrId = bt.Has(blockName) ? bt[blockName] : ImportBlock(db, blockName, blockPath);
if (btrId.IsNull)
{
ed.WriteMessage($"\nBlock '{blockName}' not found.");
return;
}

using (var br = new BlockReference(Point3d.Origin, btrId))
{

var jig = new JigBlockMove(br);
var pr = ed.Drag(jig);
if (pr.Status == Autodesk.AutoCAD.EditorInput.PromptStatus.OK)
{
var cSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
cSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
}
}
tr.Commit();
}
}

}

0 Likes
Message 4 of 4

_gile
Consultant
Consultant

Hi,

 

The 'eLockViolation' error is probably due to the way you call the method: from a modeless dialog or from a command decores with the CommandFlags.Session (do not use CommandFlags.Session if it's not absolutely required by your code).

 

The fact you do not see the block reference during the insertion (jig) may be due to ablock definition which only contains attribute definitions.

When inserting attributed block references, you have to explicitely add the attribute references to the Attribute Collection of the block reference and if you use a Jig for insertion, you also have to manage the attribute references jigging.

 

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

using System.Collections.Generic;

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

[assembly: CommandClass(typeof(InsertAttributedBlockSample.Commands))]

namespace InsertAttributedBlockSample
{
    public class Commands
    {
        [CommandMethod("TEST")]
        public static void Test()
        {
            InsertBlock(@"B:\Desktop\Test.dwg", "bloc-att");
        }

        private static void InsertBlock(string blockPath, string blockName)
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                ObjectId btrId = bt.Has(blockName) ?
                    bt[blockName] :
                    ImportBlock(db, blockName, blockPath);
                if (btrId.IsNull)
                {
                    ed.WriteMessage($"\nBlock '{blockName}' not found.");
                    return;
                }

                var cSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                var br = new BlockReference(Point3d.Origin, btrId);
                cSpace.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);

                // add attribute references to the block reference
                var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                var attInfos = new Dictionary<string, TextInfo>();
                if (btr.HasAttributeDefinitions)
                {
                    foreach (ObjectId id in btr)
                    {
                        if (id.ObjectClass.DxfName == "ATTDEF")
                        {
                            var attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
                            attInfos[attDef.Tag] = new TextInfo(
                                attDef.Position,
                                attDef.AlignmentPoint,
                                attDef.Justify != AttachmentPoint.BaseLeft,
                                attDef.Rotation);
                            var attRef = new AttributeReference();
                            attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                            attRef.TextString = attDef.TextString;
                            br.AttributeCollection.AppendAttribute(attRef);
                            tr.AddNewlyCreatedDBObject(attRef, true);
                        }
                    }
                }
                var jig = new InsertBlockJig(br, attInfos);
                var pr = ed.Drag(jig);
                if (pr.Status != PromptStatus.OK)
                {
                    br.Erase();
                }
                tr.Commit();
            }
        }

        private static ObjectId ImportBlock(Database destDb, string blockName, string sourceFileName)
        {
            if (System.IO.File.Exists(sourceFileName))
            {
                using (var sourceDb = new Database(false, true))
                {
                    try
                    {
                        // Read the DWG into a side database
                        sourceDb.ReadDwgFile(sourceFileName, FileOpenMode.OpenForReadAndAllShare, true, "");

                        // Create a variable to store the block identifier
                        var id = ObjectId.Null;
                        using (var tr = new OpenCloseTransaction())
                        {
                            // Open the block table
                            var bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);

                            // if the block table contains 'blockName', store it into the variable
                            if (bt.Has(blockName))
                                id = bt[blockName];
                        }
                        // if the variable is not null (i.e. the block was found)
                        if (!id.IsNull)
                        {
                            // Copy the block deinition from source to destination database
                            var blockIds = new ObjectIdCollection();
                            blockIds.Add(id);
                            var mapping = new IdMapping();
                            sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                            // if the copy succeeded, return the ObjectId of the clone
                            if (mapping[id].IsCloned)
                                return mapping[id].Value;
                        }
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        var ed = AcApplication.DocumentManager.MdiActiveDocument.Editor;
                        ed.WriteMessage("\nError during copy: " + ex.Message + "\n" + ex.StackTrace);
                    }
                }
            }
            return ObjectId.Null;
        }

        struct TextInfo
        {
            public Point3d Position { get; private set; }
            public Point3d Alignment { get; private set; }
            public bool IsAligned { get; private set; }
            public double Rotation { get; private set; }
            public TextInfo(Point3d position, Point3d alignment, bool aligned, double rotation)
            {
                Position = position;
                Alignment = alignment;
                IsAligned = aligned;
                Rotation = rotation;
            }
        }

        class InsertBlockJig : EntityJig
        {
            BlockReference br;
            Point3d pt;
            Dictionary<string, TextInfo> attInfos;

            public InsertBlockJig(BlockReference br, Dictionary<string, TextInfo> attInfos) : base(br)
            {
                this.br = br;
                this.attInfos = attInfos;
            }

            protected override SamplerStatus Sampler(JigPrompts prompts)
            {
                var options = new JigPromptPointOptions("\nSpecify insertion point: ");
                options.UserInputControls = UserInputControls.Accept3dCoordinates;
                var result = prompts.AcquirePoint(options);
                if (result.Value.IsEqualTo(pt))
                    return SamplerStatus.NoChange;
                pt = result.Value;
                return SamplerStatus.OK;
            }

            protected override bool Update()
            {
                br.Position = pt;
                if (br.AttributeCollection.Count > 0)
                {
                    var tr = br.Database.TransactionManager.TopTransaction;
                    foreach (ObjectId id in br.AttributeCollection)
                    {
                        var attRef = (AttributeReference)tr.GetObject(id, OpenMode.ForRead);
                        string tag = attRef.Tag.ToUpper();
                        if (attInfos.ContainsKey(tag))
                        {
                            TextInfo ti = attInfos[tag];
                            attRef.Position = ti.Position.TransformBy(br.BlockTransform);
                            if (ti.IsAligned)
                            {
                                attRef.AlignmentPoint =
                                    ti.Alignment.TransformBy(br.BlockTransform);
                                attRef.AdjustAlignment(br.Database);
                            }
                            if (attRef.IsMTextAttribute)
                            {
                                attRef.UpdateMTextAttribute();
                            }
                        }
                    }
                }
                return true;
            }
        }
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub