22/08/2013
					Использование транзитной графики
В статье мы рассматривали использование графических функций, обеспечивающих показ временной графики с помощью AutoCAD API. В этой статье мы рассмотрим использование API транзитной графики для отображения временной графики. Это API обеспечивает значительно лучшее управление над отображением графики по сравнению с графическими функциями.Это пример кода который использует транзитную графику для отображения точек пересечения прямоугольника и луча. Чтобы проверить его нарисуйте прямоугольник и выберите внутреннюю точку направления луча, когда программа спросит.
С использованием ObjectARX :
Код - C++: [Выделить]
- static AcArray<AcDbEntity*> _markers;
 - static AcArray<int> viewportNumbers;
 - static void ArxProject_Test(void)
 - {
 - Acad::ErrorStatus es;
 - AcDbDatabase *pDb =
 - acdbHostApplicationServices()->workingDatabase();
 - ads_point pickPnt;
 - ads_name ent_name;
 - int ret = acedEntSel(
 - ACRX_T("\nВыберите полилинию: "),
 - ent_name,
 - pickPnt
 - );
 - if(ret != RTNORM)
 - return;
 - AcDbObjectId plOid;
 - es = acdbGetObjectId(plOid, ent_name);
 - if (es != Acad::eOk)
 - return;
 - ads_point adsTestPoint;
 - ret = acedGetPoint
 - (
 - NULL,
 - ACRX_T("\nУкажите внутреннюю точку: "),
 - adsTestPoint
 - ) ;
 - if(ret != RTNORM)
 - return;
 - AcGePoint3d testPoint = asPnt3d(adsTestPoint);
 - ads_real rayAngle = 0.0;
 - ret = acedGetAngle(
 - asDblArray(testPoint),
 - ACRX_T("Укажите направление луча: "),
 - &rayAngle
 - );
 - if(ret != RTNORM)
 - return;
 - AcGePoint3d tempPoint = testPoint + AcGeVector3d::kXAxis;
 - tempPoint = tempPoint.rotateBy(
 - rayAngle,
 - AcGeVector3d::kZAxis,
 - testPoint
 - );
 - AcGeVector3d rayDir = tempPoint - testPoint;
 - ClearTransientGraphics();
 - AcDbTransactionManager* pTM = pDb->transactionManager();
 - AcTransaction *pTransaction = pTM->startTransaction();
 - AcDbObject *pCurveObj = NULL;
 - es = pTransaction->getObject(
 - pCurveObj,
 - plOid,
 - AcDb::kForRead
 - );
 - AcDbCurve *pCurve = AcDbCurve::cast(pCurveObj);
 - AcGiTransientManager* pTransientManager
 - = acgiGetTransientManager();
 - viewportNumbers.removeAll();
 - struct resbuf res;
 - acedGetVar(L"CVPORT", &res);
 - viewportNumbers.append(res.resval.rint);
 - if(pCurve != NULL)
 - {
 - for (int cnt = 0; cnt < 2; cnt++)
 - {
 - if (cnt == 1)
 - rayDir = rayDir.negate();
 - AcDbRay ray;
 - ray.setBasePoint(testPoint);
 - ray.setUnitDir(rayDir);
 - AcGePoint3dArray IntersectionPoints;
 - es = pCurve->intersectWith(
 - &ray,
 - AcDb::kOnBothOperands,
 - IntersectionPoints
 - );
 - if(es == Acad::eOk)
 - {
 - int numberOfInters = 0;
 - numberOfInters = IntersectionPoints.length();
 - for(int i=0; i < numberOfInters; ++i)
 - {
 - AcGePoint3d pt = IntersectionPoints[i];
 - AcDbCircle *marker
 - = new AcDbCircle
 - (
 - pt,
 - AcGeVector3d::kZAxis,
 - 0.2
 - );
 - AcCmColor color;
 - color.setColor(2);
 - marker->setColor(color);
 - _markers.append(marker);
 - pTransientManager->addTransient
 - (
 - marker,
 - kAcGiDirectShortTerm,
 - 0,
 - viewportNumbers
 - );
 - acutPrintf(
 - ACRX_T("\nТочка: %lf %lf"),
 - pt.x,
 - pt.y
 - );
 - }
 - }
 - }
 - }
 - pTM->endTransaction();
 - }
 - static void ClearTransientGraphics()
 - {
 - AcGiTransientManager* pTransientManager
 - = acgiGetTransientManager();
 - int numOfMarkers = _markers.length();
 - if (numOfMarkers > 0)
 - {
 - for(int index = 0; index < numOfMarkers; index++)
 - {
 - AcDbEntity *pMarker = _markers.at(index);
 - pTransientManager->eraseTransient
 - (
 - pMarker,
 - viewportNumbers
 - );
 - delete pMarker;
 - }
 - _markers.removeAll();
 - }
 - }
 
