- UID
- 658062
- 积分
- 2147
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2008-10-22
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 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.
As soon as additional geometry was created in the drawing, however, the text did get displayed as expected.
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.
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:
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.Runtime;
- using AcGi = Autodesk.AutoCAD.GraphicsInterface;
-
- [assembly: ExtensionApplication(
- typeof(OsnapApp.CustomOSnapApp))
- ]
-
- namespace OsnapApp
- {
- // Register and unregister custom osnap
-
- public class CustomOSnapApp : IExtensionApplication
- {
- private QuarterOsnapInfo _info =
- new QuarterOsnapInfo();
- private QuarterGlyph _glyph =
- new QuarterGlyph();
- private CustomObjectSnapMode _mode;
-
- public void Initialize()
- {
- // Register custom osnap on initialize
-
- _mode =
- new CustomObjectSnapMode(
- "Quarter",
- "Quarter",
- "Quarter of length",
- _glyph
- );
-
- // Which kind of entity will use the osnap
-
- _mode.ApplyToEntityType(
- RXObject.GetClass(typeof(Polyline)),
- new AddObjectSnapInfo(_info.SnapInfoPolyline)
- );
- _mode.ApplyToEntityType(
- RXObject.GetClass(typeof(Curve)),
- new AddObjectSnapInfo(_info.SnapInfoCurve)
- );
- _mode.ApplyToEntityType(
- RXObject.GetClass(typeof(Entity)),
- new AddObjectSnapInfo(_info.SnapInfoEntity)
- );
-
- // Activate the osnap
-
- CustomObjectSnapMode.Activate("_Quarter");
- }
-
- // Unregister custom osnap on terminate
-
- public void Terminate()
- {
- CustomObjectSnapMode.Deactivate("_Quarter");
- }
- }
-
- // Create new quarter object snap
-
- public class QuarterGlyph : AcGi.Glyph
- {
- private Point3d _pt;
-
- public override void SetLocation(Point3d point)
- {
- _pt = point;
- }
-
- protected override void SubViewportDraw(AcGi.ViewportDraw vd)
- {
- int glyphPixels = CustomObjectSnapMode.GlyphSize;
- var glyphSize = vd.Viewport.GetNumPixelsInUnitSquare(_pt);
-
- // Calculate the size of the glyph in WCS
- // (use for text height factor)
-
- // We'll add 10% to the size, as otherwise
- // it looks a little too small
-
- double glyphHeight =
- (glyphPixels / glyphSize.Y) * 1.1;
-
- string text = "¼";
-
- // Translate the X-axis of the DCS to WCS
- // (for the text direction) and the snap
- // point itself (for the text location)
-
- var dist = -glyphHeight / 2.0;
- var offset = new Vector3d(dist, dist, 0);
- var e2w = vd.Viewport.EyeToWorldTransform;
- var dir = Vector3d.XAxis.TransformBy(e2w);
- var pt = (_pt + offset).TransformBy(e2w);
-
- // Draw the centered text representing the glyph
-
- var style = new AcGi.TextStyle();
- var fd =
- new AcGi.FontDescriptor("txt.shx", false, false, 0, 0);
- style.Font = fd;
- style.TextSize = glyphHeight;
-
- vd.Geometry.Text(
- pt,
- vd.Viewport.ViewDirection,
- dir,
- text,
- false,
- style
- );
- }
- }
-
- // OSnap info
-
- public class QuarterOsnapInfo
- {
- public void SnapInfoEntity(
- ObjectSnapContext context,
- ObjectSnapInfo result)
- {
- // Nothing here
- }
-
- public void SnapInfoCurve(
- ObjectSnapContext context,
- ObjectSnapInfo result
- )
- {
- // For any curve
-
- var cv = context.PickedObject as Curve;
- if (cv == null)
- return;
-
- double startParam = cv.StartParam;
- double endParam = cv.EndParam;
-
- // Added a check to avoid zero-length curve problems
-
- if (startParam == endParam)
- return;
-
- // Add osnap at first quarter
-
- double param =
- startParam + ((endParam - startParam) * 0.25);
- var pt = cv.GetPointAtParameter(param);
-
- result.SnapPoints.Add(pt);
-
- // Add osnap at third quarter
-
- param =
- startParam + ((endParam - startParam) * 0.75);
- pt = cv.GetPointAtParameter(param);
-
- result.SnapPoints.Add(pt);
- if (cv.Closed)
- {
- pt = cv.StartPoint;
- result.SnapPoints.Add(pt);
- }
- }
-
- public void SnapInfoPolyline(
- ObjectSnapContext context,
- ObjectSnapInfo result)
- {
- // For polylines
-
- var pl = context.PickedObject as Polyline;
- if (pl == null)
- return;
-
- // Get the overall start and end parameters
-
- double plStartParam = pl.StartParam;
- double plEndParam = pl.EndParam;
-
- // Get the local
-
- double startParam = plStartParam;
- double endParam = startParam + 1.0;
-
- while (endParam <= plEndParam)
- {
- // Calculate the snap point per vertex...
-
- // Add osnap at first quarter
-
- double param =
- startParam + ((endParam - startParam) * 0.25);
- var pt = pl.GetPointAtParameter(param);
-
- result.SnapPoints.Add(pt);
-
- // Add osnap at third quarter
-
- param =
- startParam + ((endParam - startParam) * 0.75);
- pt = pl.GetPointAtParameter(param);
-
- result.SnapPoints.Add(pt);
-
- startParam = endParam;
- endParam += 1.0;
- }
- }
- }
- }
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.
|
|