首页 > 其他分享 >AnyCAD中的Editor示例代码学习1

AnyCAD中的Editor示例代码学习1

时间:2024-05-30 15:01:46浏览次数:19  
标签:return 鼠标 示例 AnyCAD ctx Start Editor evt

  AnyCAD Rapid SDK(ARS)是一个包含三维几何造型、图形显示、数据管理等模块综合三维图形平台,支持Windows、Linux、MacOS多操作系统,支持.NET、Python、Java多开发语言,可以用于开发CAD/CAE/CAM/SIM应用程序,用于机械、建筑、电力、教育、机器人、科学计算等领域。目前计划基于Anycad编写一个三维桥梁设计功能的软件。

  Editor是一个与图形界面进行交互的机制,在AutoCAD的二次开发中,也有Editor对象,对应的是CAD界面中的命令行,也是用于与CAD进行交互。交互式操作,简单来说是输入与输出的交互,输入可以是鼠标、键盘等设备信号。输出则是内容的展示。交互式操作中,对于使用者更弱化了数据的实际数值。

  AnyCAD 中的 Editor 定义为编辑器。可以理解为,当 Editor 激活时,会对键盘、鼠标等设备输入进行响应,而响应的具体内容可以由用户自行实现。如下是一段交互式操作的代码,用于实现通过选择几何边来创建标注对象(Dimension):当选择的两条边平行时,创建尺寸标注;如果选择的边不平行,则创建的是角度标注。如下图所示:

   任何交互式对象,都要继承自Editor对象,并重载其中的一些方法,如Start()、OnMouseMove()、 Finish()等。

 1 namespace Rapid.Sketch.Plugin.Dimension
 2 {
 3 
 4     class CreateDimensionEditor : Editor
 5     {
 6       #region Constructor
 7         public CreateDimensionEditor()
 8         {
 9             SetName("CreateDimensionTrial");
10         }
11         #endregion
12     }
13 }

  构造函数中SetName(),用于表示编辑器的功能。

  然后重写该类的 Start 函数,用于表示当 Editor 被激活时,需要进行的准备工作。

        // Editor启动时执行
        public override EnumEditorCode Start(ViewContext ctx)
        {
            var tmp = ctx.GetTempContext();
            tmp.Start();
            tmp.SetPickFilter(EnumShapeFilter.Edge); // 这里只处理选择边,如果需要选择点、面可更改参数
        //TODO
return base.Start(ctx); }

  这里,在Start函数中,定义了一个临时视图上下文tmp,并启动(tmp.Start()。同时设置了交互式选择图形对象的类型,此处是允许用户选择Edge对象。在许多的场景中,

  接下来就是首先各种鼠标操作的功能,比如当鼠标移动时,需要重载OnMouseMove函数:

public override EnumEditorCode onm ouseMove(ViewContext ctx, InputEvent evt)
{
  if (evt.GetButtons() == EnumMouseButton.Zero)
  {
    switch (mEditStep)
    {
      //这里预设了几种编辑步骤(EnumerateEditStep),用于不同情境下的行为       case EnumEditStep.Target1:       case EnumEditStep.Target2:       {   
       // 吸附拓扑边并进行高亮

        var item = ctx.SnapPoint(evt.GetX(), evt.GetY());//在鼠标点处拾取对象(SnapPoint,拾取通过点的对象)
        if (!item.IsNull())
        {
          ctx.GetSelectionManager().GetHilight().Add(item, false);//将item添加到高亮集合中
        }
        else
        {
          ctx.ClearSelection();
        }
        ctx.RequestUpdate(EnumUpdateFlags.Selection);//更新选择集
        return EnumEditorCode.Processed;//返回

      }
      case EnumEditStep.Location:
      {
        // 更新尺寸标注
        if (mDimNode == null)

          {
            MessageBox.Show("创建尺寸标注失败");
            return EnumEditorCode.Failed;
          }

          //更新图元标注,UpdateDimensionNode(ctx, evt)为自定义方法,获取当前鼠标射线与给定平面的交点
          if (UpdateDimensionNode(ctx, evt))
          {
            // 更新标注成功,通知场景更新渲染
            ctx.RequestUpdate(EnumUpdateFlags.Scene);
          }
          return EnumEditorCode.Processed;

        }

    }

  }  
  return base.OnMouseMove(ctx, evt); }

  其中,InputEvent类型的变量evt表示鼠标事件,evt.GetButtons用于获取相应的鼠标按键:

 if (evt.GetButtons() == EnumMouseButton.Zero)
