Code Red > .NET

FAIL: Scaling BlockReference with Attributes using SetAttributeFromBlock

<< < (2/2)

Bryco:
Give this a go.
You are not making new atts so they may be alraedy scaled, so you need to reverse that scaling (see premultiply) first.


--- Code: ---        [CommandMethod("ScaleBlock")]
        public void ScaleBlock()
        {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;       
            PromptEntityOptions peo = new PromptEntityOptions("Select an block reference to scale:");
            peo.SetRejectMessage("Must be a Blockreference:");
            peo.AddAllowedClass(typeof(BlockReference), true);
            PromptEntityResult per = ed.GetEntity(peo);
            double scale = 3.0,scaleFactor;
            if (per.Status != PromptStatus.OK) return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockReference br = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
                scaleFactor = br.ScaleFactors.X;               
                br.ScaleFactors = new Scale3d(scale);
                Matrix3d m = br.BlockTransform;
                Matrix3d m2 = m.PreMultiplyBy(Matrix3d.Scaling(1/scaleFactor,br.Position));
                BlockTableRecord btr = tr.GetObject(br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                if (!btr.HasAttributeDefinitions) goto commit;
               
                foreach (ObjectId attdefId in btr)
                {
                    if (attdefId.ObjectClass.DxfName != "ATTDEF") continue;
                    AttributeDefinition attdef = tr.GetObject(attdefId, OpenMode.ForRead) as AttributeDefinition;
                    foreach (ObjectId id in br.AttributeCollection)
                    {
                        AttributeReference att = tr.GetObject(id, OpenMode.ForWrite) as AttributeReference;
                        if (att.Tag == attdef.Tag)
                        {
                            att.SetAttributeFromBlock(m2);
                            att.Position = attdef.Position.TransformBy(m);
                            if (attdef.Justify != AttachmentPoint.BaseLeft)
                                att.AlignmentPoint = attdef.AlignmentPoint.TransformBy(m);
                            if (att.IsMTextAttribute)
                                att.UpdateMTextAttribute();
                        }
                    }
                }

            commit:
                tr.Commit();
            }
   
        }
--- End code ---

dugk:
Your suggestions worked like a charm!  THANK YOU!

Here is my version with your additional code (minus the unchanged ssGetSingleInsert and ssGetSingleWithFilter):

--- Code: ---        [CommandMethod("scaleBlock")]
        public static void scaleBlock()
        {
            Document acActiveDoc = AcApSrvApp.DocumentManager.MdiActiveDocument;
            Editor acActiveDocEd = acActiveDoc.Editor;
            Database acCurDb = acActiveDoc.Database;

            ObjectId[] id = ssGetSingleInsert("Select a block insert");
            if (id.Length > 0)
            {
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    DBObject objBr = acTrans.GetObject(id[0], OpenMode.ForRead);
                    BlockReference br = objBr as BlockReference;
                    if (br != null)
                    {
                        double scale = 3.0;
                        double scaleFactor = 1.0;
                        br.UpgradeOpen();
                        br.ScaleFactors = new Scale3d(scale);
                        Matrix3d m = br.BlockTransform;
                        Matrix3d m2 = m.PreMultiplyBy(Matrix3d.Scaling(1 / scaleFactor, br.Position));

                        BlockTableRecord btr = acTrans.GetObject(br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                        if (btr.HasAttributeDefinitions)
                        {
                            foreach (ObjectId objId in btr)
                            {
                                DBObject objAd = acTrans.GetObject(objId, OpenMode.ForRead);
                                AttributeDefinition ad = objAd as AttributeDefinition;
                                if (ad != null && !ad.Constant)
                                {
                                    foreach (ObjectId idAtt in br.AttributeCollection)
                                    {
                                        AttributeReference att = acTrans.GetObject(idAtt, OpenMode.ForWrite) as AttributeReference;
                                        if (att.Tag == ad.Tag)
                                        {
                                            att.SetAttributeFromBlock(m2);
                                            att.Position = ad.Position.TransformBy(m);
                                            if (ad.Justify != AttachmentPoint.BaseLeft)
                                                att.AlignmentPoint = ad.AlignmentPoint.TransformBy(m);
                                            if (att.IsMTextAttribute)
                                                att.UpdateMTextAttribute();
                                        }
                                    }
                                }
                            }
                        }
                    }
                    acTrans.Commit();
                    acTrans.Dispose();
                }
            }
        }
--- End code ---

Thanks again!
Doug

Bryco:
Glad it helps.

dugk:
I found an error in my code.

old: 
--- Code: ---double scaleFactor = 1.0;
--- End code ---
new: 
--- Code: ---double scaleFactor = br.ScaleFactors.X;
--- End code ---


--- Code: ---        [CommandMethod("scaleBlock")]
        public static void scaleBlock()
        {
            Document acActiveDoc = AcApSrvApp.DocumentManager.MdiActiveDocument;
            Editor acActiveDocEd = acActiveDoc.Editor;
            Database acCurDb = acActiveDoc.Database;

            ObjectId[] id = ssGetSingleInsert("Select a block insert");
            if (id.Length > 0)
            {
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    DBObject objBr = acTrans.GetObject(id[0], OpenMode.ForRead);
                    BlockReference br = objBr as BlockReference;
                    if (br != null)
                    {
                        double scale = 3.0;
                        double scaleFactor = br.ScaleFactors.X;
                        br.UpgradeOpen();
                        br.ScaleFactors = new Scale3d(scale);
                        Matrix3d m = br.BlockTransform;
                        Matrix3d m2 = m.PreMultiplyBy(Matrix3d.Scaling(1 / scaleFactor, br.Position));

                        BlockTableRecord btr = acTrans.GetObject(br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                        if (btr.HasAttributeDefinitions)
                        {
                            foreach (ObjectId objId in btr)
                            {
                                DBObject objAd = acTrans.GetObject(objId, OpenMode.ForRead);
                                AttributeDefinition ad = objAd as AttributeDefinition;
                                if (ad != null && !ad.Constant)
                                {
                                    foreach (ObjectId idAtt in br.AttributeCollection)
                                    {
                                        AttributeReference att = acTrans.GetObject(idAtt, OpenMode.ForWrite) as AttributeReference;
                                        if (att.Tag == ad.Tag)
                                        {
                                            att.SetAttributeFromBlock(m2);
                                            att.Position = ad.Position.TransformBy(m);
                                            if (ad.Justify != AttachmentPoint.BaseLeft)
                                                att.AlignmentPoint = ad.AlignmentPoint.TransformBy(m);
                                            if (att.IsMTextAttribute)
                                                att.UpdateMTextAttribute();
                                        }
                                    }
                                }
                            }
                        }
                    }
                    acTrans.Commit();
                    acTrans.Dispose();
                }
            }
        }
--- End code ---

Navigation

[0] Message Index

[*] Previous page

Go to full version