找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1271|回复: 0

[分享] Spatial Filter (XCLIP command) command in C#

[复制链接]

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-5-26 18:29:14 | 显示全部楼层 |阅读模式

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

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

×
Spatial Filter (XCLIP command) command in C#                                                        By Augusto Goncalves
  Is it possible to programmatically create a spatial filter like XCLIP command in .Net? Unfortunately the AcDbIndexFilterManager::addFilter method is not exposed, but we can P/Invoke it. The following C# sample illustrates how to do that. Note that some version specific decorated names are used (see EntryPoint parameter), which can cause this code not to work on other versions.


  1. // required ObjectARX methods, called with P/Invoke
  2. // this is valid for R19 release (AutoCAD 2013)

  3. [DllImport("acdb19.dll",
  4.     CharSet = CharSet.Unicode,
  5.     CallingConvention = CallingConvention.Cdecl,
  6.     EntryPoint = "?addFilter@AcDbIndexFilterManager@@YA?AW4ErrorStatus@Acad@@PAVAcDbBlockReference@@PAVAcDbFilter@@@Z")]
  7. private static extern int addFilter32(IntPtr pBlkRef, IntPtr pFilter);

  8. [DllImport("acdb19.dll",
  9.     CharSet = CharSet.Unicode,
  10.     CallingConvention = CallingConvention.Cdecl,
  11.     EntryPoint = "?addFilter@AcDbIndexFilterManager@@YA?AW4ErrorStatus@Acad@@PEAVAcDbBlockReference@@PEAVAcDbFilter@@@Z")]
  12. private static extern int addFilter64(IntPtr pBlkRef, IntPtr pFilter);



  13. /// <summary>
  14. /// Check if the OS is 32 or 64 bit
  15. /// </summary>
  16. static public bool is64bits
  17. {
  18.   get { return (Application.GetSystemVariable
  19.     ("PLATFORM").ToString().IndexOf("64") > 0); }
  20. }

  21. //Create a spatial filter on the selected block reference
  22. //create rectangular cliping area by providing the 2 corners
  23. [CommandMethod("NetClip")]
  24. public void NetClip()
  25. {
  26.   // required variables
  27.   Document doc = Application.DocumentManager.
  28.     MdiActiveDocument;
  29.   Database db = doc.Database;
  30.   Editor ed = doc.Editor;
  31.   // select a block reference
  32.   PromptEntityOptions peo = new PromptEntityOptions(
  33.     "\nSelect a block reference: ");
  34.   peo.SetRejectMessage("\nMust be a block reference...");
  35.   peo.AddAllowedClass(typeof(BlockReference), true);
  36.   PromptEntityResult per = ed.GetEntity(peo);

  37.   if (per.Status != PromptStatus.OK) return;
  38.   PromptPointOptions ppo = new PromptPointOptions(
  39.     "\nSelect rect clip 1st corner: ");
  40.   PromptPointResult ppr1 = ed.GetPoint(ppo);

  41.   if (ppr1.Status != PromptStatus.OK)
  42.     return;
  43.   PromptCornerOptions pco = new PromptCornerOptions(
  44.     "\nSelect rect clip 2nd corner: ", ppr1.Value);
  45.   pco.UseDashedLine = true;
  46.   PromptPointResult ppr2 = ed.GetCorner(pco);
  47.   if (ppr2.Status != PromptStatus.OK)
  48.     return;
  49.   using (Transaction trans = db.TransactionManager
  50.     .StartTransaction())
  51.   {
  52.     BlockReference bref = trans.GetObject(per.ObjectId,
  53.       OpenMode.ForWrite) as BlockReference;

  54.    //Define clip rectangle
  55.     Point3d pt3d1 = ppr1.Value.TransformBy(
  56.       bref.BlockTransform.Inverse());
  57.     Point3d pt3d2 = ppr2.Value.TransformBy(
  58.       bref.BlockTransform.Inverse());
  59.     Point2dCollection boundary =
  60.       GetClipRectangle(pt3d1, pt3d2);
  61.     double elevation = 0.0;
  62.     SpatialFilter filter = new SpatialFilter();
  63.     filter.Definition = new
  64.       SpatialFilterDefinition(boundary,
  65.       bref.Normal, elevation, 1000, -1000, true);
  66.     //P/Invoke AcDbIndexFilterManager::addFilter
  67.     int es;
  68.     if (is64bits)
  69.       es = addFilter64(bref.UnmanagedObject,
  70.         filter.UnmanagedObject);
  71.     else
  72.       es = addFilter32(bref.UnmanagedObject,
  73.         filter.UnmanagedObject);
  74.     if (es == 0)
  75.     {
  76.       ed.WriteMessage(
  77.         "\nSpatial filter added successfully...");
  78.       DrawClipBoundary(boundary, bref,
  79.         bref.Normal, elevation);
  80.     }
  81.     else
  82.     {
  83.       ed.WriteMessage(
  84.         "\nSpatial filter failed:(...Error code:"
  85.         + es.ToString());
  86.     };

  87.     // need to explicitely close the filter
  88.     filter.Close();
  89.     trans.Commit();
  90.   }
  91. }
  92. // the clip rectangle needs to be provided
  93. // with (lower-left, upper-right) so we may
  94. // need to re-arrange depending on how the
  95. // user selected corners
  96. Point2dCollection GetClipRectangle(
  97.   Point3d p1, Point3d p2)
  98. {
  99.   Point2dCollection clipRect =
  100.     new Point2dCollection();
  101.   double minX = p1.X;
  102.   double minY = p1.Y;
  103.   double maxX = p2.X;
  104.   double maxY = p2.Y;

  105.   if (minX > p2.X)
  106.   {
  107.     minX = p2.X;
  108.     maxX = p1.X;
  109.   }

  110.   if (minY > p2.Y)
  111.   {
  112.     minY = p2.Y;
  113.     maxY = p1.Y;
  114.   }

  115.   clipRect.Add(new Point2d(minX, minY));
  116.   clipRect.Add(new Point2d(maxX, maxY));
  117.   return clipRect;
  118. }

  119. //Just an optional method in order to visualize the clip area

  120. void DrawClipBoundary(
  121.   Point2dCollection boundary,
  122.   BlockReference bref,
  123.   Vector3d Normal,
  124.   double elevation)
  125. {
  126.   Database db = HostApplicationServices.
  127.     WorkingDatabase;

  128.   using (Transaction trans =
  129.     db.TransactionManager.StartTransaction())
  130.   {
  131.     BlockTable bT = trans.GetObject(
  132.       db.BlockTableId, OpenMode.ForRead)
  133.       as BlockTable;
  134.     BlockTableRecord bTR = trans.GetObject(
  135.       bT[BlockTableRecord.ModelSpace],
  136.       OpenMode.ForWrite)
  137.         as BlockTableRecord;
  138.     Polyline pline = new Polyline();
  139.     pline.Closed = true;
  140.     pline.Thickness = 0.0;
  141.     pline.SetPropertiesFrom(bref);
  142.     pline.Normal = Normal;
  143.     pline.Elevation = elevation;
  144.     pline.ColorIndex = 1;
  145.     pline.AddVertexAt(0,
  146.       new Point2d(
  147.         boundary[0].X, boundary[0].Y), 0, 0, 0);
  148.     pline.AddVertexAt(1,
  149.       new Point2d(
  150.         boundary[0].X, boundary[1].Y), 0, 0, 0);
  151.     pline.AddVertexAt(2,
  152.       new Point2d(
  153.         boundary[1].X, boundary[1].Y), 0, 0, 0);
  154.     pline.AddVertexAt(3,
  155.       new Point2d(
  156.         boundary[1].X, boundary[0].Y), 0, 0, 0);
  157.     pline.TransformBy(bref.BlockTransform);
  158.     bTR.AppendEntity(pline);
  159.     trans.AddNewlyCreatedDBObject(pline, true);
  160.     trans.Commit();
  161.   }
  162. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-17 22:16 , Processed in 0.338428 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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