Scale nested blocks and refresh graphics

E3DE
Enthusiast
Enthusiast

Scale nested blocks and refresh graphics

E3DE
Enthusiast
Enthusiast

Hi,

In my dwg I have blockrefrences entities that contains n nested blockreferences. For example a chair block and its nested blocks: arms, legs, back, etc.

My program cycles over each nestest block and change the scale factors.

The problem is that I need to change view to see the changes.

I try to use QueueForGraphicsFlush with no result.

 

Thank you

 

This is my sample code:

        [CommandMethod("scalanestedblocks", CommandFlags.Transparent)]
        public void scalanestedblocks()
        {
            Document d = ACAP.Application.DocumentManager.MdiActiveDocument;
            Editor ed = d.Editor;

            var per = ed.GetEntity("Select blockreference:");
            if (per.Status == PromptStatus.OK)
            {
                using (Transaction tr = d.TransactionManager.StartTransaction())
                {
                    BlockReference mainBlockRef = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
                    if (mainBlockRef == null) return;

                    BlockTableRecord mainBTR = tr.GetObject(mainBlockRef.BlockTableRecord, OpenMode.ForWrite) as BlockTableRecord;
                    if (mainBTR == null)
                        return;

                    ed.WriteMessage("Main block ref: " + mainBTR.Name + Environment.NewLine);

                    foreach (ObjectId nestedBlokRefId in mainBTR)
                    {
                        BlockReference nestedBlockRef = tr.GetObject(nestedBlokRefId, OpenMode.ForWrite) as BlockReference;
                        if (nestedBlockRef == null) 
                            continue;

                        ed.WriteMessage("       +--- Nested block ref: " + nestedBlockRef.Name + Environment.NewLine);

                        if (nestedBlockRef.ScaleFactors.X < 1.5)
                            nestedBlockRef.ScaleFactors = new Scale3d(2, 2, 2);
                        else
                            nestedBlockRef.ScaleFactors = new Scale3d(1, 1, 1);
                    }

                    d.TransactionManager.QueueForGraphicsFlush();
                    d.TransactionManager.FlushGraphics();
                    tr.Commit();
                }
            }
        }

 

0 Likes
Reply
Accepted solutions (2)
771 Views
5 Replies
Replies (5)

_gile
Mentor
Mentor
Accepted solution

Hi,

 

Just add: ed.Regen(); at the end of your code.

 

Some remarks:

You could avoid checking if an entity is null after opening it as 'some type':

- you can define allowed classes using a PromptEntityOptions instance

- you can check the ObjectId.ObjectClass before opening it.

 

        [CommandMethod("SCALANESTEDBLOCKS", CommandFlags.Transparent)]
        public void ScalaNestedBlocks()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var options = new PromptEntityOptions("\nSelect block reference: ");
            options.SetRejectMessage("\nSelected object is not a bloc reference.");
            options.AddAllowedClass(typeof(BlockReference), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var br = (BlockReference)tr.GetObject(result.ObjectId, OpenMode.ForRead);
                var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
                var brClass = RXObject.GetClass(typeof(BlockReference));
                foreach (ObjectId id in btr)
                {
                    if (id.ObjectClass == brClass)
                    {
                        var nestedBr = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
                        if (nestedBr.ScaleFactors.X < 1.5)
                            nestedBr.ScaleFactors = new Scale3d(2.0, 2.0, 2.0);
                        else
                            nestedBr.ScaleFactors = new Scale3d(1.0, 1.0, 1.0);
                    }
                }
                tr.Commit();
            }
            ed.Regen();
        }

PS: it would be nice of you if you give some feedback on the answers you got in your previous posts.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

E3DE
Enthusiast
Enthusiast

Thank you,

My application do this operation on many "main" blocks.

Is it possibile to regen/refresh single blockrefence after setting scale factor?

 

Thank you very much

0 Likes

_gile
Mentor
Mentor

Could you clarify what you mean with "regen/refresh single blockrefence after setting scale factor" because "setting scale factor" is done in the block table record and this will affect all the block references.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

E3DE
Enthusiast
Enthusiast
Yes, 
I need to precess many different BlockReferences (different block definition), call this primary block.For each of this I need to change scale of nested BlockReferences. It's possible to regen a main block (only this one) after has been processed and before to precess the next?Thank you


0 Likes

_gile
Mentor
Mentor
Accepted solution

You can update the block references calling RecordGraphicsModified(true) on each reference of the edited block table record.

 

        [CommandMethod("SCALANESTEDBLOCKS", CommandFlags.Transparent)]
        public void ScalaNestedBlocks()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var options = new PromptEntityOptions("\nSelect block reference: ");
            options.SetRejectMessage("\nSelected object is not a bloc reference.");
            options.AddAllowedClass(typeof(BlockReference), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var br = (BlockReference)tr.GetObject(result.ObjectId, OpenMode.ForRead);
                var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
                var brClass = RXObject.GetClass(typeof(BlockReference));
                foreach (ObjectId id in btr)
                {
                    if (id.ObjectClass == brClass)
                    {
                        var nestedBr = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
                        if (nestedBr.ScaleFactors.X < 1.5)
                            nestedBr.ScaleFactors = new Scale3d(2.0, 2.0, 2.0);
                        else
                            nestedBr.ScaleFactors = new Scale3d(1.0, 1.0, 1.0);
                    }
                }
                foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
                {
                    var b = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
                    b.RecordGraphicsModified(true);
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes