AutoCAD .NET:使用 DrawJig 移动多个图元,任意数量/种类

AutoCAD .NET:使用 DrawJig 移动多个图元,任意数量/种类


AutoCAD .NET API 提供了两个具体的Jig类,供我们在不同情况下Jig不同的事物,即 EntityJig 和 DrawJig。EntityJig 用于Jig特定图元,顾名思义,DrawJig 用于夹具任何具有要绘制的图形,可以是单个图元、一组图元或 AutoCAD 中本机不可用的内容。

在这篇文章中,让我们看看如何使用 DrawJig 移动单个或多个实体,这些实体可以是任意数量的,并且可以在单个组中具有任何类型。

这是整个 DrawJig 实现类以及其中的测试命令。

#region Namespaces

using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.Drawing;
using System.IO;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows;

using Autodesk.AutoCAD.GraphicsSystem;
using Autodesk.AutoCAD.GraphicsInterface;

using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.ComponentModel;
using Autodesk.AutoCAD.Customization;
using Autodesk.AutoCAD.DataExtraction;
using Autodesk.AutoCAD.Diagnostics;
using Autodesk.AutoCAD.Internal;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.MacroRecorder;
using Autodesk.AutoCAD.Publishing;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Ribbon;

using MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using MgdAcDocument = Autodesk.AutoCAD.ApplicationServices.Document;
using AcWindowsNS = Autodesk.AutoCAD.Windows;

#endregion

namespace AcadNetAddinWizard_Namespace
{
    public class DrawJigger7 : DrawJig
    {
        #region Fields

        private Point3d mBase;
        private Point3d mLocation;
        List<Entity> mEntities;

        #endregion

        #region Constructors

        public DrawJigger7(Point3d basePt)
        {
            mBase = basePt.TransformBy(UCS);
            mEntities = new List<Entity>();
        }

        #endregion

        #region Properties

        public Point3d Base
        {
            get { return mLocation; }
            set { mLocation = value; }
        }

        public Point3d Location
        {
            get { return mLocation; }
            set { mLocation = value; }
        }

        public Matrix3d UCS
        {
            get
            {
                return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
            }
        }

        #endregion

        #region Methods

        public void AddEntity(Entity ent)
        {
            mEntities.Add(ent);
        }

        public void TransformEntities()
        {
            Matrix3d mat = Matrix3d.Displacement(mBase.GetVectorTo(mLocation));

            foreach (Entity ent in mEntities)
            {
                ent.TransformBy(mat);
            }
        }

        #endregion

        #region Overrides

        protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
        {
            Matrix3d mat = Matrix3d.Displacement(mBase.GetVectorTo(mLocation));

            WorldGeometry geo = draw.Geometry;
            if (geo != null)
            {
                geo.PushModelTransform(mat);

                foreach (Entity ent in mEntities)
                {
                    geo.Draw(ent);
                }

                geo.PopModelTransform();
            }

            return true;
        }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nNew location:");
            prOptions1.UseBasePoint = false;

            PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
            if (prResult1.Status == PromptStatus.Cancel || prResult1.Status == PromptStatus.Error)
                return SamplerStatus.Cancel;

            if (!mLocation.IsEqualTo(prResult1.Value, new Tolerance(10e-10, 10e-10)))
            {
                mLocation = prResult1.Value;
                return SamplerStatus.OK;
            }
            else
                return SamplerStatus.NoChange;
        }

        #endregion

        #region Commands

        public static DrawJigger7 jigger;
        [CommandMethod("TestDrawJigger7")]
        public static void TestDrawJigger7_Method()
        {
            try
            {
                Database db = HostApplicationServices.WorkingDatabase;
                Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;

                PromptSelectionResult selRes = ed.GetSelection();
                if (selRes.Status != PromptStatus.OK) return;

                PromptPointOptions prOpt = new PromptPointOptions("\nBase point:");
                PromptPointResult pr = ed.GetPoint(prOpt);
                if (pr.Status != PromptStatus.OK) return;

                jigger = new DrawJigger7(pr.Value);
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    foreach (ObjectId id in selRes.Value.GetObjectIds())
                    {
                        Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                        jigger.AddEntity(ent);
                    }

                    PromptResult jigRes = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.Drag(jigger);
                    if (jigRes.Status == PromptStatus.OK)
                    {
                        jigger.TransformEntities();
                        tr.Commit();
                    }
                    else
                        tr.Abort();
                }
            }
            catch (System.Exception ex)
            {
                MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
            }
        }

        #endregion

    }
}

加载测试部件并运行测试命令后,我们将看到此处的Jigger的行为与本机 AutoCAD MOVE 命令几乎完全相同。

因此,使用如此简洁的代码,可以进一步压缩,例如删除那些未使用的命名空间,我们已经重现了看起来相当复杂的AutoCAD MOVE命令的确切行为。

有关代码的一些要点可能更有帮助。

• DrawJig 的关键是它的 WorldDraw()方法。它提供了绘制任何图形的功能。
• WorldGeometry 实例提供了各种方法来绘制我们想要的任何内容。
• 它还为我们提供了一种结构化的简单方法来处理任何矩阵变换,就像我们在这里对位移矩阵所做的那样。
• Sampler()是另一种核心方法,用于收集用户输入,例如大小写中的光标位置。
• 虽然Sampler()看起来与 EntityJig 中的完全相同,但它有根本的区别。在EntityJig中,除非使用输入控件明确指定,否则收集的点位于UCS中;但在 DrawJig 中,点坐标位于 WCS 中。
• 但是Editor.GetPoint()方法返回 UCS 中的基点。这就解释了为什么我们必须将基点转换为 WCS 以使事情保持一致。
• WorldGeometry 可以绘制从 Drawable 接口派生的任何内容,然后绘制 Entity 类,因此我们可以在新位置重新绘制实体。
• PushModelTransform 和 PopModelTransform 机制让我们的生活更轻松。我们不必像之前在 EntityJig 中那样将处理的新位置缓存为新基点来移动单个实体。
• 通常,我们不会将实体指针传递给 DrawJig,因为它不仅应该关心特定实体的图形,而且在这里,我们将实体指针列表传递到 DrawJig 中,以便同时更新它们的图形。
• WorldGeometry.Draw 非常友好,我们可以用它来逐个绘制关注的实体。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值