Author Topic: Drag (attributed) block reference  (Read 1210 times)

0 Members and 1 Guest are viewing this topic.

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Drag (attributed) block reference
« on: January 26, 2013, 10:44:15 PM »
Dragging and rotating an (attributed) block.

BlockJig is to be used to drag (and possibly rotate) a simple block.
While dragging the block, it's possible to dynamically rotate the block by pressing Ctrl.
A click terminate the process keeping the current position and rotation for the block

BlockAttribJig inherits from BlockJig and handles the block attribute references.
In the constructor, each attribute definition informations (position, alignement and rotation) is stored in a structure.
The overrided Update() method sets the attributes geometry according to the attribute definition informations and the block reference position and rotation.

Code: (csharp) [Select]
        class BlockJig : EntityJig
        {
            protected BlockReference _br;
            protected Point3d _pos;
            protected double _rot, _ucsRot;

            public BlockJig(BlockReference br)
                : base(br)
            {
                _br = br;
                _pos = _br.Position;
                Editor ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
                CoordinateSystem3d ucs = ed.CurrentUserCoordinateSystem.CoordinateSystem3d;
                Matrix3d ocsMat = Matrix3d.WorldToPlane(new Plane(Point3d.Origin, ucs.Zaxis));
                _ucsRot = Vector3d.XAxis.GetAngleTo(ucs.Xaxis.TransformBy(ocsMat), ucs.Zaxis);
                _rot = _br.Rotation - _ucsRot;
            }

            protected override SamplerStatus Sampler(JigPrompts prompts)
            {
                System.Windows.Forms.Keys mods = System.Windows.Forms.Control.ModifierKeys;
                if ((mods & System.Windows.Forms.Keys.Control) > 0)
                {
                    JigPromptAngleOptions jpao =
                        new JigPromptAngleOptions("\nSpecify the rotation: ");
                    jpao.UseBasePoint = true;
                    jpao.BasePoint = _br.Position;
                    jpao.Cursor = CursorType.RubberBand;
                    jpao.UserInputControls = (
                        UserInputControls.Accept3dCoordinates |
                        UserInputControls.UseBasePointElevation);
                    PromptDoubleResult pdr = prompts.AcquireAngle(jpao);

                    if (_rot == pdr.Value)
                    {
                        return SamplerStatus.NoChange;
                    }
                    else
                    {
                        _rot = pdr.Value;
                        return SamplerStatus.OK;
                    }
                }
                else
                {
                    JigPromptPointOptions jppo =
                        new JigPromptPointOptions("\nSpecify insertion point (or press Ctrl for rotation): ");
                    jppo.UserInputControls =
                      (UserInputControls.Accept3dCoordinates | UserInputControls.NullResponseAccepted);
                    PromptPointResult ppr = prompts.AcquirePoint(jppo);
                    if (_pos.DistanceTo(ppr.Value) < Tolerance.Global.EqualPoint)
                    {
                        return SamplerStatus.NoChange;
                    }
                    else
                    {
                        _pos = ppr.Value;
                    }
                    return SamplerStatus.OK;
                }
            }

            protected override bool Update()
            {
                _br.Position = _pos;
                _br.Rotation = _rot +_ucsRot;
                return true;
            }
        }

        class BlockAttribJig : BlockJig
        {
            struct TextInfo
            {
                public Point3d Position;
                public Point3d Alignment;
                public double Rotation;
                public bool IsAligned;
            }

            private Dictionary<string, TextInfo> _attInfos;

            public BlockAttribJig(BlockReference br)
                : base(br)
            {
                _attInfos = new Dictionary<string, TextInfo>();
                BlockTableRecord btr = (BlockTableRecord)br.BlockTableRecord.GetObject(OpenMode.ForRead);
                foreach (ObjectId id in btr)
                {
                    if (id.ObjectClass.Name == "AcDbAttributeDefinition")
                    {
                        AttributeDefinition attDef = (AttributeDefinition)id.GetObject(OpenMode.ForRead);
                        TextInfo ti = new TextInfo()
                        {
                            Position = attDef.Position,
                            Alignment = attDef.AlignmentPoint,
                            IsAligned = attDef.Justify != AttachmentPoint.BaseLeft,
                            Rotation = attDef.Rotation
                        };
                        _attInfos.Add(attDef.Tag.ToUpper(), ti);
                    }
                }
            }

            protected override bool Update()
            {
                base.Update();
                foreach (ObjectId id in _br.AttributeCollection)
                {
                    AttributeReference att = (AttributeReference)id.GetObject(OpenMode.ForWrite);
                    att.Rotation = _br.Rotation;
                    string tag = att.Tag.ToUpper();
                    if (_attInfos.ContainsKey(tag))
                    {
                        TextInfo ti = _attInfos[tag];
                        att.Position = ti.Position.TransformBy(_br.BlockTransform);
                        if (ti.IsAligned)
                        {
                            att.AlignmentPoint =
                                ti.Alignment.TransformBy(_br.BlockTransform);
                            att.AdjustAlignment(_br.Database);
                        }
                        if (att.IsMTextAttribute)
                        {
                            att.UpdateMTextAttribute();
                        }
                        att.Rotation = ti.Rotation + _br.Rotation;
                    }
                }
                return true;
            }
        }

A little using example to insert a block

Code: (csharp) [Select]
        [CommandMethod("TEST")]
        public void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptResult pr = ed.GetString("\nBlock name: ");
            if (pr.Status != PromptStatus.OK) return;
            string blockName = pr.StringResult;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(blockName))
                {
                    ed.WriteMessage("\nNone block '{0}' in the document block table.", blockName);
                    return;
                }
                BlockTableRecord curSpace =
                    (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                // Add the block reference to Database first
                BlockReference br = new BlockReference(Point3d.Origin, bt[blockName]);
                br.TransformBy(ed.CurrentUserCoordinateSystem);
                curSpace.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);

                // Get the block definition
                BlockTableRecord btr =
                    (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead);
                BlockJig jig;
                if (btr.HasAttributeDefinitions)
                {
                    // Add attribute references to the block reference
                    foreach (ObjectId id in btr)
                    {
                        if (id.ObjectClass.Name == "AcDbAttributeDefinition")
                        {
                            AttributeDefinition attDef =
                                (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
                            AttributeReference attRef = new AttributeReference();
                            attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                            ObjectId attId = br.AttributeCollection.AppendAttribute(attRef);
                            tr.AddNewlyCreatedDBObject(attRef, true);
                        }
                    }
                    // Create a BlockAttribJig instance
                    jig = new BlockAttribJig(br);
                }
                else
                {
                    // Create a BlockJig instance
                    jig = new BlockJig(br);
                }
                // Drag the block reference
                pr = ed.Drag(jig);
                if (pr.Status != PromptStatus.OK) br.Erase();
                tr.Commit();
            }
        }
« Last Edit: January 27, 2013, 07:40:42 PM by (gile) »