admin 发表于 2024-3-14 20:14:32

[每日一码] 几个视图ARX代码

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, rb.resval.rpoint, rb.resval.rpoint);
                  }
                  // 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();
          }
      }
页: [1]
查看完整版本: [每日一码] 几个视图ARX代码