表示鼠标在移动的过程中没有按下任何按键,evt.GetButtons()还有其它几种取值,如下:
public enum EnumMouseButton
{
    Zero = 0,//无
    Left = 1,//左键
    Middle = 2,//中键
    Right = 4,//右键
    LeftRight = 5,//左键和右键
    LeftMiddle = 3,//左键和中键
    RightMiddle = 6,//右键和中键
    All = 7   //全部按键,左/中/右
}

  鼠标按键事件处理函数用OnMouseUp函数,鼠标按键有两个事件,分别是按下(OnMouseDown)和抬起(OnMouseUp),这里处理鼠标左键的OnMouseUp事件。

        // 鼠标点击时执行
        public override EnumEditorCode onm ouseUp(ViewContext ctx, InputEvent evt)
        {
            //判断是否为鼠标左键,只处理鼠标左键事件
            if (evt.GetButtons() == EnumMouseButton.Left)
            {
                if (mEditStep == EnumEditStep.Location)
                {
                    // 自定义Editor的Commit方法,用于提交当前编辑的结果
                    Commit(ctx);

                    // 重置,继续下一个标注创建
                    Reset(ctx);
                    return EnumEditorCode.Processed;
                }

                // 获取被高亮的拓扑边
                var hilight = ctx.GetSelectionManager().GetHilight();
                if (hilight.GetCount() > 0)
                {
                    var pickedItem = hilight.GetItem(0);
                    // 自定义方法,用于处理拓扑边的选择
                    return SetPickedEdge(ctx, pickedItem);
                }
            }

            return base.OnMouseUp(ctx, evt);
        }

  当Editor编辑结束后,需通过重载Finish方法来关闭视图上下文。

        // Editor结束时执行
        public override void Finish(ViewContext ctx)
        {
            ctx.GetTempContext().Close();
            base.Finish(ctx);
        }

  同时,在重启Editor操作时,还需要重载Reset方法,设置命令启动的状态。

        // 重置Editor状态
        public override void Reset(ViewContext ctx)
        {
           ....
        }

  当需要其它功能时候,还可以重载其它的Editor方法,或者自定义方法。

 

  上述代码来自于A你要CAD提供的官方代码,通过学习,对Editor的进行简单总结如下:

  1.Editor是一种定义交互式操作的基类,可以继承之并扩展自己的功能。此时需要对基类的方法进行重载;

  2.在继承类的构造函数中SetName(""),以描述编辑器的功能;当给编辑器添加界面时,编辑器作为ViewModel,在构造函数中定义RelayCommand,供交互界面进行调用。

  3.重载Start方法,完成编辑器启动时的准备工作。如果定义了交互式界面,就可以在Start方法中进行实例化。

  4.根据需要重载OnMouseMove、OnMouseDown、OnMouseUp等方法,实现相应的行为逻辑。

  5.当退出编辑器时,一定要通过重载的Finish方法进行视图上下文的清理。

标签:return,鼠标,示例,AnyCAD,ctx,Start,Editor,evt
From: https://www.cnblogs.com/DSBIMbyLincoln/p/18221899

