/* ObjSearch
* Commands.cs
* © Andrey Bushman, 2016
*
* Searching the AutoCAD database entities through their
* ObjectId values.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
[assembly: CommandClass(typeof(Bushman.AutoCAD
.DatabaseServices.ObjSearch.Commands))]
namespace Bushman.AutoCAD.DatabaseServices.ObjSearch
{
public sealed class Commands
{
const string cmd_group = "bushman";
/// <summary>
/// Find and zoom the Entity item by its ObjectId value
/// </summary>
[CommandMethod(cmd_group, "FindEntity", CommandFlags
.Modal)]
public void FindEntity()
{
Document doc = cad.DocumentManager
.MdiActiveDocument;
if (doc == null) return;
Editor ed = doc.Editor;
Database db = doc.Database;
using (doc.LockDocument())
{
/* just in case... */
db.UpdateExt(true);
PromptResult pr = ed.GetString(
"\nEnter ObjectId: ");
if (pr.Status != PromptStatus.OK) return;
// Convert hexadecimal string to 64-bit integer
long ln = Convert.ToInt64(pr.StringResult);
// ObjectId id = StaticMethods.GetEntityIds(db,
// (n) => n.OldIdPtr.ToInt64() == ln)
// .FirstOrDefault();
ObjectId id = new ObjectId(new IntPtr(ln));
bool isPaperSpace = false;
Extents3d ext;
using (Transaction tr = db.TransactionManager
.StartTransaction())
{
Entity ent = (Entity)tr.GetObject(id,
OpenMode.ForRead);
ext = ent.GeometricExtents;
ext.TransformBy(ed
.CurrentUserCoordinateSystem.Inverse())
;
double x = (ext.MaxPoint.X - ext.MinPoint.X
) / 2.0 + ext.MinPoint.X;
double y = (ext.MaxPoint.Y - ext.MinPoint.Y
) / 2.0 + ext.MinPoint.Y;
double z = (ext.MaxPoint.Z - ext.MinPoint.Z
) / 2.0 + ext.MinPoint.Z;
Point3d point = new Point3d(x, y, z);
ed.WriteMessage("Entity type: {0}\n"
, ent.GetType().ToString());
ed.WriteMessage("Entity coordinates: {0}\n"
, point.ToString());
BlockTableRecord btr = tr.GetObject(
ent.BlockId, OpenMode.ForRead) as
BlockTableRecord;
if (btr.IsLayout)
{
Layout layout = tr.GetObject(btr
.LayoutId, OpenMode.ForRead) as
Layout;
if (LayoutManager.Current.CurrentLayout
!= layout.LayoutName)
{
LayoutManager.Current.CurrentLayout
= layout.LayoutName;
}
ed.WriteMessage("The entity is " +
"located on the '{0}' layout.\n\n",
layout.LayoutName);
isPaperSpace = true;
if (!db.TileMode)
{
/* Main paper space area Viewport
* ObjectId.
*
* # Note: First ObjectId from
* GetViewports() is the main paper
* space area Viewport ObjectId.*/
ObjectId mainPSpaceVportId = layout
.GetViewports()[0];
/* Create Extents3d based on
* BlockTableRecord entities.
*
* # Note: Exclude main paper space
* viewport ObjectId. */
Extents3d extents = new Extents3d()
;
foreach (ObjectId _id in btr)
{
if (_id != mainPSpaceVportId)
{
Entity _ent = tr.GetObject(
_id, OpenMode.ForRead)
as Entity;
if (_ent != null)
{
try
{
/* EXCEPTION:
* Here I get the
* 'eNullExtents'
* errors for
* 'BlockReference'
* instances. */
extents.AddExtents(
_ent
.GeometricExtents
);
}
catch (System.Exception
ex)
{
ed.WriteMessage(
"{0} item. " +
"Error: {1}\n",
_ent.GetType()
.ToString(),
ex.Message);
}
}
}
}
/* Create Extents3d based on paper
* space layout limits. */
Extents3d limits = new Extents3d(
new Point3d(layout.Limits
.MinPoint.X, layout.Limits
.MinPoint.Y, 0),
new Point3d(layout.Limits
.MaxPoint.X, layout
.Limits.MaxPoint.Y, 0)
);
extents.AddExtents(limits);
// Update Pextmin and Pextmax.
db.Pextmin = extents.MinPoint;
db.Pextmax = extents.MaxPoint;
}
}
else if (btr.IsAnonymous)
{
ed.WriteMessage("The entity is located"
+ " in the '{0}' anonymous block.\n\n",
btr.Name);
}
else if (btr.IsAProxy)
{
ed.WriteMessage("The entity is located"
+ " in the '{0}' proxy block.\n\n",
btr.Name);
}
else if (btr.IsDynamicBlock)
{
ed.WriteMessage("The entity is located"
+ " in the '{0}' dynamic block.\n\n",
btr.Name);
}
tr.Commit();
}
PrintExtends(db.Extmin, db.Extmax, db.Pextmin,
db.Pextmax);
try
{
/* EXCEPTION: Here I get the
* 'eNullObjectPointer' error.
*
* I looked these resources also:
*
* http://adndevblog.typepad.com/autocad/2012/08/incorrect-extmin-extmax-values-for-a-drawing.html
*
* http://forums.autodesk.com/t5/net/drawing-extents-in-paperspace/m-p/3178638#M25435
*
* but they didn't help me...
*/
ZoomWinSpace(ed, ext.MinPoint, ext.MaxPoint, isPaperSpace);
}
catch (System.Exception ex)
{
ed.WriteMessage("{0}\n", ex.Message
);
}
}
}
private void PrintExtends(Point3d extmin, Point3d
extmax, Point3d pextmin, Point3d pextmax)
{
Document doc = cad.DocumentManager
.MdiActiveDocument;
if (doc == null) return;
Editor ed = cad.DocumentManager.MdiActiveDocument
.Editor;
ed.WriteMessage("\nEXTMIN: {0}\n", extmin);
ed.WriteMessage("EXTMAX: {0}\n\n", extmax);
ed.WriteMessage("PEXTMIN: {0}\n", pextmin);
ed.WriteMessage("PEXTMAX: {0}\n\n", pextmax);
}
private static void ZoomWinSpace(Editor ed, Point3d min,
Point3d max, bool isPaperSpace)
{
Point2d min2d = new Point2d(min.X, min.Y);
Point2d max2d = new Point2d(max.X, max.Y);
ViewTableRecord view = new ViewTableRecord();
view.CenterPoint = min2d + ((max2d - min2d) / 2.0);
view.Height = max2d.Y - min2d.Y;
view.Width = max2d.X - min2d.X;
view.IsPaperspaceView = isPaperSpace; // !!!
ed.SetCurrentView(view);
}
}
}