static void viewRect() {
AcGeMatrix3d ucs2wcs(Ucs2Wcs());
AcGeMatrix3d wcs2dcs(Wcs2Dcs());
AcGeMatrix3d dcs2wcs(Dcs2Wcs());
resbuf rb;
acedGetVar(_T("VIEWCTR"), &rb);
AcGePoint3d center(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
center.transformBy(ucs2wcs).transformBy(wcs2dcs);
acedGetVar(_T("VIEWSIZE"), &rb);
double height = rb.resval.rreal;
acedGetVar(_T("SCREENSIZE"), &rb);
double width = height * rb.resval.rpoint[X] / rb.resval.rpoint[Y];
AcGePoint3d p[4] = {
AcGePoint3d((center.x - (width / 2)), (center.y - (height / 2)), 0),
AcGePoint3d((center.x - (width / 2)), (center.y + (height / 2)), 0),
AcGePoint3d((center.x + (width / 2)), (center.y + (height / 2)), 0),
AcGePoint3d((center.x + (width / 2)), (center.y - (height / 2)), 0)
};
AcGePoint3dArray pts;
for (int i = 0; i < 4; i++)
{
p[i] = p[i].transformBy(dcs2wcs);
pts.append(p[i]);
}
AcDbBlockTableRecordPointer btr(acdbSymUtil()->blockModelSpaceId(acdbCurDwg()), AcDb::kForWrite);
AcDb3dPolyline *pline = new AcDb3dPolyline(AcDb::Poly3dType::k3dSimplePoly, pts, true);
btr->appendAcDbEntity(pline);
pline->close();
}
static AcGeMatrix3d Ucs2Wcs()
{
AcGeMatrix3d mat; mat.setToIdentity();
acedGetCurrentUCS(mat);
return mat;
}
static AcGeMatrix3d Ucs2Dcs()
{
return Ucs2Wcs() * Wcs2Dcs();
}
static AcGeMatrix3d Dcs2Ucs()
{
return Ucs2Dcs().inverse();
}
static AcGeMatrix3d Wcs2Ucs()
{
return Ucs2Wcs().inverse();
}
static AcGeMatrix3d Dcs2Wcs()
{
AcGeMatrix3d mat; mat.setToIdentity();
acedVports2VportTableRecords();
AcDbViewportTableRecordPointer vtr(acedActiveViewportId(), AcDb::kForRead);
if (vtr.openStatus() == Acad::eOk)
{
mat = AcGeMatrix3d::rotation(-vtr->viewTwist(), vtr->viewDirection(), vtr->target()) *
AcGeMatrix3d::translation(vtr->target().asVector()) *
AcGeMatrix3d::planeToWorld(vtr->viewDirection());
}
return mat;
}
static AcGeMatrix3d Wcs2Dcs()
{
return Dcs2Wcs().inverse();
}