С использованием AutoCAD .NET API :
Код - C#: [Выделить]
- using Autodesk.AutoCAD.GraphicsInterface;
 - DBObjectCollection _markers = null;
 - [CommandMethod("Test")]
 - public void TestMethod()
 - {
 - Document activeDoc
 - = Application.DocumentManager.MdiActiveDocument;
 - Database db = activeDoc.Database;
 - Editor ed = activeDoc.Editor;
 - PromptEntityOptions peo
 - = new PromptEntityOptions("\nВыберите полилинию: ");
 - peo.SetRejectMessage("Это не полилиния!");
 - peo.AddAllowedClass
 - (
 - typeof(Autodesk.AutoCAD.DatabaseServices.Polyline),
 - true
 - );
 - PromptEntityResult per = ed.GetEntity(peo);
 - if (per.Status != PromptStatus.OK)
 - return;
 - ObjectId plOid = per.ObjectId;
 - PromptPointResult ppr =
 - ed.GetPoint
 - (
 - new PromptPointOptions("\nВыберите внутреннюю точку: ")
 - );
 - if (ppr.Status != PromptStatus.OK)
 - return;
 - Point3d testPoint = ppr.Value;
 - PromptAngleOptions pao
 - = new PromptAngleOptions("Укажите направление луча: ");
 - pao.BasePoint = testPoint;
 - pao.UseBasePoint = true;
 - PromptDoubleResult rayAngle = ed.GetAngle(pao);
 - if (rayAngle.Status != PromptStatus.OK)
 - return;
 - Point3d tempPoint = testPoint.Add(Vector3d.XAxis);
 - tempPoint
 - = tempPoint.RotateBy(
 - rayAngle.Value,
 - Vector3d.ZAxis,
 - testPoint
 - );
 - Vector3d rayDir = tempPoint - testPoint;
 - ClearTransientGraphics();
 - _markers = new DBObjectCollection();
 - using (Transaction tr
 - = db.TransactionManager.StartTransaction())
 - {
 - Curve plcurve = tr.GetObject(
 - plOid,
 - OpenMode.ForRead
 - ) as Curve;
 - for (int cnt = 0; cnt < 2; cnt++)
 - {
 - if (cnt == 1)
 - rayDir = rayDir.Negate();
 - using (Ray ray = new Ray())
 - {
 - ray.BasePoint = testPoint;
 - ray.UnitDir = rayDir;
 - Point3dCollection intersectionPts
 - = new Point3dCollection();
 - plcurve.IntersectWith(
 - ray,
 - Intersect.OnBothOperands,
 - intersectionPts,
 - IntPtr.Zero,
 - IntPtr.Zero
 - );
 - foreach (Point3d pt in intersectionPts)
 - {
 - Circle marker
 - = new Circle(pt, Vector3d.ZAxis, 0.2);
 - marker.Color = Color.FromRgb(0, 255, 0);
 - _markers.Add(marker);
 - IntegerCollection intCol
 - = new IntegerCollection();
 - TransientManager tm
 - = TransientManager.CurrentTransientManager;
 - tm.AddTransient
 - (
 - marker,
 - TransientDrawingMode.Highlight,
 - 128,
 - intCol
 - );
 - ed.WriteMessage("\n" + pt.ToString());
 - }
 - }
 - }
 - tr.Commit();
 - }
 - }
 - void ClearTransientGraphics()
 - {
 - TransientManager tm
 - = TransientManager.CurrentTransientManager;
 - IntegerCollection intCol = new IntegerCollection();
 - if (_markers != null)
 - {
 - foreach (DBObject marker in _markers)
 - {
 - tm.EraseTransient(
 - marker,
 - intCol
 - );
 - marker.Dispose();
 - }
 - }
 - }
 
Источник: http://adndevblog.typepad.com/autocad/2012/04/using-transient-graphics.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=184
Опубликовано 22.08.2013