.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

block not placing on newly opened drawing

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
kmkxperia
203 Views, 3 Replies

block not placing on newly opened drawing

Hi Below are the Things I want to achieve
1. Get the block from the File location
2. Insert the Block on Drawing
3. Then Rotate this block along the insertion point

1: Issue that I facing is in Step 2 where when I run the command of fresh drawing instead of placing the block it goes to 
"\nBlock '{blockName}' not found." unless I manually place the block it does not proceed further.. expected was it should had added this new block and updated the Block table accordingly..

2: Other part is Step 3 once I place the block I want to rotate it but not sure how to do place the code as when i use the rotationjig file it crashes auto ca with error enotopenforwrite.


using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace palet.TESTCODES
{
    public class Commands_InsertBlock
    {
        [CommandMethod("Insertblockp")]
        public static void Test()
        {

            string blockFilePath = @"C:\block\_temp.dwg";
            string blockName = "_temp";

            InsertBlock(blockFilePath, blockName);
        }

        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 = Application.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;
            }
        }
    }
}

 

3 REPLIES 3
Message 2 of 4
norman.yuan
in reply to: kmkxperia

For your first issue, if you simply had stepped through the code in ImportBlock() method, you would have easily found out why the block definition has been imported or not. Is the source drawing is a block drawing, or a drawing that contains many block definitions (you only use WBlockCloneObjects() for the latter; if it is former, you use Database.Insert() to bring a block drawing in as block definition)? It looks to me, the drawing seems to be a block drawing (i.e. the source drawing does not contain a block definition with the given block name), thus, nothing is imported. Again, you need to know when to use Database.Insert() andDatabase.WBlockCloneObjects(), and very basic debug work could let you find code error easily and quickly.

 

The second issue you have is quite obvious as the exception message tells: your code in the Update() method opens each AttributeReference FOR READ, yet the code continue to change the AttributeReference (its position), thus the error.

 

BTW, since you mention the Jig is meant rotate the inserted block reference, the code in your jig does not make sense in terms of rotation. It should determine a rotation angle based on a mouse's move/drag with a base point (block insertion point would be the default) in the Sample() method, where you get a Matrix3d.Rotation, then you can transform the block reference as WHOLE, no need to do it against attributes individually (unless the the attributes may be required to rotated differently for some reasons, but then the rotation Matrix3ds have to calculated differently).

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 4
kmkxperia
in reply to: kmkxperia

yes you are correct  Database.Insert() is what I should have used.. just overlooked it.. also for the error I was closing the Transaction and trying to do the rotation that was causing Autocad to Crash.. 
now all works fine after refactoring the code.. 
 
for Block rotation I need to rotate the text as well  with the block so its aligned with the rotation.. so if you can point to some example how we achieve this will help.

Message 4 of 4
norman.yuan
in reply to: kmkxperia

By "...rotate the text as well", I assume you meant the AttributeReferences of the BlockReference. As I said previously, you do not need to rotate them individually while you are jigging the blockreference. You transform the blockreference as whole after you obtain the rotation transforming Matrix3d (pseudocode)

 

protected override SimplerStatus Sampler(...)

{

   // acquired rotation angle here.

  if ([result.Status!=PromptStatus.Ok) return SamplerStatus.Cancel;

 

  if (currentAngle != newAngle)

  {

     var angle=newAngle-currentAngle

     var mt=Matrix3d.Rotation([basePoint], angle, Vector3d.ZAxis)

     // this would transform BlockReference as whole (i.e. including the attributes it owns)

     [BlockReference].TransformBy(mt);

     return SamplerStatus.OK;

  }

  else

  {

     return SamplerStatus.NoChange;

  }

}

 

 

Norman Yuan

Drive CAD With Code

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report