ADN Open CIS
Сообщество программистов Autodesk в СНГ

30/05/2013

Установка камеры/объектива, цели, ширины и высоты вида

Вопрос:

Я хочу установить камеру, цели и поле зрения в окне модели, чтобы точно сфокусироваться на определенных объектах в перспективе. Я пытался это сделать различными способами, но никогда не получалось в точности то, что хотелось.

Решение:

В прикрепленном чертеже (Загрузить Окружности) у нас три круга: красный (r = 10), зеленый (r = 20) и голубой (r = 30). Они все параллельны и их центры лежат на одной прямой.

Допустим, мы хотим поместить камеру в центре красного круга, а затем сфокусируемся на зелёном круге. Вы можете использовать AcGsView, связанный с текущим видом модели и настроить его. position устанавливает положение камеры и target устанавливает цель. Так как плоскость окружности параллельна плоскости дисплея, поэтому мы не должны преобразовать габариты круга из МСК (WCS) в ДСК (DCS). Ширина и высота поля и высота имеет габариты в плоскости, которая определяется целевой точкой и направлением взгляда. Так что если вы установите точку цели совпадающей с центром зеленого круга, то ширины поля и высоты могут быть установлены на основе диаметра круга.

Когда выполняется код примера сначала выбираем центр красного круга, а затем центр зеленого круга.

 

Код - C++: [Выделить]
  1. static void TransformTest_SetModelView(void)
  2. {
  3.   AcDbDatabase * pDb =
  4.     acdbHostApplicationServices()->workingDatabase();
  5.  
  6.   if (!pDb->tilemode())
  7.   {
  8.     acutPrintf(
  9.       L"\nЭта команда работает только в пространстве модели (т.е. tilemode отлична от 0)\n");
  10.     return;
  11.   }
  12.  
  13.   AcGePoint3d ptCamera;
  14.   if (RTNORM != acedGetPoint(
  15.     NULL, L"\nВыберите точку камеры: ", asDblArray(ptCamera)))
  16.     return;
  17.  
  18.   AcGePoint3d ptTarget;
  19.   if (RTNORM != acedGetPoint(
  20.     NULL, L"\nВыберите точку цели: ", asDblArray(ptTarget)))
  21.     return;
  22.  
  23.   resbuf cvport;
  24.   acedGetVar(L"CVPORT", &cvport);
  25.  
  26.   AcGsView * view = acgsGetGsView(cvport.resval.rint, true); 
  27.  
  28.   double aspectRatio = view->fieldWidth() / view->fieldHeight();
  29.   double newWidth, newHeight;
  30.   if (aspectRatio > 1)
  31.   {
  32.     // Высота зеленого круга, который мы хотим включить
  33.     // в картинку равна 40
  34.     newHeight = 40;
  35.     newWidth = newHeight * aspectRatio;
  36.   }
  37.   else
  38.   {
  39.     newWidth = 40;
  40.     newHeight = newWidth / aspectRatio;
  41.   }
  42.  
  43.   view->setView(
  44.     ptCamera,
  45.     ptTarget,
  46.     AcGeVector3d::kZAxis,
  47.     newWidth,
  48.     newHeight,
  49.     AcGsView::kPerspective);
  50.   view->update();
  51.  
  52.   acgsSetViewParameters(cvport.resval.rint, view, true, true);
  53. }

Этого же самого можно достичь используя AcDbViewTableRecord и функцию acedSetCurrentView:

Код - C++: [Выделить]
  1. static void TransformTest_SetModelView2(void)
  2. {
  3.   AcDbDatabase * pDb =
  4.     acdbHostApplicationServices()->workingDatabase();
  5.  
  6.   if (!pDb->tilemode())
  7.   {
  8.     acutPrintf(
  9.       L"\nЭта команда работает только в пространстве модели (т.е. tilemode отлична от 0)\n");
  10.     return;
  11.   }
  12.  
  13.   AcGePoint3d ptCamera;
  14.   if (RTNORM != acedGetPoint(NULL,
  15.     L"\nУкажите точку камеры: ", asDblArray(ptCamera)))
  16.     return;
  17.  
  18.   AcGePoint3d ptTarget;
  19.   if (RTNORM != acedGetPoint(NULL,
  20.     L"\nУкажите точку цели: ", asDblArray(ptTarget)))
  21.     return;
  22.  
  23.   Acad::ErrorStatus err = acedVports2VportTableRecords();
  24.   {
  25.     AcDbViewportTableRecordPointer
  26.       ptrVp(acedActiveViewportId(), AcDb::kForRead);
  27.  
  28.     // Копируем данные из ViewportTableRecord
  29.     AcDbViewTableRecord vtr;   
  30.     vtr.setBackClipDistance(ptrVp->backClipDistance()); 
  31.     vtr.setBackClipEnabled(ptrVp->backClipEnabled());  
  32.     vtr.setElevation(ptrVp->elevation());  
  33.     vtr.setFrontClipAtEye(ptrVp->frontClipAtEye());  
  34.     vtr.setFrontClipDistance(ptrVp->frontClipDistance()); 
  35.     vtr.setPerspectiveEnabled(ptrVp->perspectiveEnabled()); 
  36.     vtr.setRenderMode(ptrVp->renderMode()); 
  37.     vtr.setUcs(ptrVp->ucsName());  
  38.     vtr.setViewTwist(ptrVp->viewTwist());   
  39.     vtr.setCenterPoint(ptrVp->centerPoint()); 
  40.     vtr.setLensLength(ptrVp->lensLength());  
  41.  
  42.     // Главные установки
  43.     double aspectRatio = vtr.width() / vtr.height();
  44.     double newWidth, newHeight;
  45.     if (aspectRatio > 1)
  46.     {
  47.     // Высота зеленого круга, который мы хотим включить
  48.     // в картинку равна 40
  49.       newHeight = 40;
  50.       newWidth = newHeight * aspectRatio;
  51.     }
  52.     else
  53.     {
  54.       newWidth = 40;
  55.       newHeight = newWidth / aspectRatio;
  56.     }
  57.     vtr.setWidth(newWidth);
  58.     vtr.setHeight(newHeight);
  59.     vtr.setTarget(ptTarget);
  60.     vtr.setViewDirection(ptCamera - ptTarget); 
  61.  
  62.     acedSetCurrentView(&vtr, NULL);
  63.   }
  64. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/07/set-model-viewports-cameraeye-target-view-width-view-height.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=89.0

Опубликовано 30.05.2013
Отредактировано 08.06.2013 в 02:41:21