相关文章

  • .NET|--WPF|--如何使用LINQPad创建一个WPF示例
    1.安装包管理器#搜索框内需要填入↓"id=Microsoft.NETCore.App""id=Microsoft.WindowsDesktop.App.Ref"2.代码voidMain(){ varapp=newSystem.Windows.Application(); varmainWindow=newSystem.Windows.Window { Title="SimpleWPFProgra......
  • golang reflect 常见示例
    reflect是golang中元编程的能力体现。需要注意的是,reflect尽量不用,有性能问题,也有避免滥用的考虑。packagemainimport( "log" "reflect")typeAstruct{ aint bstring cbool}//实验reflect的相关函数funcmain(){ typeValue() callFunc()}funcother......
  • 通栏中不定数量的图片/轮播自适应宽高的简单示例
    最近接到一个需求,在一个页面会有多个通栏,每个通栏中会有不固定数量的图片或轮播图,要求各图片/轮播要同等比例自适应宽高,写成通用代码。示意图:光是图片好说,其中有swiper就会比较麻烦。代码:<divclass="container"><divclass="zt_banner"><divclass="swiper">......
  • Python-使用OpenCV(二)_第一个示例程序
    1、创建项目2、创建代码importcv2#加载图片image=cv2.imread("C:\\Users\\Administrator\\Pictures\\Screenshots\\20240311220733.png")#显示图片cv2.imshow("Image",image)#等待任意键被敲击cv2.waitKey(0)#关闭所有窗口cv2.destroyAllWindows()3、结......
  • YAML示例:创建daemonset
    apiVersion:apps/v1kind:DaemonSetmetadata:name:test-ds-1namespace:sjlabels:k8s-app:arksec-ds-1spec:selector:matchLabels:name:arksec-ds-1template:metadata:labels:name:arksec-ds-1spec:nodeSelector:#只让它在指定hostname的节点上创建,注意,......
  • ThinkEditor电子病历编辑器:一款优秀的原生电子病历编辑器
    设计理念信译(ThinkEditor)跨平台电子病历编辑器在技术端核心设计理念是跨平台和全结构化。在产品端的核心开发思想是实现医疗电子病历编辑器的全功能和低耦合。以产品创新为导向,以服务订制为宗旨提高合作厂商产品迭代速度,提升医疗产品竞争力,实现合作与共赢创新技术手段实......
  • 使用 Marked 2 为 CotEditor 预览 markdown 内容
    CotEditor虽然各种好,但毕竟功能比较轻量,用来编辑markdown甚至没有一个预览功能。不过好在它还支持脚本拓展。我之前曾经用过coteditor_markdown_setPublic仓库里的预览脚本。不过这个脚本的预览依赖Safari实现,而且颇有一些年久失修,很多Markdown特性都不支持。最近突然想......
  • css通过子元素选择父元素的实现示例
    在CSS中,直接通过子元素选择其父元素并不直接支持,因为CSS的选择器是从上到下(从父元素到子元素)进行选择的,而不是相反。但是,你可以使用其他方法或技术来间接实现这一效果,比如使用JavaScript、jQuery或其他脚本语言,或者通过调整你的HTML结构和CSS样式来达到类似的效果。不过,我可以给......
  • 使用Python进行数据分析与可视化的简单示例
    使用Python进行数据分析与可视化的简单示例。在这个示例中,我们将使用Pandas库进行数据分析,并使用Matplotlib库进行数据可视化。首先,假设我们有一个包含销售数据的CSV文件(sales_data.csv),其中包含以下列:日期(Date)、销售额(Sales)和产品类别(Product_Category)。CSV文件的内容可能......
  • HDevelop示例程序-optical_flow.hdev
    应用范围:安全系统提示:这里可以添加系列文章的所有文章的目录coherence_enhancing_diff.hdevoptical_flow.hdevoptical_flow_bicycle.hdevoptical_flow_hydraulic_engineering.hdevxing.hdev提示:文章目录文章目录应用范围:安全系统前言一、原示例程序二、程序解......