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

05/08/2013

Создание поверхности сопряжения ассоциированной с краями.

Это пример кода, создающего поверхность сопряжения, которая ассоциативно связана с краями двух других поверхностей. Ассоциативность подразумевает, что при изменении  любой из этих поверхностей средствами AutoCAD, поверхность сопряжения будет автоматически изменена.

В этом коде создаются две выдавленных поверхности. Информация о краях этих поверхностей используется для создания профиля по сечениям. Профиль по сечениям используется для создания поверхности сопряжения.

Код - C++: [Выделить]
  1. #include "dbextrudedsurf.h"
  2. #include "dbBlendOptions.h"
  3. #include "AcDbAssocVariable.h"
  4. #include "AcDbAssocDependency.h"
  5. #include "AcDbAssocPersSubentIdPE.h"
  6. #include "acarray.h"
  7. Void CreateBlended()
  8. {
  9.   AcDbDatabase *pDb
  10.               = acdbHostApplicationServices()->workingDatabase();
  11.   Acad::ErrorStatus es;
  12.    
  13.   AcDbObjectId surfaceId1 = AcDbObjectId::kNull;
  14.   AcDbObjectId surfaceId2 = AcDbObjectId::kNull;
  15.   AcDbSweepOptions sweepOptions;
  16.   
  17.   // Создаём первую цилиндрическую поверхность
  18.   AcGePoint3d center1 = AcGePoint3d::kOrigin;
  19.   double radius1 = 10.0;
  20.   double height1 = 5.0;
  21.   AcDbCircle *pCircle1
  22.         = new AcDbCircle(center1, AcGeVector3d::kZAxis, radius1);
  23.   AcDb3dProfile circularProfile1(pCircle1);
  24.   AcDbExtrudedSurface *pExtrudedSurface1 = NULL;
  25.   es = AcDbSurface::createExtrudedSurface
  26.                       (
  27.                           &circularProfile1,
  28.                           AcGeVector3d(0.0, 0.0, height1),
  29.                           sweepOptions,
  30.                           pExtrudedSurface1
  31.                       );
  32.   
  33.   // Создаём вторую цилиндрическую поверхность
  34.   AcGePoint3d center2(0.0, 0.0, 10.0);
  35.   double radius2 = 5.0;
  36.   double height2 = 5.0;
  37.   AcDbCircle *pCircle2
  38.       = new AcDbCircle(center2,  AcGeVector3d::kZAxis, radius2);
  39.   AcDb3dProfile circularProfile2(pCircle2);
  40.   AcDbExtrudedSurface *pExtrudedSurface2 = NULL;
  41.   es = AcDbSurface::createExtrudedSurface
  42.                   (
  43.                       &circularProfile2,
  44.                       AcGeVector3d(0.0, 0.0, height2),
  45.                       sweepOptions,
  46.                       pExtrudedSurface2
  47.                   );
  48.   
  49.   AcDbBlockTable *pBlockTable;
  50.   AcDbBlockTableRecord *pMS = NULL;
  51.   pDb->getBlockTable(pBlockTable, AcDb::kForRead);
  52.   pBlockTable->getAt(ACDB_MODEL_SPACE, pMS, AcDb::kForWrite);
  53.   
  54.   // Добавляем обе цилиндрические поверхности в базу
  55.   pMS->appendAcDbEntity(surfaceId1, pExtrudedSurface1);
  56.   
  57.   pMS->appendAcDbEntity(surfaceId2, pExtrudedSurface2);
  58.   
  59.   pMS->close();
  60.   pBlockTable->close();
  61.   
  62.   // Получаем протокол расширения, ассоциированный
  63.   // с первой цилиндрической поверхностью.
  64.   // Эта информация будет использоваться для извлечения информации о грани.
  65.   AcDbAssocPersSubentIdPE* const pAssocPersSubentIdPE1
  66.       = AcDbAssocPersSubentIdPE::cast(
  67.       pExtrudedSurface1->queryX(AcDbAssocPersSubentIdPE::desc()));
  68.   
  69.   if( pAssocPersSubentIdPE1 == NULL)
  70.       return;
  71.   
  72.   // Получаем все субпримитивы грани первой цилиндрической поверхности
  73.   AcArray<AcDbSubentId> edgeSubentIds1;
  74.   pAssocPersSubentIdPE1->getAllSubentities
  75.                       (
  76.                           pExtrudedSurface1,
  77.                           AcDb::kEdgeSubentType,
  78.                           edgeSubentIds1
  79.                       );
  80.   
  81.   // Получаем субпримитив грани для грани, которая будет использоваться
  82.   // для сопряжения поверхностей.
  83.   AcDbFullSubentPath path1(surfaceId1, edgeSubentIds1[0]);
  84.   
  85.   // Создаём профиль по сечениям используя грань
  86.   AcDbEdgeRef edgeRef1(path1);
  87.   AcArray<AcDbEdgeRef> edgeArray1;
  88.   edgeArray1.append(edgeRef1);
  89.   AcDbPathRef pathRef1(edgeArray1);
  90.   AcDbLoftProfile startProfile(pathRef1);
  91.   
  92.   // Получаем протокол расширения, ассоциированный со
  93.   // второй цилиндрической поверхностью
  94.   AcDbAssocPersSubentIdPE* const pAssocPersSubentIdPE2
  95.       = AcDbAssocPersSubentIdPE::cast(
  96.           pExtrudedSurface2->queryX(AcDbAssocPersSubentIdPE::desc()));
  97.   
  98.   if( pAssocPersSubentIdPE2 == NULL)
  99.       return;
  100.   
  101.   // Получаем все субпримитивы граней второй цилиндрической поверхности
  102.   AcArray<AcDbSubentId> edgeSubentIds2;
  103.   pAssocPersSubentIdPE2->getAllSubentities
  104.                   (
  105.                       pExtrudedSurface2,
  106.                       AcDb::kEdgeSubentType,
  107.                       edgeSubentIds2
  108.                   );
  109.   
  110.   // Получаем субпримитив грани, которая будет использоваться
  111.   // для сопряжения поверхностей
  112.   AcDbFullSubentPath path2(surfaceId2, edgeSubentIds2[1]);
  113.   
  114.   // Создаём профиль по сечениям используя грани
  115.   AcDbEdgeRef edgeRef2(path2);
  116.   AcArray<AcDbEdgeRef> edgeArray2;
  117.   edgeArray2.append(edgeRef2);
  118.   AcDbPathRef pathRef2(edgeArray2);
  119.   AcDbLoftProfile endProfile(pathRef2);
  120.   
  121.   pExtrudedSurface1->close();
  122.   pExtrudedSurface2->close();
  123.   
  124.   // Используем поверхность сопряжения используя профили по сечениям
  125.   // Убедимся, что мы создаём ассоциативную поверхность сопряжения.
  126.   AcDbBlendOptions blendOptions;
  127.   AcDbObjectId blendSurfaceId = AcDbObjectId::kNull;
  128.   AcDbSurface *pBlendSurface = NULL;
  129.   
  130.   es = AcDbSurface::createBlendSurface
  131.                   (
  132.                       &startProfile,
  133.                       &endProfile,
  134.                       &blendOptions,
  135.                       true,
  136.                       blendSurfaceId
  137.                   );
  138.   if(es == Acad::eOk)
  139.   {
  140.       acutPrintf(ACRX_T("Создана поверхность сопряжения !"));
  141.   }
  142. }


На рисунке видны цилиндрические поверхности и поверхность сопряжения:

 

 

Источник: http://adndevblog.typepad.com/autocad/2013/06/creating-blended-surface-associated-with-edges.html

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

 

Опубликовано 05.08.2013
Отредактировано 08.08.2013 в 14:55:15