AutoCAD users who work in civil engineering/land development/surveying very often want a easy way to know the area value of a enclosed area, be it by a single closed polyline, or by a boundary formed by multiple entities. AutoCAD provides "AREA" command for user to pick points to get the area value of the boundary formed by the picked points. If the area is formed by a closed polyline, or a circle, user can also use "LIST" command to see the area value.
Readers who come to my blogs often probably know that I am a fan of using Transient graphics to help AutoCAD user with visual hints. Here is another example of using Transient graphics in conjunction with Editor.PointMonitor event handle to allow user to move mouse cursor freely to get visual feedback of an enclosed area.
The code is quite simple and straightforward, so, no need for the extra explanation.
This is the class that handles Editor.PointMinitor event and trace the boundary of possible area:
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.GraphicsInterface; using CadDb = Autodesk.AutoCAD.DatabaseServices; using System; namespace AreaPrompting { public class AreaDetector : IDisposable { private readonly Document _dwg; private readonly Editor _ed; private readonly TransientManager _tsManager = TransientManager.CurrentTransientManager; private MPolygon _mPoly = null; public AreaDetector() { _dwg = Application.DocumentManager.MdiActiveDocument; _ed = _dwg.Editor; } public void Dispose() { ClearTransient(); } public void PromptArea() { try { _ed.PointMonitor += Editor_PointMonitor; _ed.GetPoint("\nMove mouse cursor into an enclosed area:"); } finally { _ed.PointMonitor-= Editor_PointMonitor; ClearTransient(); } } #region private methods private void Editor_PointMonitor(object sender, PointMonitorEventArgs e) { ClearTransient(); var polygon = DetectArea(e.Context.RawPoint); if (polygon!=null) { _mPoly = polygon; _tsManager.AddTransient( _mPoly, TransientDrawingMode.Highlight, 128, new IntegerCollection()); e.AppendToolTipText($"AREA={_mPoly.Area}"); } } private void ClearTransient() { if (_mPoly!=null) { _tsManager.EraseTransient( _mPoly, new Autodesk.AutoCAD.Geometry.IntegerCollection()); _mPoly.Dispose(); } } private MPolygon DetectArea(Point3d point) { MPolygon polygon = null; var boundaryEnts = _ed.TraceBoundary(point, false); if(boundaryEnts!=null && boundaryEnts.Count>0) { var pline = boundaryEnts[0] as CadDb.Polyline; if (pline!=null) { polygon = new MPolygon(); polygon.ColorIndex = 9; polygon.SetPattern(HatchPatternType.PreDefined, "SOLID"); polygon.AppendLoopFromBoundary( pline, false, Tolerance.Global.EqualVector); } } return polygon; } #endregion } }
This is the CommandMethod to execute the above code:
using Autodesk.AutoCAD.Runtime; using CadApp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(AreaPrompting.MyCommands))] namespace AreaPrompting { public class MyCommands { [CommandMethod("GetArea")] public static void RunCommand() { var dwg = CadApp.DocumentManager.MdiActiveDocument; var ed = dwg.Editor; using (var detector = new AreaDetector()) { detector.PromptArea(); } } } }
See the video clip showing the code effect:
One may notice one annoying thing: when Editor.TraceBoundary() method is called (many times while mouse moves), AutoCAD shows useless/meaningless messages at command line. I guess the message was used when Autodesk's engineers implemented and tested the TraceBoundary() method, and they forgot to clean them out after they had their job done!
1 comment:
Nice post! I appreciate the insights and information you've shared about AutoCad. Keep up the good work and continue sharing such valuable content!
Post a Comment