Последние сообщения

Последние сообщения

Страницы: [1] 2 3 ... 10
1
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от Александр Ривилис 23-09-2017, 14:09:26 »
begiz
Я сделал несколько исправлений в коде - выкинул лишнее и переписал видео.
2
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от begiz 23-09-2017, 09:37:42 »
Спасибо Александр!
Ваш код работает как надо!!

Попробую переписать свой чтобы понять, что в нем не так.
Потому что принцип как должно работать у меня вроде правельный, наверно чтото не закрываю или не в том месте закрываю.
3
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от Александр Ривилис 23-09-2017, 01:34:21 »
На всякий случай второй вариант с немедленной перерисовкой штриховки:

Код - C++ [Выбрать]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6.  
  7. //-----------------------------------------------------------------------------
  8. #define szRDS _RXST("")
  9.  
  10. //-----------------------------------------------------------------------------
  11. //----- ObjectARX EntryPoint
  12. class CTestChangeHatchApp : public AcRxArxApp {
  13.  
  14. public:
  15.   CTestChangeHatchApp() : AcRxArxApp() {}
  16.  
  17.   virtual AcRx::AppRetCode On_kInitAppMsg(void *pkt) {
  18.     AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);
  19.     return (retCode);
  20.   }
  21.  
  22.   virtual AcRx::AppRetCode On_kUnloadAppMsg(void *pkt) {
  23.     AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);
  24.     return (retCode);
  25.   }
  26.  
  27.   virtual void RegisterServerComponents() {     }
  28.  
  29.   static int GetIndexOfNearestVertex(AcGePoint3d pNearUcs, AcDbPolyline *pPline)
  30.   {
  31.     AcGePoint3d pWcs;
  32.     acdbUcs2Wcs(asDblArray(pNearUcs), asDblArray(pWcs), false);
  33.     AcGePoint3d pNearWcs;
  34.     pPline->getClosestPointTo(pWcs, pNearWcs);
  35.     double param = 0;
  36.     pPline->getParamAtPoint(pNearWcs, param);
  37.     double dMin = floor(param);
  38.     double dMax = ceil(param);
  39.     int iVertex =
  40.       ((fabs(dMin - param) < fabs(dMax - param)) ? int(dMin + 1e-6) : int(dMax + 1e-6)) % pPline->numVerts();
  41.     return iVertex;
  42.   }
  43.  
  44.   static void MyGroupMyCommand1() {
  45.     AcGePoint3d pUcs; ads_name en;
  46.     while (acedEntSel(_T("\nSelect pline: "), en, asDblArray(pUcs)) == RTNORM)
  47.     {
  48.       AcDbObjectId idPline; acdbGetObjectId(idPline, en);
  49.       AcDbObjectPointer<AcDbPolyline> pPline(idPline, AcDb::kForRead);
  50.       if (pPline.openStatus() != Acad::eOk)
  51.       {
  52.         acutPrintf(_T("\nError selection pline")); return;
  53.       }
  54.       int iVertex = GetIndexOfNearestVertex(pUcs, pPline);
  55.       AcGePoint3d pVertexWcs;
  56.       pPline->getPointAt(iVertex, pVertexWcs);
  57.       AcGePoint3d pVertexUcs; acdbWcs2Ucs(asDblArray(pVertexWcs), asDblArray(pVertexUcs), false);
  58.       AcGePoint3d pNewVertexUcs;
  59.       const AcDbVoidPtrArray *reactors = NULL;
  60.       if (acedGetPoint(asDblArray(pVertexUcs), _T("\nNew vertex position: "), asDblArray(pNewVertexUcs)) == RTNORM)
  61.       {
  62.         AcGePoint3d pNewVertexWcs; acdbUcs2Wcs(asDblArray(pNewVertexUcs), asDblArray(pNewVertexWcs), false);
  63.         if (pPline->upgradeOpen() == Acad::eOk)
  64.         {
  65.           AcGePoint3d pEcs;
  66.           acdbWcs2Ecs(asDblArray(pNewVertexWcs), asDblArray(pEcs), asDblArray(pPline->normal()), false);
  67.           pPline->setPointAt(iVertex, AcGePoint2d(pEcs.x, pEcs.y));
  68.           reactors = pPline->reactors();
  69.         }
  70.       }
  71.       pPline->close();
  72.       if (reactors != NULL)
  73.       {
  74.         for (int i = 0; i < reactors->length(); i++)
  75.         {
  76.           void* pSomething = reactors->at(i);
  77.           if (acdbIsPersistentReactor(pSomething))
  78.           {
  79.             AcDbObjectPointer<AcDbHatch> pHatch(acdbPersistentReactorObjectId(pSomething), AcDb::kForWrite);
  80.             if (pHatch.openStatus() == Acad::eOk)
  81.             {
  82.               pHatch->setPattern(pHatch->patternType(), pHatch->patternName());
  83.               AcDbObjectIdArray ids;
  84.               pHatch->getAssocObjIds(ids);
  85.               pHatch->removeLoopAt(0);
  86.               pHatch->appendLoop(AcDbHatch::kExternal, ids);
  87.               pHatch->evaluateHatch();
  88.             }
  89.           }
  90.         }
  91.       }
  92.     }
  93.   }
  94. };
  95.  
  96. //-----------------------------------------------------------------------------
  97. IMPLEMENT_ARX_ENTRYPOINT(CTestChangeHatchApp)
  98.  
  99. ACED_ARXCOMMAND_ENTRY_AUTO(CTestChangeHatchApp, MyGroup, MyCommand1, MyCommandLocal1, ACRX_CMD_MODAL, NULL)
  100.  



