Author Topic: Switch block  (Read 72 times)

0 Members and 1 Guest are viewing this topic.

latour_g

  • Newt
  • Posts: 113
Switch block
« on: August 15, 2017, 04:19:20 pm »
Hi,
I want to be able to switch two blocks.  The user select the first block and then the second block.  After that I switch the position and rotation of those two blocks.  It's working fine except for the attributes, they stay in place.  Is there an easy way to make them follow the new position of the block ? Or I have to find a way to calculate the displacement of the block and apply it to the attributes ?

This is what I have so far, pretty simple :

Code - C++: [Select]
  1. private void btnCopyBlk_Click(object sender, EventArgs e)
  2.        {
  3.            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  4.            Editor ed = doc.Editor;
  5.            Database db = doc.Database;
  6.  
  7.            PromptEntityOptions peo1 = new PromptEntityOptions("Select first block: \n");
  8.            peo1.SetRejectMessage(MB.rmM.GetString("SelNoBlock"));
  9.            peo1.AllowNone = false;
  10.            peo1.AddAllowedClass(typeof(BlockReference), false);
  11.            PromptEntityResult per1 = ed.GetEntity(peo1);
  12.            if (per1.Status != PromptStatus.OK) return;
  13.            if (per1.ObjectId == ObjectId.Null) return;
  14.  
  15.            PromptEntityOptions peo2 = new PromptEntityOptions("Select second block: \n");
  16.            peo2.SetRejectMessage(MB.rmM.GetString("SelNoBlock"));
  17.            peo2.AllowNone = false;
  18.            peo2.AddAllowedClass(typeof(BlockReference), false);
  19.            PromptEntityResult per2 = ed.GetEntity(peo2);
  20.            if (per2.Status != PromptStatus.OK) return;
  21.            if (per2.ObjectId == ObjectId.Null) return;
  22.  
  23.            using (doc.LockDocument())
  24.            {
  25.                using (Transaction tr = db.TransactionManager.StartTransaction())
  26.                {
  27.                    BlockReference br1 = (BlockReference)tr.GetObject(per1.ObjectId, OpenMode.ForWrite);
  28.                    BlockReference br2 = (BlockReference)tr.GetObject(per2.ObjectId, OpenMode.ForWrite);
  29.  
  30.                    Point3d position1 = br1.Position;
  31.                    Point3d position2 = br2.Position;
  32.                    double rotation1 = br1.Rotation;
  33.                    double rotation2 = br2.Rotation;
  34.  
  35.                    br1.Position = position2;
  36.                    br2.Position = position1;
  37.  
  38.                    br1.Rotation = rotation2;
  39.                    br2.Rotation = rotation1;
  40.  
  41.                    tr.Commit();
  42.                }
  43.            }
  44.        }

gile

  • Water Moccasin
  • Posts: 2080
  • Marseille, France
Re: Switch block
« Reply #1 on: August 15, 2017, 06:35:55 pm »
Hi;

The TransformBy() method works on a block and its attributes references.

Try replacing:
Code - C#: [Select]
  1.                    Point3d position1 = br1.Position;
  2.                    Point3d position2 = br2.Position;
  3.                    double rotation1 = br1.Rotation;
  4.                    double rotation2 = br2.Rotation;
  5.  
  6.                    br1.Position = position2;
  7.                    br2.Position = position1;
  8.  
  9.                    br1.Rotation = rotation2;
  10.                    br2.Rotation = rotation1;

with:
Code - C#: [Select]
  1.                    Matrix3d xform1 = br1.BlockTransform;
  2.                    Matrix3d xform2 = br2.BlockTransform;
  3.  
  4.                    br1.TransformBy(xform2 * xform1.Inverse());
  5.                    br2.TransformBy(xform1 * xform2.Inverse());
Speaking English as a French Frog

latour_g

  • Newt
  • Posts: 113
Re: Switch block
« Reply #2 on: August 16, 2017, 09:40:26 am »
Thanks so much it's working fine !