By Fenton Webb
Recently I tried to find some information on how to convert a Paper Space point to a Model Space point, and was shocked to find there was no simple to use sample code!!! Perhaps I missed something obvious, nevertheless, I opted to create my own and share it with you.
The code below utilizes the acedTrans() (which has been around since the R11 ADS days) using PInvoke, it’s very simple to use when you know how.
Steps to Run and Test the Code
- Run AutoCAD and load the code below
- Switch to Paper Space, either click the Layout tab or set TILEMODE=0
- Create a VPort
- Make sure you have TILEMODE=0
- Run my “ps2ms” command and click somewhere over the MS VPort. You will see a DBPoint appear directly under your cursor, but in Model space.
- If you can’t see the DBPoint, simply set PDSIZE=10 and PDMODE=98
Hope you like it.
// convert a PS point to MS and then add a DBPoint to MS to show where we picked
// by Fenton Webb, DevTech, Autodesk, 20/Aug/2012
#if NOTACAD2013
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint="acedTrans")]
#else
[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
#endif
static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
[CommandMethod("ps2ms", CommandFlags.NoTileMode)]
static public void ps2ms()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
// pick some point in PS
PromptPointResult res = ed.GetPoint("Pick Model Space Point");
if (res.Status == PromptStatus.OK)
{
// now to make sure this works for all viewpoints
ResultBuffer psdcs = new ResultBuffer(new TypedValue(5003, 3));
ResultBuffer dcs = new ResultBuffer(new TypedValue(5003, 2));
ResultBuffer wcs = new ResultBuffer(new TypedValue(5003, 0));
double[] retPoint = new double[] { 0, 0, 0 };
// translate from the DCS of Paper Space (PSDCS) RTSHORT=3 to
// the DCS of the current model space viewport RTSHORT=2
acedTrans(res.Value.ToArray(), psdcs.UnmanagedObject, dcs.UnmanagedObject, 0, retPoint);
//translate the DCS of the current model space viewport RTSHORT=2
//to the WCS RTSHORT=0
acedTrans(retPoint, dcs.UnmanagedObject, wcs.UnmanagedObject, 0, retPoint);
ObjectId btId = ed.Document.Database.BlockTableId;
// create a new DBPoint and add it to model space to show where we picked
using (DBPoint pnt = new DBPoint(new Point3d(retPoint[0], retPoint[1], retPoint[2])))
using (BlockTable bt = btId.Open(OpenMode.ForRead) as BlockTable)
using (BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite)
as BlockTableRecord)
ms.AppendEntity(pnt);
}
}
Important Corrections
Thanks to Giles for pointing out these important corrections:
I think there’re two things wrong in the posted code:
- PSDCS and DCS are related to the active Viewport, so it’s needed to activate the Viewport (switching to ModelSpace if it’s assumed there’s only one viewport in the current layout)
- retPoint coordinates are DCS coordinates which need to be translated to WCS coordinates before passing to the DBPoint ctor.
So, I’d replace:
// Transform from PS point to MS point
ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 3));
ResultBuffer rbTo = new ResultBuffer(new TypedValue(5003, 2));
double[] retPoint = new double[] { 0, 0, 0 };
// translate from from the DCS of Paper Space (PSDCS) RTSHORT=3
// and the DCS of the current model space viewport RTSHORT=2
acedTrans(res.Value.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, retPoint);
with:
// Transform from PS point to MS point
ResultBuffer rbPSDCS = new ResultBuffer(new TypedValue(5003, 3));
ResultBuffer rbDCS = new ResultBuffer(new TypedValue(5003, 2));
ResultBuffer rbWCS = new ResultBuffer(new TypedValue(5003, 0));
double[] retPoint = new double[] { 0, 0, 0 };
ed.SwitchToModelSpace();
using (Viewport vp = (Viewport)ed.CurrentViewportObjectId.Open(OpenMode.ForRead))
{
// translate from from the DCS of Paper Space (PSDCS) RTSHORT=3
// to the DCS of the current model space viewport RTSHORT=2
acedTrans(res.Value.ToArray(), rbPSDCS.UnmanagedObject, rbDCS.UnmanagedObject, 0, retPoint);
//translate the DCS of the current model space viewport RTSHORT=2
//to the WCS RTSHORT=0
acedTrans(retPoint, rbDCS.UnmanagedObject, rbWCS.UnmanagedObject, 0, retPoint);
}
ed.SwitchToPaperSpace();
Or, rather than P/Invoking acedTrans, use some extension methods defined in the GeometryExtension library:
http://www.theswamp.org/index.php?topic=31865.msg373672#msg373672

Leave a Reply