Хочу подчеркнуть, что это лишь пример с минимальным количеством проверок на ошибки.
4
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от Александр Ривилис 23-09-2017, 01:01:30 »
Код действительно "страшненький". Но дело не в этом. Вот код редактирования контура штриховки (передвигается выбранная вершина полилинии):

Код - C++ [Выбрать]
  1. static void MyGroupMyCommand1() {
  2. AcGePoint3d pUcs; ads_name en;
  3. if (acedEntSel(_T("\nSelect pline: "), en, asDblArray(pUcs)) == RTNORM)
  4. {
  5.   AcDbObjectId idPline; acdbGetObjectId(idPline, en);
  6.   AcDbObjectPointer<AcDbPolyline> pPline(idPline, AcDb::kForRead);
  7.   if (pPline.openStatus() != Acad::eOk)
  8.   {
  9.     acutPrintf(_T("\nError selection pline")); return;
  10.   }
  11.   AcGePoint3d pWcs;
  12.   acdbUcs2Wcs(asDblArray(pUcs), asDblArray(pWcs), false);
  13.   AcGePoint3d pNear;
  14.   pPline->getClosestPointTo(pWcs, pNear);
  15.   double param = 0;
  16.   pPline->getParamAtPoint(pNear, param);
  17.   double dMin = floor(param);
  18.   double dMax = ceil(param);
  19.   int iVertex =
  20.     ((fabs(dMin - param) <  fabs(dMax - param)) ? int(dMin + 1e-6) : int(dMax + 1e-6)) % pPline->numVerts();
  21.   AcGePoint3d pVertexWcs;
  22.   pPline->getPointAt(iVertex, pVertexWcs);
  23.   AcGePoint3d pVertexUcs; acdbWcs2Ucs(asDblArray(pVertexWcs), asDblArray(pVertexUcs), false);
  24.   AcGePoint3d pNewVertexUcs;
  25.   if (acedGetPoint(asDblArray(pVertexUcs), _T("\nNew vertex position: "), asDblArray(pNewVertexUcs)) == RTNORM)
  26.   {
  27.     AcGePoint3d pNewVertexWcs; acdbUcs2Wcs(asDblArray(pNewVertexUcs), asDblArray(pNewVertexWcs), false);
  28.     if (pPline->upgradeOpen() == Acad::eOk)
  29.     {
  30.       AcGePoint3d pEcs;
  31.       acdbWcs2Ecs(asDblArray(pNewVertexWcs), asDblArray(pEcs), asDblArray(pPline->normal()), false);
  32.       pPline->setPointAt(iVertex, AcGePoint2d(pEcs.x, pEcs.y));
  33.     }
  34.   }
  35.   pPline->close();
  36.      
  37.   acedGetPoint(NULL, _T("\nPress Enter to continue: "), asDblArray(pUcs));
  38. }

Вот результат:



Обрати внимание, что штриховка перерисовывается под новый контур только после окончания команды, тогда когда управление передаётся AutoCAD'у. Если тебе это нужно сделать немедленно, то есть только один способ - переделать саму штриховку, т.е. удалить loop контура, добавить новый и выполнить evaluateHatch (практически всё тоже самое, что и при создании новой штриховки).
5
Задачка явно выше уровнем, чем знания автора...
6
Ну возможно еще в коде обновления что-то не то. Например, я обратил внимание, что BlockTable открыт для чтения, а изменение параметров динамического блока приводит к созданию нового анонимного блока, BlockTableRecord которого должен записаться в BlockTable.
Короче говоря поиграйся с заменой OpenMode.ForRead на OpenMode.ForWrite в разных местах у себя. А может стоит заменить обычную транзакцию на эмуляцию транзакции.
7
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от begiz 22-09-2017, 12:25:09 »
код страшненкий,
добавление полилинии обычное
только выбор точек изменен

Код - C++ [Выбрать]
  1.  
  2. AcDbObjectId addToDataBase(AcDbEntity * pEnt, CString BlockTableName, AcDbDatabase * pDwg)
  3. {
  4.         AcDbObjectId oId;
  5.         Acad::ErrorStatus es;
  6.         AcDbBlockTable * pTbl;
  7.         es = acdbOpenObject(pTbl, pDwg->blockTableId(), AcDb::kForRead);
  8.         if (es != Acad::eOk) return NULL;
  9.         AcDbBlockTableRecord * pRec;
  10.  
  11.         es = pTbl->getAt(BlockTableName, pRec, AcDb::kForWrite);
  12.  
  13.         if (es != Acad::eOk)
  14.         {
  15.                 if (es == Acad::eKeyNotFound)
  16.                 {
  17.                         AcDbObjectId newRec;
  18.                         pRec = new AcDbBlockTableRecord();
  19.                         pRec->setName(BlockTableName);
  20.                         pTbl->upgradeOpen();
  21.                         pTbl->add(newRec, pRec);
  22.                         pRec->close();
  23.  
  24.                         es = acdbOpenObject(pRec, newRec, AcDb::kForWrite);
  25.                 }
  26.                 else return NULL;
  27.         }
  28.  
  29.         es = pRec->appendAcDbEntity(oId, pEnt);
  30.         es = pRec->close();
  31.         pTbl->close();
  32.  
  33.         actrTransactionManager->flushGraphics();
  34.         acedUpdateDisplay();
  35.  
  36.         return oId;
  37. }
  38.  
  39. AcDbObjectId createPoint(AcGePoint3d pt)
  40. {
  41.         AcDbObjectPointer<AcDbPoint> pPoint;
  42.         pPoint.create();
  43.         pPoint->setPosition(pt);
  44.         pPoint->setColorIndex(6);
  45.         return addToDataBase(pPoint);
  46. }
  47.  
  48. AcDbObjectId createPolygone()
  49. {
  50.         AcGePoint3d strPt;
  51.         AcGePoint2d endPt;
  52.         AcDbObjectIdArray ptArray;
  53.  
  54.         TCHAR result[8] = { _T("") };
  55.         int rez = RTNORM;
  56.  
  57.         bool multi = false;
  58.         bool first = true;
  59.  
  60.         AcDbObjectPointer<AcDbPolyline> pLine;
  61.         pLine.create();
  62.         pLine->setDatabaseDefaults();
  63.         pLine->setClosed(TRUE);
  64.         AcDbObjectId plineId = addToDataBase(pLine);
  65.         pLine->close();
  66.  
  67.         while (rez != RTCAN)
  68.         {
  69.                 bool can = true;
  70.                 AcDbExtents ext;
  71.                 if (multi)
  72.                 {
  73.                         int rez2 = RTNORM;
  74.                         AcDbObjectIdArray ptArray2;
  75.                         while (rez2 != RTCAN && rez2 != RTKWORD)
  76.                         {
  77.                                 acedInitGet(RSG_OTHER, _T("Single Multi Undo"));
  78.                                 if (first)
  79.                                 {
  80.                                         rez2 = acedGetPoint(NULL, _T("\nSelect Single/Multi/Undo<Multi>:"), asDblArray(strPt));
  81.                                         first = false;
  82.                                 }
  83.                                 else
  84.                                 {
  85.                                         rez2 = acedGetPoint(asDblArray(strPt), _T("\nSelect Single/Multi/Undo<Multi>:"), asDblArray(strPt));
  86.                                 }
  87.                                
  88.                                 if(rez2==RTNORM)
  89.                                 {
  90.                                         can = false;
  91.                                         ext.addPoint(strPt);
  92.                                         ptArray2.append(createPoint(strPt));
  93.                                 }
  94.                         }
  95.  
  96.                         for (int i = 0; i < ptArray2.length(); i++)
  97.                         {
  98.                                 AcDbEntityPointer pEnt(ptArray2.at(i), AcDb::kForWrite);
  99.                                 if (pEnt.openStatus() == Acad::eOk)
  100.                                         pEnt->erase();
  101.                         }
  102.  
  103.                         if(rez2==RTCAN && !can)
  104.                         {
  105.                                 rez = RTNORM;
  106.                         }              
  107.                         else
  108.                                 rez = rez2;
  109.                 }
  110.                 else
  111.                 {
  112.                         acedInitGet(RSG_OTHER, _T("Single Multi Undo"));
  113.                         if (first)
  114.                         {
  115.                                 rez = acedGetPoint(NULL, _T("\nSelect Single/Multi/Undo<Single>:"), asDblArray(strPt));
  116.                                 first = false;
  117.                         }
  118.                         else
  119.                         {
  120.                                 rez = acedGetPoint(asDblArray(endPt), _T("\nSelect Single/Multi/Undo<Single>:"), asDblArray(strPt));
  121.                         }
  122.                         if(rez==RTNORM)
  123.                                 ext.addPoint(strPt);
  124.                 }
  125.  
  126.                 switch (rez)
  127.                 {
  128.                 case RTCAN: break;
  129.                 case RTNORM:
  130.                 {
  131.                         endPt = AcGePoint2d((ext.maxPoint().x + ext.minPoint().x) / 2,
  132.                                                                 (ext.maxPoint().y + ext.minPoint().y) / 2);
  133.                         pLine.open(plineId, AcDb::kForWrite);
  134.                         if (pLine.openStatus() == Acad::eOk)
  135.                         {
  136.                                 pLine->addVertexAt(pLine->numVerts(), endPt);
  137.                                 pLine.close();
  138.                                 ptArray.append(createPoint(AcGePoint3d(endPt.x,endPt.y,0)));
  139.                                 actrTransactionManager->flushGraphics();
  140.                                 acedUpdateDisplay();
  141.                         }
  142.                         break;
  143.                 }
  144.                 case RTKWORD:
  145.                 {
  146.                         if (acedGetInput(result) == RTNORM)
  147.                         {
  148.                                 if (_tcscmp(result, _T("Multi")) == 0)
  149.                                         multi = true;
  150.                                 if (_tcscmp(result, _T("Single")) == 0)
  151.                                         multi = false;
  152.                                 if (_tcscmp(result, _T("Undo")) == 0)
  153.                                 {
  154.                                         pLine.open(plineId, AcDb::kForWrite);
  155.                                         if(pLine.openStatus()==Acad::eOk && pLine->numVerts()>0)
  156.                                         {
  157.                                                 pLine->removeVertexAt(pLine->numVerts() - 1);
  158.                                                 pLine->getPointAt(pLine->numVerts() - 1, endPt);
  159.                                                 pLine.close();
  160.                                                 AcDbEntityPointer pEnt(ptArray.last(), AcDb::kForWrite);
  161.                                                 if (pEnt.openStatus() == Acad::eOk)
  162.                                                         pEnt->erase();
  163.                                         }
  164.                                         actrTransactionManager->flushGraphics();
  165.                                         acedUpdateDisplay();
  166.                                 }
  167.                         }
  168.                         break;
  169.                 }
  170.                 default:
  171.                         break;
  172.                 }
  173.         };
  174.  
  175.         pLine.open(plineId, AcDb::kForWrite);
  176.         if (pLine.openStatus() == Acad::eOk)
  177.         {
  178.                 if (pLine->numVerts() < 3)
  179.                         pLine->erase();        
  180.  
  181.                 pLine->close();
  182.                 actrTransactionManager->flushGraphics();
  183.                 acedUpdateDisplay();
  184.         }
  185.  
  186.         for (int i=0; i < ptArray.length(); i++)
  187.         {
  188.                 AcDbEntityPointer pEnt(ptArray.at(i), AcDb::kForWrite);
  189.                 if (pEnt.openStatus() == Acad::eOk)
  190.                         pEnt->erase();
  191.         }
  192.  
  193.         return plineId;
  194. }
  195.  
  196. AcDbObjectId createHatch(AcDbObjectId oId)
  197. {
  198.         AcDbObjectPointer<AcDbHatch> pHatch;
  199.         pHatch.create();
  200.         // Set hatch plane
  201.         AcGeVector3d normal(0.0, 0.0, 1.0);
  202.         pHatch->setDatabaseDefaults();
  203.         pHatch->setNormal(normal);
  204.         pHatch->setElevation(0.0);
  205.         pHatch->setPatternScale(5);
  206.         // Set hatch pattern to ANSI31 predefined type //
  207.         pHatch->setPattern(AcDbHatch::kPreDefined, _T("SOLID"));
  208.         // Set Associativity
  209.         pHatch->setAssociative(Adesk::kTrue);
  210.         // Construct database AcDbLines
  211.         AcDbObjectId hatchId;
  212.         AcDbObjectIdArray dbObjIds;
  213.         dbObjIds.append(oId);
  214.         // Append an external rectangular loop to hatch boundary //
  215.         pHatch->appendLoop(AcDbHatch::kExternal, dbObjIds);
  216.  
  217.         // Elaborate hatch lines
  218.         pHatch->evaluateHatch();
  219.         // Get all associative source boundary object Ids for later use.
  220.         dbObjIds.setLogicalLength(0);
  221.         pHatch->getAssocObjIds(dbObjIds);
  222.         // Post hatch entity to database
  223.         hatchId = addToDataBase(pHatch);
  224.         // Attach hatchId to all source boundary
  225.         // objects for notification.
  226.         AcDbEntity *pEnt;
  227.         int numObjs = dbObjIds.length();
  228.         for (int i = 0; i < numObjs; i++)
  229.         {
  230.                 if (acdbOpenAcDbEntity(pEnt, dbObjIds[i],AcDb::kForWrite) == Acad::eOk)
  231.                 {
  232.                         pEnt->addPersistentReactor(hatchId);
  233.                         pEnt->close();
  234.                 }
  235.         }
  236.         return hatchId;
  237. }
  238.  
  239. //from modal dialog
  240. BeginEditorCommand();
  241. plineId = createPolygone();
  242. CompleteEditorCommand();
  243. if (plineId.isValid() && !plineId.isErased() && !plineId.isNull())
  244. {
  245. hatchId = createHatch(plineId);
  246. }
  247.  
  248.  
8
AutoCAD .NET API / Re: Изменить файл не открывая AutoCAD
« Последний ответ от Serg34 22-09-2017, 12:24:11 »
Спасибо большое.
По примеру сделал так:
Код - C# [Выбрать]
  1. private static void AccessGlobalFromFile(...)
  2. {
  3.         Document doc = Application.DocumentManager.MdiActiveDocument;
  4.         if (doc == null) return;
  5.  
  6.         Editor ed = doc.Editor;
  7.         using (Database db = new Database(false, true))
  8.         {
  9.                 db.ReadDwgFile(autoCADFilePath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
  10.                 Database prevDb = HostApplicationServices.WorkingDatabase;
  11.                 HostApplicationServices.WorkingDatabase = db;
  12.  
  13.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  14.                 {
  15.                         ...
  16.                         tr.Commit();
  17.                 }
  18.                 HostApplicationServices.WorkingDatabase = prevDb;
  19.                 db.SaveAs(db.OriginalFileName, true, db.OriginalFileVersion, db.SecurityParameters);
  20.         }
  21. }
Эффект тот же(
Попробую еще с открытым файлом - может, если программно блоки редактировать, то не будет fatal error
9
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от Александр Ривилис 22-09-2017, 12:16:47 »
Смогу посмотреть только вечером. Пока покажи код которым добавляешь полилинию, штриховку и делаешь её ассоциативной.
10
ObjectARX / Re: обновить ассоциативный AcDbHatch
« Последний ответ от begiz 22-09-2017, 12:13:24 »
да, и AcDbPolyline и AcDbHatch в базе.
добавил, команда закончилась, подергал полилинию - всё обновляется.
вызвал другую команду, которая должна Vertex полинии подвинуть, он подвинулся, а Hatch не обновился
Страницы: [1] 2 3 ... 10