找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1786|回复: 0

[分享] Implementing a custom AutoCAD object snap mode using .NET (redux)

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-7-30 22:04:40 来自手机 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 csharp 于 2014-7-31 07:58 编辑

http://through-the-interface.typepad.com/through_the_interface/2014/04/implementing-a-custom-autocad-object-snap-mode-using-net-redux.html

Implementing a custom AutoCAD object snap mode using .NET (redux)
I had an email from Martin Duke about this old post a couple of weeks ago. I started to update the original post but then realised that a) I couldn’t easily go that far back using Windows Live Writer and the built-in Typepad editor often messes up code in old posts when I edit them and b) there was some value in revisiting this topic again now that nearly 6 years has passed. I’ll hopefully manage to link to this updated post from the old one without things going awry.
Martin was having some trouble with text display in object snap glyphs: it worked well enough once some geometry has been drawn – even if it didn’t automatically use the colour of the other object snap glyph graphics – but it didn’t work well when a drawing has just been created or loaded. If the previously implemented object snap was used in a fresh drawing, the text didn’t get displayed.
0.jpg
As soon as additional geometry was created in the drawing, however, the text did get displayed as expected.
1.jpg
The answer, it turns out, was to use an SHX font: this allowed the transient text to be displayed properly from the start and with the colour the glyph markers should have.
2.jpg
I also took the opportunity to centre the text properly on the snap point, which is ultimately a matter of taste: I think I even moved it away from the snap point on purpose 6 years ago. ;-)
It would clearly be nice to have TrueType fonts display properly, but this is an artifact of the 2D graphics system (and is logged as an issue in our internal tracking system). The behaviour is different when using a 3D Visual Style, for whatever that’s worth.
Here’s the updated C# code that shows how this can be made to work in this way:

  1. using Autodesk.AutoCAD.DatabaseServices;

  2. using Autodesk.AutoCAD.Geometry;

  3. using Autodesk.AutoCAD.Runtime;

  4. using AcGi = Autodesk.AutoCAD.GraphicsInterface;



  5. [assembly: ExtensionApplication(

  6.   typeof(OsnapApp.CustomOSnapApp))

  7. ]



  8. namespace OsnapApp

  9. {

  10.   // Register and unregister custom osnap



  11.   public class CustomOSnapApp : IExtensionApplication

  12.   {

  13.     private QuarterOsnapInfo _info =

  14.       new QuarterOsnapInfo();

  15.     private QuarterGlyph _glyph =

  16.       new QuarterGlyph();

  17.     private CustomObjectSnapMode _mode;



  18.     public void Initialize()

  19.     {

  20.       // Register custom osnap on initialize



  21.       _mode =

  22.         new CustomObjectSnapMode(

  23.           "Quarter",

  24.           "Quarter",

  25.           "Quarter of length",

  26.           _glyph

  27.         );



  28.       // Which kind of entity will use the osnap



  29.       _mode.ApplyToEntityType(

  30.         RXObject.GetClass(typeof(Polyline)),

  31.         new AddObjectSnapInfo(_info.SnapInfoPolyline)

  32.       );

  33.       _mode.ApplyToEntityType(

  34.         RXObject.GetClass(typeof(Curve)),

  35.         new AddObjectSnapInfo(_info.SnapInfoCurve)

  36.       );

  37.       _mode.ApplyToEntityType(

  38.         RXObject.GetClass(typeof(Entity)),

  39.         new AddObjectSnapInfo(_info.SnapInfoEntity)

  40.       );



  41.       // Activate the osnap



  42.       CustomObjectSnapMode.Activate("_Quarter");

  43.     }



  44.     // Unregister custom osnap on terminate



  45.     public void Terminate()

  46.     {

  47.       CustomObjectSnapMode.Deactivate("_Quarter");

  48.     }

  49.   }



  50.   // Create new quarter object snap



  51.   public class QuarterGlyph : AcGi.Glyph

  52.   {

  53.     private Point3d _pt;



  54.     public override void SetLocation(Point3d point)

  55.     {

  56.       _pt = point;

  57.     }



  58.     protected override void SubViewportDraw(AcGi.ViewportDraw vd)

  59.     {

  60.       int glyphPixels = CustomObjectSnapMode.GlyphSize;

  61.       var glyphSize = vd.Viewport.GetNumPixelsInUnitSquare(_pt);



  62.       // Calculate the size of the glyph in WCS

  63.       //  (use for text height factor)



  64.       // We'll add 10% to the size, as otherwise

  65.       //  it looks a little too small



  66.       double glyphHeight =

  67.         (glyphPixels / glyphSize.Y) * 1.1;



  68.       string text = "¼";



  69.       // Translate the X-axis of the DCS to WCS

  70.       //  (for the text direction) and the snap

  71.       //  point itself (for the text location)



  72.       var dist = -glyphHeight / 2.0;

  73.       var offset = new Vector3d(dist, dist, 0);

  74.       var e2w = vd.Viewport.EyeToWorldTransform;

  75.       var dir = Vector3d.XAxis.TransformBy(e2w);

  76.       var pt = (_pt + offset).TransformBy(e2w);



  77.       //  Draw the centered text representing the glyph



  78.       var style = new AcGi.TextStyle();

  79.       var fd =

  80.         new AcGi.FontDescriptor("txt.shx", false, false, 0, 0);

  81.       style.Font = fd;

  82.       style.TextSize = glyphHeight;



  83.       vd.Geometry.Text(

  84.         pt,

  85.         vd.Viewport.ViewDirection,

  86.         dir,

  87.         text,

  88.         false,

  89.         style

  90.       );

  91.     }

  92.   }



  93.   // OSnap info



  94.   public class QuarterOsnapInfo

  95.   {

  96.     public void SnapInfoEntity(

  97.       ObjectSnapContext context,

  98.       ObjectSnapInfo result)

  99.     {

  100.       // Nothing here

  101.     }



  102.     public void SnapInfoCurve(

  103.       ObjectSnapContext context,

  104.       ObjectSnapInfo result

  105.     )

  106.     {

  107.       // For any curve



  108.       var cv = context.PickedObject as Curve;

  109.       if (cv == null)

  110.         return;



  111.       double startParam = cv.StartParam;

  112.       double endParam = cv.EndParam;



  113.       // Added a check to avoid zero-length curve problems



  114.       if (startParam == endParam)

  115.         return;



  116.       // Add osnap at first quarter



  117.       double param =

  118.         startParam + ((endParam - startParam) * 0.25);

  119.       var pt = cv.GetPointAtParameter(param);



  120.       result.SnapPoints.Add(pt);



  121.       // Add osnap at third quarter



  122.       param =

  123.         startParam + ((endParam - startParam) * 0.75);

  124.       pt = cv.GetPointAtParameter(param);



  125.       result.SnapPoints.Add(pt);

  126.       if (cv.Closed)

  127.       {

  128.         pt = cv.StartPoint;

  129.         result.SnapPoints.Add(pt);

  130.       }

  131.     }



  132.     public void SnapInfoPolyline(

  133.       ObjectSnapContext context,

  134.       ObjectSnapInfo result)

  135.     {

  136.       // For polylines



  137.       var pl = context.PickedObject as Polyline;

  138.       if (pl == null)

  139.         return;



  140.       // Get the overall start and end parameters



  141.       double plStartParam = pl.StartParam;

  142.       double plEndParam = pl.EndParam;



  143.       // Get the local



  144.       double startParam = plStartParam;

  145.       double endParam = startParam + 1.0;



  146.       while (endParam <= plEndParam)

  147.       {

  148.         // Calculate the snap point per vertex...



  149.         // Add osnap at first quarter



  150.         double param =

  151.           startParam + ((endParam - startParam) * 0.25);

  152.         var pt = pl.GetPointAtParameter(param);



  153.         result.SnapPoints.Add(pt);



  154.         // Add osnap at third quarter



  155.         param =

  156.           startParam + ((endParam - startParam) * 0.75);

  157.         pt = pl.GetPointAtParameter(param);



  158.         result.SnapPoints.Add(pt);



  159.         startParam = endParam;

  160.         endParam += 1.0;

  161.       }

  162.     }

  163.   }

  164. }


I’m easing back into the swing of things after my 10+ days out of the office. I’ll hopefully get the time to post on more new AutoCAD 2015 APIs during the coming few days.
Update:
Added a fix for a crash when hovering over zero-length lines.


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-22 07:06 , Processed in 0.235132 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表