|
[code]static bool GetActiveViewPortInfo (AcDbDatabase *pDb, ads_real &height, ads_real &width,
AcGePoint3d &target, AcGeVector3d &viewDir,
ads_real &viewTwist,
AcDbObjectId ¤tVsId,
bool getViewCenter)
{
// if not ok
if (pDb == NULL)
return false;
// get the current document associated with the PDb database and set it current
AcApDocument *pDoc = acDocManager->document(pDb);
acDocManager->setCurDocument(pDoc);
acDocManager->lockDocument(pDoc);
// make sure the active view port is uptodate
acedVports2VportTableRecords();
// open the view port records
AcDbViewportTablePointer pVTable(pDb->viewportTableId(), AcDb::kForRead);
// if we opened them ok
if (pVTable.openStatus() == Acad::eOk)
{
AcDbViewportTableRecord *pViewPortRec = NULL;
Acad::ErrorStatus es = pVTable->getAt (_T("*Active"), pViewPortRec, AcDb::kForRead);
if (es == Acad::eOk)
{
// get the height of the view
height = pViewPortRec->height ();
// get the width
width = pViewPortRec->width ();
// if the user wants the center of the viewport used
if (getViewCenter == true)
{
struct resbuf rb;
memset (&rb, 0, sizeof (struct resbuf));
// get the system var VIEWCTR
acedGetVar (_T("VIEWCTR"), &rb);
// set that as the target
target = AcGePoint3d (rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
}
// we want the viewport's camera target setting
else
{
// get the target of the view
target = pViewPortRec->target ();
}
// get the view direction
viewDir = pViewPortRec->viewDirection ();
// get the view twist of the viewport
viewTwist = pViewPortRec->viewTwist ();
// return the current Visual Style
currentVsId = pViewPortRec->visualStyle();
}
// close after use
pViewPortRec->close();
}
acDocManager->unlockDocument(pDoc);
// now restore the original document
acDocManager->setCurDocument(acDocManager->mdiActiveDocument());
return (true);
}
// set the passed AcGsView to the *Active* AutoCAD AcDbDatabase view
static AcDbObjectId SetViewTo(AcGsView *pView, AcDbDatabase *pDb, AcGeMatrix3d& viewMat)
{
// we are going to set the view to the current view of the drawing
// The overall approach is to calculate the extents of the database in the coordinate system of the view
// Calculate the extents in WCS
AcGePoint3d extMax = pDb->extmax();
AcGePoint3d extMin = pDb->extmin();
// initialize it with sensible numbers - even if there is no entity
if (extMin.distanceTo(extMax) > 1e20)
{
extMin.set(0, 0, 0);
extMax.set(100, 100, 100);
}
// get the view port information - see parameter list
ads_real height = 0.0, width = 0.0, viewTwist = 0.0;
AcGePoint3d targetView;
AcGeVector3d viewDir;
AcDbObjectId currentVsId;
GetActiveViewPortInfo (pDb, height, width, targetView, viewDir, viewTwist, currentVsId, true);
// we are only interested in the directions of the view, not the sizes, so we normalise.
viewDir = viewDir.normal();
//**********************************************
// Our view coordinate space consists of z direction
// get a perp vector off the z direction
// Make sure its normalised
AcGeVector3d viewXDir = viewDir.perpVector ().normal();
// correct the x angle by applying the twist
viewXDir = viewXDir.rotateBy (viewTwist, -viewDir);
// now we can work out y, this is of course perp to the x and z directions. No need to normalise this,
// as we know that x and z are of unit length, and perpendicular, so their cross product must be on unit length
AcGeVector3d viewYDir = viewDir.crossProduct (viewXDir);
// find a nice point around which to transform the view. We'll use the same point as the center of the view.
AcGePoint3d boxCenter = extMin + 0.5 * ( extMax - extMin );
//**********************************************
// create a transform from WCS to View space
// this represents the transformation from WCS to the view space. (Actually not quite since
// we are keeping the fixed point as the center of the box for convenience )
viewMat = AcGeMatrix3d::alignCoordSys (boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
boxCenter, viewXDir, viewYDir, viewDir).inverse();
AcDbExtents wc**tents(extMin, extMax);
// now we have the view Extents
AcDbExtents viewExtents = wc**tents;
// transforms the extents in WCS->view space
viewExtents.transformBy (viewMat);
//**********************************************
// get the extents of the AutoCAD view
double xMax = fabs(viewExtents.maxPoint ().x - viewExtents.minPoint ().x);
double yMax = fabs(viewExtents.maxPoint ().y - viewExtents.minPoint ().y);
//**********************************************
// setup the view
AcGePoint3d eye = boxCenter + viewDir;
// upvector
pView->setView(eye, boxCenter, viewYDir, xMax, yMax);
// update the gsView
refreshView(pView);
return currentVsId;
}
static void refreshView(AcGsView *pView)
{
if (pView != NULL)
{
pView->invalidate();
pView->update();
}
}[/code] |
|