Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.
Can anyone tell me how I can recreate the function that focuses on an object in AutoCAD through the .NET API?
I'm trying but I only managed to do it for 2D, for 3D it gets lost and focuses on an empty place.
My code that I was testing:
public static void FocusOnObject(ObjectId objId)
{
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
if (objId == ObjectId.Null)
{
ed.WriteMessage($"\nItem inválido!\n");
return;
}
using (Transaction tr = doc.TransactionManager.StartTransaction())
{
try
{
Entity entity = tr.GetObject(objId, OpenMode.ForRead) as Entity;
if (entity != null)
{
ed.SetImpliedSelection(new ObjectId[] { objId });
if (entity.Bounds.HasValue)
{
Extents3d extents = entity.GeometricExtents;
using (ViewTableRecord view = ed.GetCurrentView())
{
Point3d minPt = extents.MinPoint;
Point3d maxPt = extents.MaxPoint;
Point3d center = new Point3d(
(minPt.X + maxPt.X) / 2.0,
(minPt.Y + maxPt.Y) / 2.0,
(minPt.Z + maxPt.Z) / 2.0);
double margin = 0.1; // 10% of margin
double width = (maxPt.X - minPt.X) * (1 + margin);
double height = (maxPt.Y - minPt.Y) * (1 + margin);
double depth = (maxPt.Z - minPt.Z) * (1 + margin);
view.Target = center;
view.Height = height;
view.Width = width;
view.ViewDirection = new Vector3d(view.ViewDirection.X, view.ViewDirection.Y, 1.0);
if (depth > height && depth > width)
{
view.LensLength = depth;
}
ed.SetCurrentView(view);
}
}
else
{
ed.WriteMessage("\nA entidade não possui extents válidos.");
}
}
tr.Commit();
}
catch (System.Exception ex)
{
ed.WriteMessage($"Erro ao focar no objeto: {ex.Message}");
}
}
}
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
You have to transform the extents of the entity from World coordinates (WCS) to the current view display coordinates (DCS) before usint it to define the view center and size.
Here's an example from your code integrating some code from this library ( specifically AbstractViewTableRecordExtension and EditorExtension ).
public static void FocusOnObject(ObjectId objId)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
if (objId.IsNull)
{
ed.WriteMessage($"\nItem inválido!\n");
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
Entity entity = tr.GetObject(objId, OpenMode.ForRead) as Entity;
if (entity != null)
{
if (entity.Bounds.HasValue)
{
Extents3d extents = entity.GeometricExtents;
using (ViewTableRecord view = ed.GetCurrentView())
{
Matrix3d worldToEye =
Matrix3d.WorldToPlane(view.ViewDirection) *
Matrix3d.Displacement(view.Target.GetAsVector().Negate()) *
Matrix3d.Rotation(view.ViewTwist, view.ViewDirection, view.Target);
extents.TransformBy(worldToEye);
view.Width = extents.MaxPoint.X - extents.MinPoint.X;
view.Height = extents.MaxPoint.Y - extents.MinPoint.Y;
view.CenterPoint = new Point2d(
(extents.MaxPoint.X + extents.MinPoint.X) / 2.0,
(extents.MaxPoint.Y + extents.MinPoint.Y) / 2.0);
ed.SetCurrentView(view);
}
}
else
{
ed.WriteMessage("\nA entidade não possui extents válidos.");
}
}
tr.Commit();
}
catch (System.Exception ex)
{
ed.WriteMessage($"Erro ao focar no objeto: {ex.Message}");
}
}
}
Referencing Gile.AutoCAD.R20.Extension.dll (or Gile.AutoCAD.R25.Extension.dll for AutoCAD 2025), you could simply write:
public static void FocusOnObject(ObjectId objId)
{
var ed = Active.Editor;
if (objId.IsNull)
{
ed.WriteMessage($"\nItem inválido!\n");
return;
}
using (var tr = Active.Database.TransactionManager.StartTransaction())
{
try
{
if (objId.TryGetObject(tr, out Entity entity))
{
if (entity.Bounds.HasValue)
{
ed.Zoom(entity.GeometricExtents);
}
else
{
ed.WriteMessage("\nA entidade não possui extents válidos.");
}
}
tr.Commit();
}
catch (System.Exception ex)
{
ed.WriteMessage($"Erro ao focar no objeto: {ex.Message}");
}
}
}
Can't find what you're looking for? Ask the community or share your knowledge.