Author Topic: Replace blocks by name  (Read 745 times)

0 Members and 1 Guest are viewing this topic.

Offline fixo

  • Full Member
  • ***
  • Posts: 135
  • Karma: +4/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Replace blocks by name
« on: January 03, 2012, 10:30:54 PM »
Hope this framework would be useful for beginners

Code: [Select]
#region Imports

// Microsoft

using System;

using System.Collections.Generic;

using System.Text;

// Autodesk

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Geometry;
#endregion

[assembly: CommandClass(typeof(BlockCS.ReplaceCommands))]

namespace BlockCS
{
    public class ReplaceCommands
    {
        [CommandMethod("BlockReplaceTest", "breplace", CommandFlags.Session | CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]

        public void TestBlockReplaceByName()
        {
            // objects initializing
            Document doc = acadApp.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Database db = doc.Database;

            try
            {
                using (doc.LockDocument())
                {
                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        PromptStringOptions psto =
                            new PromptStringOptions("\nEnter a replacement block name: ");

                        psto.AllowSpaces = true;

                        psto.DefaultValue = "MyBlock";//old block

                        PromptResult stres;

                        stres = ed.GetString(psto);

                        if (stres.Status != PromptStatus.OK)
                            return;

                        string oldblock = stres.StringResult;
                       
                        ed.WriteMessage("\nText Entered\t{0}", oldblock);

                        psto = new PromptStringOptions("\nEnter a block name to be replaced: ");

                        psto.AllowSpaces = true;

                        psto.DefaultValue = "NewBlock";//new block

                        stres = ed.GetString(psto);

                        if (stres.Status != PromptStatus.OK)

                            return;

                        string newblock = stres.StringResult;

                        BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                        if (!bt.Has(newblock)) return;

                        ObjectId newblkId = bt[newblock];

                        acadApp.SetSystemVariable("nomutt", 0);

                        TypedValue[] tvs = { new TypedValue(0, "insert"), new TypedValue(2, oldblock) };

                        SelectionFilter filt = new SelectionFilter(tvs);

                        PromptSelectionOptions pso = new PromptSelectionOptions();

                        pso.MessageForRemoval = "You must select the blocks only";

                        pso.MessageForAdding = "\nSelect replacement blocks: ";

                        ed.SelectionAdded += new SelectionAddedEventHandler(ed_SelectionAdded);

                        PromptSelectionResult res = ed.GetSelection(pso, filt);



                        if (res.Status != PromptStatus.OK) return;

                        BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                        SelectionSet sset = res.Value;

                        foreach (SelectedObject obj in sset)
                        {
                            Entity ent = (Entity)obj.ObjectId.GetObject(OpenMode.ForRead) as Entity;

                            BlockReference oldblk = ent as BlockReference;

                            Point3d ip = oldblk.Position;

                            Scale3d scl = oldblk.ScaleFactors;

                            double rot = oldblk.Rotation;

                            BlockReference newblk = new BlockReference(ip, newblkId);

                            newblk.SetPropertiesFrom(ent);

                            newblk.Rotation = rot;

                            newblk.ScaleFactors = scl;
                           
                            btr.AppendEntity(newblk);

                            tr.AddNewlyCreatedDBObject(newblk, true);

                            ApplyAttributes(db, tr, newblk);

                            oldblk.UpgradeOpen();

                            oldblk.Erase();

                            oldblk.Dispose();

                        }
                     
                        tr.Commit();
                    }

                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);
            }
            finally
            {
                acadApp.SetSystemVariable("nomutt", 1);

               ed.SelectionAdded -= ed_SelectionAdded;
 
            }

        }


        void ed_SelectionAdded(object sender, SelectionAddedEventArgs e)
        {
            ((Editor)sender).WriteMessage("\n\t{0} blocks to selection added", e.AddedObjects.Count);

        }


        public void ApplyAttributes(Database db, Transaction tr, BlockReference bref)
        {
            BlockTableRecord btrec = tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;

            if (btrec.HasAttributeDefinitions)
            {
                Autodesk.AutoCAD.DatabaseServices.AttributeCollection atcoll = bref.AttributeCollection;

                foreach (ObjectId subid in btrec)
                {
                    Entity ent = (Entity)subid.GetObject(OpenMode.ForRead);

                    AttributeDefinition attDef = ent as AttributeDefinition;

                    if (attDef != null)
                    {

                        AttributeReference attRef = new AttributeReference();

                        attRef.SetDatabaseDefaults();//optional

                        attRef.SetAttributeFromBlock(attDef, bref.BlockTransform);

                        attRef.Position = attDef.Position.TransformBy(bref.BlockTransform);

                        attRef.Tag = attDef.Tag;

                        attRef.AdjustAlignment(db);

                        atcoll.AppendAttribute(attRef);

                        tr.AddNewlyCreatedDBObject(attRef, true);

                    }
                }

            }
        }
    }
}

Offline ketxu

  • Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
    • prefered language: VB
    • Prog expertise: Beginner
    • View Profile
Re: Replace blocks by name
« Reply #1 on: January 04, 2012, 07:30:22 AM »
Thanks you.. It's an useful  ex for me ^^
P/s : 4room haven't Thank button, so i post it
Sorry for my poor English

Offline fixo

  • Full Member
  • ***
  • Posts: 135
  • Karma: +4/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Good
    • View Profile
Re: Replace blocks by name
« Reply #2 on: January 04, 2012, 10:01:34 AM »
Glad if this working for you
Thanks,