- UID
- 14
- 积分
- 8264
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-4
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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.
- // required ObjectARX methods, called with P/Invoke
- // this is valid for R19 release (AutoCAD 2013)
- [DllImport("acdb19.dll",
- CharSet = CharSet.Unicode,
- CallingConvention = CallingConvention.Cdecl,
- EntryPoint = "?addFilter@AcDbIndexFilterManager@@YA?AW4ErrorStatus@Acad@@PAVAcDbBlockReference@@PAVAcDbFilter@@@Z")]
- private static extern int addFilter32(IntPtr pBlkRef, IntPtr pFilter);
- [DllImport("acdb19.dll",
- CharSet = CharSet.Unicode,
- CallingConvention = CallingConvention.Cdecl,
- EntryPoint = "?addFilter@AcDbIndexFilterManager@@YA?AW4ErrorStatus@Acad@@PEAVAcDbBlockReference@@PEAVAcDbFilter@@@Z")]
- private static extern int addFilter64(IntPtr pBlkRef, IntPtr pFilter);
-
- /// <summary>
- /// Check if the OS is 32 or 64 bit
- /// </summary>
- static public bool is64bits
- {
- get { return (Application.GetSystemVariable
- ("PLATFORM").ToString().IndexOf("64") > 0); }
- }
- //Create a spatial filter on the selected block reference
- //create rectangular cliping area by providing the 2 corners
- [CommandMethod("NetClip")]
- public void NetClip()
- {
- // required variables
- Document doc = Application.DocumentManager.
- MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- // select a block reference
- PromptEntityOptions peo = new PromptEntityOptions(
- "\nSelect a block reference: ");
- peo.SetRejectMessage("\nMust be a block reference...");
- peo.AddAllowedClass(typeof(BlockReference), true);
- PromptEntityResult per = ed.GetEntity(peo);
- if (per.Status != PromptStatus.OK) return;
- PromptPointOptions ppo = new PromptPointOptions(
- "\nSelect rect clip 1st corner: ");
- PromptPointResult ppr1 = ed.GetPoint(ppo);
- if (ppr1.Status != PromptStatus.OK)
- return;
- PromptCornerOptions pco = new PromptCornerOptions(
- "\nSelect rect clip 2nd corner: ", ppr1.Value);
- pco.UseDashedLine = true;
- PromptPointResult ppr2 = ed.GetCorner(pco);
- if (ppr2.Status != PromptStatus.OK)
- return;
- using (Transaction trans = db.TransactionManager
- .StartTransaction())
- {
- BlockReference bref = trans.GetObject(per.ObjectId,
- OpenMode.ForWrite) as BlockReference;
- //Define clip rectangle
- Point3d pt3d1 = ppr1.Value.TransformBy(
- bref.BlockTransform.Inverse());
- Point3d pt3d2 = ppr2.Value.TransformBy(
- bref.BlockTransform.Inverse());
- Point2dCollection boundary =
- GetClipRectangle(pt3d1, pt3d2);
- double elevation = 0.0;
- SpatialFilter filter = new SpatialFilter();
- filter.Definition = new
- SpatialFilterDefinition(boundary,
- bref.Normal, elevation, 1000, -1000, true);
- //P/Invoke AcDbIndexFilterManager::addFilter
- int es;
- if (is64bits)
- es = addFilter64(bref.UnmanagedObject,
- filter.UnmanagedObject);
- else
- es = addFilter32(bref.UnmanagedObject,
- filter.UnmanagedObject);
- if (es == 0)
- {
- ed.WriteMessage(
- "\nSpatial filter added successfully...");
- DrawClipBoundary(boundary, bref,
- bref.Normal, elevation);
- }
- else
- {
- ed.WriteMessage(
- "\nSpatial filter failed:(...Error code:"
- + es.ToString());
- };
- // need to explicitely close the filter
- filter.Close();
- trans.Commit();
- }
- }
- // the clip rectangle needs to be provided
- // with (lower-left, upper-right) so we may
- // need to re-arrange depending on how the
- // user selected corners
- Point2dCollection GetClipRectangle(
- Point3d p1, Point3d p2)
- {
- Point2dCollection clipRect =
- new Point2dCollection();
- double minX = p1.X;
- double minY = p1.Y;
- double maxX = p2.X;
- double maxY = p2.Y;
- if (minX > p2.X)
- {
- minX = p2.X;
- maxX = p1.X;
- }
- if (minY > p2.Y)
- {
- minY = p2.Y;
- maxY = p1.Y;
- }
- clipRect.Add(new Point2d(minX, minY));
- clipRect.Add(new Point2d(maxX, maxY));
- return clipRect;
- }
- //Just an optional method in order to visualize the clip area
- void DrawClipBoundary(
- Point2dCollection boundary,
- BlockReference bref,
- Vector3d Normal,
- double elevation)
- {
- Database db = HostApplicationServices.
- WorkingDatabase;
- using (Transaction trans =
- db.TransactionManager.StartTransaction())
- {
- BlockTable bT = trans.GetObject(
- db.BlockTableId, OpenMode.ForRead)
- as BlockTable;
- BlockTableRecord bTR = trans.GetObject(
- bT[BlockTableRecord.ModelSpace],
- OpenMode.ForWrite)
- as BlockTableRecord;
- Polyline pline = new Polyline();
- pline.Closed = true;
- pline.Thickness = 0.0;
- pline.SetPropertiesFrom(bref);
- pline.Normal = Normal;
- pline.Elevation = elevation;
- pline.ColorIndex = 1;
- pline.AddVertexAt(0,
- new Point2d(
- boundary[0].X, boundary[0].Y), 0, 0, 0);
- pline.AddVertexAt(1,
- new Point2d(
- boundary[0].X, boundary[1].Y), 0, 0, 0);
- pline.AddVertexAt(2,
- new Point2d(
- boundary[1].X, boundary[1].Y), 0, 0, 0);
- pline.AddVertexAt(3,
- new Point2d(
- boundary[1].X, boundary[0].Y), 0, 0, 0);
- pline.TransformBy(bref.BlockTransform);
- bTR.AppendEntity(pline);
- trans.AddNewlyCreatedDBObject(pline, true);
- trans.Commit();
- }
- }
|
|