How to do zoom drawing extents for a viewport without sending commands?
<
For every viewport, you need three things to zoom correctly.
- Its View center ( using setViewCenter( ) ) – and not its center point. View center is the 2D point that you center your view on, while center point (using setCenterPoint( ) ) is the viewport’s center point in PaperSpace Layout. Center point is simply used to position viewports in a layout. The view center would depend on the drawing’s extent.
- View Direction.
-
View’s height, and not the Viewport’s height. Viewport’s width and height would apply to paper space. The width and height once again will depend on draiwing’s extent.
The following code creates 3 layouts that is zoomed to drawing’s extents programatically. They are placed arbitratily in paper space layout, but you may set your own center point and view’s height. The view’s width is set in the code to be proportional the extent’s windows width:height ratio. If you don’t do this, the layout won’t be wide enough to accomodate the whole drawing although it may be tall enough!
static void AdskTestCommand()
{
AcDbDatabase *pDbUse
= acdbHostApplicationServices()->workingDatabase();
AcDbDictionary *pNOD;
Acad::ErrorStatus eStat;
eStat = pDbUse->getNamedObjectsDictionary(pNOD, AcDb::kForRead);
if (eStat != Acad::eOk)
return;
AcDbObjectId idDict;
eStat = pNOD->getAt(L"ACAD_LAYOUT", idDict);
pNOD->close();
if (eStat != Acad::eOk)
return;
AcDbDictionary *pDict;
eStat = acdbOpenObject(pDict, idDict, AcDb::kForRead);
if (eStat != Acad::eOk)
return;
AcDbObjectId idLyt;
eStat = pDict->getAt(L"Layout1", idLyt);
pDict->close();
AcApLayoutManager *pLayM
=(AcApLayoutManager*)acdbHostApplicationServices()->layoutManager();
pLayM->setCurrentLayout(L"Layout1");
AcDbLayout* pLyt;
if (acdbOpenObject(pLyt, idLyt, AcDb::kForRead) != Acad::eOk)
return;
AcDbObjectId idBtr = pLyt->getBlockTableRecordId();
pLyt->close();
AddViewPort(idBtr, AcGePoint3d(2,5,0), AcGeVector3d( 0,0,1));
//for sw-iso
AddViewPort(idBtr, AcGePoint3d(5,5,0), AcGeVector3d( -1,-1,1));
//for ne-iso
AddViewPort(idBtr, AcGePoint3d(8,5,0), AcGeVector3d( 1,1,1));
}
// Gets a rectangular window in viewport's x-y plane
// that represents drawing's extents
static void getUcsExts(AcGePoint2d &maxExt,
AcGePoint2d &minExt,
AcGeMatrix3d UcsMat )
{
AcDbDatabase* pDb
= acdbHostApplicationServices()->workingDatabase();
AcGePoint3d max = pDb->extmax(), min = pDb->extmin();
// Make extents box
AcDbExtents ext(min, max);
// Transform extents to UCS
ext.transformBy(UcsMat);
max = ext.maxPoint();
min = ext.minPoint();
maxExt[X] = max[X];
maxExt[Y] = max[Y];
minExt[X] = min[X];
minExt[Y] = min[Y];
}
static void SetViewportExtents(AcDbViewport *pVp,
AcGePoint2d &max,
AcGePoint2d &min,
double height)
{
// Set View center
AcGePoint2d ViewCenter;
ViewCenter[X] = (max[X]+min[X])/2.0;
ViewCenter[Y] = (max[Y]+min[Y])/2.0;
pVp->setViewCenter(ViewCenter);
//set View's height + 0.5
pVp->setViewHeight((max[Y]-min[Y])+0.5);
// Get width proportional to height
double WidthHeightRatio = (max[X]-min[X])/(max[Y]-min[Y]);
pVp->setHeight(height);
//The viewport's width maintains the extent windows proportions
pVp->setWidth(height * WidthHeightRatio);
}
// Get WCS to UCS transformation matrix
static void getTrnsMatrix (AcGeMatrix3d &ucsMatrix,
AcGeVector3d ViewDirection, AcGePoint3d origin)
{
AcGePlane XYPlane(origin, ViewDirection);
ucsMatrix.setToWorldToPlane(XYPlane);
}
void AddViewPort(AcDbObjectId idToBtr,
AcGePoint3d centerPoint,
AcGeVector3d vecVPoint)
{
AcDbDatabase* pDb
= acdbHostApplicationServices()->workingDatabase();
AcDbViewport* pVp = new AcDbViewport;
// Append new viewport to paper space
AcDbBlockTableRecord *pBTR;
if (acdbOpenObject(pBTR, idToBtr, AcDb::kForWrite) != Acad::eOk)
{
acutPrintf(L"nCannot access paper space.");
delete pVp;
return;
}
if (pBTR->appendAcDbEntity( pVp) != Acad::eOk)
{
acutPrintf(L"nCannot append viewport to paper space.");
pBTR->close();
delete pVp;
return;
}
pBTR->close();
pVp->setCenterPoint(centerPoint);
//Set View direction
pVp->setViewDirection(vecVPoint);
//Assume target point is WCS (0,0,0)
AcGeMatrix3d ucsMatrix;
getTrnsMatrix (ucsMatrix, vecVPoint,AcGePoint3d(0,0,0));
// Get a rectangular window in viewport's x-y plane
// that represents drawing's extents
AcGePoint2d maxExt, minExt;
getUcsExts(maxExt, minExt, ucsMatrix);
// Here 2 is the view's height. You may change it to any height
SetViewportExtents(pVp, maxExt, minExt, 2);
pVp->setOn();
pVp->close();
}

Leave a Reply