Hi
You can use these extension methods (from GeometryExtensions).
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace GeometryExtensions
{
/// <summary>
/// Provides extension methods for the Viewport type.
/// </summary>
public static class ViewportExtensions
{
/// <summary>
/// Gets the transformation matrix from the specified model space viewport Display Coordinate System (DCS)
/// to the World Coordinate System (WCS).
/// </summary>
/// <param name="vp">The instance to which this method applies.</param>
/// <returns>The DCS to WDCS transformation matrix.</returns>
public static Matrix3d DCS2WCS(this Viewport vp)
{
return
Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, vp.ViewTarget) *
Matrix3d.Displacement(vp.ViewTarget - Point3d.Origin) *
Matrix3d.PlaneToWorld(vp.ViewDirection);
}
/// <summary>
/// Gets the transformation matrix from the World Coordinate System (WCS)
/// to the specified model space viewport Display Coordinate System (DCS).
/// </summary>
/// <param name="vp">The instance to which this method applies.</param>
/// <returns>The WCS to DCS transformation matrix.</returns>
public static Matrix3d WCS2DCS(this Viewport vp)
{
return vp.DCS2WCS().Inverse();
}
/// <summary>
/// Gets the transformation matrix from the specified paper space viewport Display Coordinate System (DCS)
/// to the paper space Display Coordinate System (PSDCS).
/// </summary>
/// <param name="vp">The instance to which this method applies.</param>
/// <returns>The DCS to PSDCS transformation matrix.</returns>
public static Matrix3d DCS2PSDCS(this Viewport vp)
{
return
Matrix3d.Scaling(vp.CustomScale, vp.CenterPoint) *
Matrix3d.Displacement(vp.CenterPoint.GetAsVector()) *
Matrix3d.Displacement(new Vector3d(-vp.ViewCenter.X, -vp.ViewCenter.Y, 0.0));
}
/// <summary>
/// Gets the transformation matrix from the Paper Space Display Coordinate System (PSDCS)
/// to the specified paper space viewport Display Coordinate System (DCS).
/// </summary>
/// <param name="vp">The instance to which this method applies.</param>
/// <returns>The PSDCS to DCS transformation matrix.</returns>
public static Matrix3d PSDCS2DCS(this Viewport vp)
{
return vp.DCS2PSDCS().Inverse();
}
}
}
Here's a testing command which draws a Polyline3d in the model space figuring the selected viewport extents.
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using GeometryExtensions;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
[assembly: CommandClass(typeof(ViewportToWorldCoordinates.Commands))]
namespace ViewportToWorldCoordinates
{
public class Commands
{
[CommandMethod("Test", CommandFlags.NoTileMode)]
public void Test()
{
var doc = AcAp.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var options = new PromptSelectionOptions();
options.MessageForAdding = "\nSelect a viewport: ";
options.SelectEverythingInAperture = true;
options.SingleOnly = true;
var filter = new SelectionFilter(new[] { new TypedValue(0, "VIEWPORT") });
var selection = ed.GetSelection(options, filter);
if (selection.Status != PromptStatus.OK)
return;
using (var tr = db.TransactionManager.StartTransaction())
{
var vp = (Viewport)tr.GetObject(selection.Value[0].ObjectId, OpenMode.ForRead);
var extents = vp.GeometricExtents;
var xform = vp.DCS2WCS() * vp.PSDCS2DCS();
var vertices = new Point3dCollection();
vertices.Add(extents.MinPoint.TransformBy(xform));
vertices.Add(new Point3d(extents.MaxPoint.X, extents.MinPoint.Y, 0.0).TransformBy(xform));
vertices.Add(extents.MaxPoint.TransformBy(xform));
vertices.Add(new Point3d(extents.MinPoint.X, extents.MaxPoint.Y, 0.0).TransformBy(xform));
Polyline3d pline = new Polyline3d(Poly3dType.SimplePoly, vertices, true);
var modelSpace = (BlockTableRecord)tr.GetObject(
SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
modelSpace.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
tr.Commit();
}
}
}
}