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

22/08/2013

Использование транзитной графики

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

Это пример кода который использует транзитную графику для отображения точек пересечения прямоугольника и луча. Чтобы проверить его нарисуйте прямоугольник и выберите внутреннюю точку направления луча, когда программа спросит.

С использованием ObjectARX :

Код - C++: [Выделить]
  1. static AcArray<AcDbEntity*> _markers;
  2. static AcArray<int> viewportNumbers;
  3.  
  4. static void ArxProject_Test(void)
  5. {
  6.     Acad::ErrorStatus es;
  7.     AcDbDatabase *pDb =
  8.         acdbHostApplicationServices()->workingDatabase();
  9.  
  10.     ads_point pickPnt;
  11.     ads_name ent_name;
  12.     int ret = acedEntSel(
  13.                             ACRX_T("\nВыберите полилинию: "),
  14.                             ent_name,
  15.                             pickPnt
  16.                         );
  17.     if(ret != RTNORM)
  18.         return;
  19.  
  20.     AcDbObjectId plOid;
  21.     es = acdbGetObjectId(plOid, ent_name);
  22.     if (es != Acad::eOk)
  23.         return;
  24.  
  25.     ads_point adsTestPoint;
  26.     ret = acedGetPoint
  27.                 (
  28.                     NULL,
  29.                     ACRX_T("\nУкажите внутреннюю точку: "),
  30.                     adsTestPoint
  31.                 ) ;
  32.     if(ret != RTNORM)
  33.         return;
  34.     AcGePoint3d testPoint = asPnt3d(adsTestPoint);
  35.  
  36.     ads_real rayAngle = 0.0;
  37.     ret = acedGetAngle(
  38.                         asDblArray(testPoint),
  39.                         ACRX_T("Укажите направление луча: "),
  40.                         &rayAngle
  41.                       );
  42.     if(ret != RTNORM)
  43.         return;
  44.  
  45.     AcGePoint3d tempPoint = testPoint + AcGeVector3d::kXAxis;
  46.     tempPoint = tempPoint.rotateBy(
  47.                                     rayAngle,
  48.                                     AcGeVector3d::kZAxis,
  49.                                     testPoint
  50.                                   );
  51.     AcGeVector3d rayDir = tempPoint - testPoint;
  52.  
  53.     ClearTransientGraphics();
  54.  
  55.     AcDbTransactionManager* pTM = pDb->transactionManager();
  56.     AcTransaction *pTransaction = pTM->startTransaction();
  57.     AcDbObject *pCurveObj = NULL;
  58.  
  59.     es = pTransaction->getObject(
  60.                                     pCurveObj,
  61.                                     plOid,
  62.                                     AcDb::kForRead
  63.                                 );
  64.     AcDbCurve *pCurve = AcDbCurve::cast(pCurveObj);
  65.  
  66.     AcGiTransientManager* pTransientManager
  67.                                 = acgiGetTransientManager();
  68.  
  69.     viewportNumbers.removeAll();
  70.     struct resbuf res;
  71.     acedGetVar(L"CVPORT", &res);
  72.     viewportNumbers.append(res.resval.rint);
  73.  
  74.     if(pCurve != NULL)
  75.     {
  76.         for (int cnt = 0; cnt < 2; cnt++)
  77.         {
  78.             if (cnt == 1)
  79.                 rayDir = rayDir.negate();
  80.  
  81.             AcDbRay ray;
  82.             ray.setBasePoint(testPoint);
  83.             ray.setUnitDir(rayDir);
  84.  
  85.             AcGePoint3dArray IntersectionPoints;
  86.             es = pCurve->intersectWith(
  87.                                         &ray,
  88.                                         AcDb::kOnBothOperands,
  89.                                         IntersectionPoints
  90.                                       );
  91.             if(es == Acad::eOk)
  92.             {
  93.                 int numberOfInters = 0;
  94.                 numberOfInters = IntersectionPoints.length();
  95.                 for(int i=0; i < numberOfInters; ++i)
  96.                 {
  97.                     AcGePoint3d pt = IntersectionPoints[i];
  98.                     AcDbCircle *marker
  99.                         = new AcDbCircle
  100.                                     (
  101.                                         pt,
  102.                                         AcGeVector3d::kZAxis,
  103.                                         0.2
  104.                                     );
  105.                     AcCmColor color;
  106.                     color.setColor(2);
  107.                     marker->setColor(color);
  108.                     _markers.append(marker);
  109.  
  110.                     pTransientManager->addTransient
  111.                                         (
  112.                                             marker,
  113.                                             kAcGiDirectShortTerm,
  114.                                             0,
  115.                                             viewportNumbers
  116.                                         );
  117.  
  118.                     acutPrintf(
  119.                                 ACRX_T("\nТочка: %lf %lf"),
  120.                                 pt.x,
  121.                                 pt.y
  122.                               );
  123.                 }
  124.             }
  125.         }
  126.     }
  127.     pTM->endTransaction();
  128. }
  129.  
  130. static void ClearTransientGraphics()
  131. {
  132.     AcGiTransientManager* pTransientManager
  133.                                     = acgiGetTransientManager();
  134.  
  135.     int numOfMarkers = _markers.length();
  136.     if (numOfMarkers > 0)
  137.     {
  138.         for(int index = 0; index < numOfMarkers; index++)
  139.         {
  140.             AcDbEntity *pMarker = _markers.at(index);
  141.             pTransientManager->eraseTransient
  142.                                     (
  143.                                         pMarker,
  144.                                         viewportNumbers
  145.                                     );
  146.             delete pMarker;
  147.         }
  148.         _markers.removeAll();
  149.     }
  150. }

 

С использованием AutoCAD .NET API :

 

Код - C#: [Выделить]
  1. using Autodesk.AutoCAD.GraphicsInterface;
  2.  
  3. DBObjectCollection _markers = null;
  4.  
  5. [CommandMethod("Test")]
  6. public void TestMethod()
  7. {
  8.     Document activeDoc
  9.         = Application.DocumentManager.MdiActiveDocument;
  10.     Database db = activeDoc.Database;
  11.     Editor ed = activeDoc.Editor;
  12.  
  13.     PromptEntityOptions peo
  14.         = new PromptEntityOptions("\nВыберите полилинию: ");
  15.     peo.SetRejectMessage("Это не полилиния!");
  16.     peo.AddAllowedClass
  17.         (
  18.             typeof(Autodesk.AutoCAD.DatabaseServices.Polyline),
  19.             true
  20.         );
  21.     PromptEntityResult per = ed.GetEntity(peo);
  22.     if (per.Status != PromptStatus.OK)
  23.         return;
  24.  
  25.     ObjectId plOid = per.ObjectId;
  26.  
  27.     PromptPointResult ppr =
  28.         ed.GetPoint
  29.         (
  30.             new PromptPointOptions("\nВыберите внутреннюю точку: ")
  31.         );
  32.     if (ppr.Status != PromptStatus.OK)
  33.         return;
  34.     Point3d testPoint = ppr.Value;
  35.  
  36.     PromptAngleOptions pao
  37.         = new PromptAngleOptions("Укажите направление луча: ");
  38.     pao.BasePoint = testPoint;
  39.     pao.UseBasePoint = true;
  40.     PromptDoubleResult rayAngle = ed.GetAngle(pao);
  41.     if (rayAngle.Status != PromptStatus.OK)
  42.         return;
  43.  
  44.     Point3d tempPoint = testPoint.Add(Vector3d.XAxis);
  45.     tempPoint
  46.         = tempPoint.RotateBy(
  47.                                 rayAngle.Value,
  48.                                 Vector3d.ZAxis,
  49.                                 testPoint
  50.                             );
  51.     Vector3d rayDir = tempPoint - testPoint;
  52.  
  53.     ClearTransientGraphics();
  54.     _markers = new DBObjectCollection();
  55.  
  56.     using (Transaction tr
  57.                 = db.TransactionManager.StartTransaction())
  58.     {
  59.         Curve plcurve = tr.GetObject(
  60.                                         plOid,
  61.                                         OpenMode.ForRead
  62.                                     ) as Curve;
  63.  
  64.         for (int cnt = 0; cnt < 2; cnt++)
  65.         {
  66.             if (cnt == 1)
  67.                 rayDir = rayDir.Negate();
  68.  
  69.             using (Ray ray = new Ray())
  70.             {
  71.                 ray.BasePoint = testPoint;
  72.                 ray.UnitDir = rayDir;
  73.  
  74.                 Point3dCollection intersectionPts
  75.                                     = new Point3dCollection();
  76.                 plcurve.IntersectWith(
  77.                                         ray,
  78.                                         Intersect.OnBothOperands,
  79.                                         intersectionPts,
  80.                                         IntPtr.Zero,
  81.                                         IntPtr.Zero
  82.                                      );
  83.  
  84.                 foreach (Point3d pt in intersectionPts)
  85.                 {
  86.                     Circle marker
  87.                         = new Circle(pt, Vector3d.ZAxis, 0.2);
  88.                     marker.Color = Color.FromRgb(0, 255, 0);
  89.                     _markers.Add(marker);
  90.  
  91.                     IntegerCollection intCol
  92.                                     = new IntegerCollection();
  93.                     TransientManager tm
  94.                         = TransientManager.CurrentTransientManager;
  95.  
  96.                     tm.AddTransient
  97.                         (
  98.                             marker,
  99.                             TransientDrawingMode.Highlight,
  100.                             128,
  101.                             intCol
  102.                         );
  103.  
  104.                     ed.WriteMessage("\n" + pt.ToString());
  105.                 }
  106.             }
  107.         }
  108.         tr.Commit();
  109.     }
  110. }
  111.  
  112. void ClearTransientGraphics()
  113. {
  114.     TransientManager tm
  115.             = TransientManager.CurrentTransientManager;
  116.     IntegerCollection intCol = new IntegerCollection();
  117.     if (_markers != null)
  118.     {
  119.         foreach (DBObject marker in _markers)
  120.         {
  121.             tm.EraseTransient(
  122.                                 marker,
  123.                                 intCol
  124.                              );
  125.             marker.Dispose();
  126.         }
  127.     }
  128. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/04/using-transient-graphics.html

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

Опубликовано 22.08.2013