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

ADN Club => ObjectARX => Тема начата: Николай Горлов от 04-12-2013, 13:23:32

Название: вставка блоков
Отправлено: Николай Горлов от 04-12-2013, 13:23:32
даже не знаю в чем дело. короче говоря, ситуация такая (упрощенно :) )
есть окошко с кнопочками. за каждой кнопочкой закреплена вставка соответствующего блока (блок может быть динамическим).
сами блоки находятся в файле, например, c:\aaa\data.dwg, ну и естественно имеют уникальные имена.
по нажатию на кнопочку отрабатывает функция
drawSign(_T("динблок1"),_T("C:\\aaa\\data.dwg"),0.2); //динблок1 - имя блока, C:\\aaa\\data.dwg - в каком файле искать блок, 0.2 - масштаб

за этой функцией скрывается следующее:
Код - C++ [Выбрать]
  1. AcDbObjectId importBlockToCurDWGDatabase(const ACHAR *pBlockName, const ACHAR *pFileName)
  2. {
  3.         Acad::ErrorStatus es=Acad::eOk;
  4.         AcDbObjectId idImported; // ID нашего нового блока
  5.         AcDbDatabase* pWorkDatabase = acdbHostApplicationServices()->workingDatabase();
  6.         AcAxDocLock docLock(pWorkDatabase);
  7.         AcDbDatabase* pBlockDatabase = new AcDbDatabase(false,true);
  8.         es = pBlockDatabase->readDwgFile(pFileName);
  9.         if(es!=Acad::eOk){delete pBlockDatabase;return NULL;}
  10.        
  11.         try
  12.         {
  13.                 AcDbBlockTable* pBlockTable;
  14.                 es=pBlockDatabase->getSymbolTable(pBlockTable,AcDb::kForRead);
  15.                 if(es!=Acad::eOk){delete pBlockDatabase;return NULL;}
  16.          
  17.                 AcDbObjectId idInsRecord;      
  18.                 es=pBlockTable->getAt(pBlockName,idInsRecord);
  19.                 pBlockTable->close();
  20.                 if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // нет такого блока
  21.          
  22.                 AcDbDatabase* pTempDB;
  23.                 es=pBlockDatabase->wblock(pTempDB,idInsRecord);
  24.                 if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // не скопировался блок в пустую базу
  25.          
  26.                 es=pWorkDatabase->insert(idImported,pBlockName,pTempDB);
  27.                 delete pTempDB;
  28.                 if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // не вставилась пустая база с блоком в нашу текущую базу
  29.         }catch(...){delete pBlockDatabase;return NULL;}
  30.  
  31.         delete pBlockDatabase;
  32.         return idImported;
  33. }
  34.  
  35. void drawSign(CString blockName, CString blockFilePath, double scale)
  36. {
  37.         AcDbObjectId newBlockTableId;
  38.         AcGePoint3d insPnt;
  39.  
  40.         acdbHostApplicationServices()->enableMessageDisplay(false);
  41.         newBlockTableId = importBlockToCurDWGDatabase(blockName.GetString(),blockFilePath.GetString());
  42.         acdbHostApplicationServices()->enableMessageDisplay(true);
  43.         if (newBlockTableId.isNull())
  44.         {
  45.                 acedAlert(_T("Данный блок не найден"));
  46.                 return;
  47.         }
  48.        
  49.         acedCommand(RTSTR,_T("_ucsicon"),RTSTR,_T("_off"),0); // значек СК
  50.         acedCommand (RTSTR, _T("_ucs"),RTSTR,_T("_v"),0);
  51.         AcDbDatabase* pWorkDatabase = acdbHostApplicationServices()->workingDatabase();
  52.         AcAxDocLock docLock(pWorkDatabase);
  53.  
  54.         int osnap = acdbHostApplicationServices()->workingAppSysvars()->osmode();
  55.         acdbHostApplicationServices()->workingAppSysvars()->setOsmode(64 + 512);
  56.         if(acedGetPoint(NULL,_T("\nТочка вставки: "),asDblArray (insPnt))!=RTNORM)
  57.         {
  58.                 acdbHostApplicationServices()->workingAppSysvars()->setOsmode(osnap);
  59.                 acedCommand(RTSTR,_T("_ucs"),RTSTR,_T("_p"),0);
  60.                 acedCommand(RTSTR,_T("_ucsicon"),RTSTR,_T("_on"),0);
  61.                 return;
  62.         }
  63.  
  64.         AcDbBlockReference *blockReference = new AcDbBlockReference(insPnt,newBlockTableId);
  65.         blockReference->setRotation(0.0);
  66.         blockReference->setNormal (AcGeVector3d (0.0, 0.0, 1.0)) ;
  67.         blockReference->setScaleFactors(AcGeScale3d(scale));
  68.         AcGeMatrix3d matUcs;
  69.         acedGetCurrentUCS(matUcs);
  70.         blockReference->transformBy(matUcs);
  71.         postToDb(blockReference); // запись экзкмпляра блока в БД чертежа
  72.  
  73.         acdbHostApplicationServices()->workingAppSysvars()->setOsmode(osnap);
  74.         acedCommand(RTSTR,_T("_ucs"),RTSTR,_T("_p"),0);
  75.         acedCommand(RTSTR,_T("_ucsicon"),RTSTR,_T("_on"),0);
  76.         acedPostCommandPrompt();
  77. }
  78.  

если вставлять блоки в чертеж через drawSign (т.е. нажимать кнопочку), то вставляются всегда хорошо, но пользователи люди ... и им намного "проще" найти нужный блок в одном из их чертежей, а не клацнуть на кнопочку. после того как они его находят в куче своих чертежей, они Ctrl+C\Ctrl+V блок в новый чертеж. и, о чудо, у некоторых блоков умирает порядок прорисовки и после вставки вместо правильно начерченного блока получается мешанина отрезков и штриховок.
пробовал повторить сам ручками. картина та же. при вставке с кнопочки всегда все ok, а вот при копировании (причем без разницы в новый чертеж или в тот же) порядок прорисовки игнорируется.

может что-то не так с моим кодом? дело в том, что если ручками открыть файл C:\aaa\data.dwg, вставить туда этот блок (вставка->блок. блоков в самом чертеже нет. они только в БД чертежа), а потом скопировать его в буфер, то в другие чертежи (если там еще не было вхождения такого блока) всё вставляется правильно.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 04-12-2013, 13:45:56
Проверь копируется ли у тебя связанная с AcDbBlockTableRecord AcDbSortentsTable (отвечает за порядок прорисовки). Она содержится в ExtDictionary у AcDbBlockTableRecord с ключом "ACAD_SORTENTS". Если нет, то тебе придётся её самостоятельно скопировать.
Название: Re: вставка блоков
Отправлено: Николай Горлов от 04-12-2013, 14:15:40
пробежался arxdbg. взял правильно отрисованный блок и неправильно. результаты одинаковые
- на самом ВСТАВЛЕННОМ блоке (Entity Info) в Extension dictionary только AcDbBlockRepresentation
- в database \ BlockTable \ имя_блока в Extension dictionary есть ACAD_SORTENTS, ACAD_ENHANCEDBLOCK и AcDbDynamicBlockRoundTripPurgePrevent
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 04-12-2013, 14:59:53
результаты одинаковые
1) Одинаково и содержимое AcDbSortentsTable?
2) Такое происходит только с динамическими блоками?
3) Такое происходит в трёх последних версиях AutoCAD?
Если удастся всё это формально записать с минимальным примером кода (проект) и dwg-файла с блоками - будем трясти ADN DevHelp
Название: Re: вставка блоков
Отправлено: Николай Горлов от 04-12-2013, 18:42:24
1. ну в пределах допустимого. блоки то разные ), так что handle, owner и entity name - разные
2. за простые ничего сказать не могу (простых почти нет :), а на те что есть никто не жаловался). так что будем считать, что только динамические.
3. начиная с 2010 акада по 2014. чтоб все работало начиная с 2010 автокада, версия файла с блоками - 2010.
4. еще иногда слетает динамика после копирования. допустим есть столбики, которые идут массивом при растяжке. вставили через "кнопочку", потянули, все ок. скопировали, вставили рядом через Ctrl+C\Ctrl+V. потянули, а остается только первый столбик, хотя точка растяжки уходит туда, куда клацнул (у меня dwg файлика нет. нада скататься взять. но видел собственными глазами). и самое интересное, происходит это ТОЛЬКО с редактируемым экземпляром блока. столбики в остальных экземпляров блока находятся там где и должны и после регенерации. а вот если начать растягивать и другие подобные блоки, то такой же косяк происходит и на них.

PS: а проектик подготовлю, это не проблема. только на следующей неделе. сейчас весь в разъездах )))

Цитировать
будем трясти ADN DevHelp
ну да, ток исправлять то ЭТО в 2010 автокаде никто не будет, если это баг. а пользуются уже сейчас. эх, опять заплатки делать ))). так что ооочень сильно надеюсь, что это я что-то намудрил

а пока что dwg с блоком. можете попробовать его скопировать в новый чертеж средствами автокада. у меня штриховка всегда идет на передний план. хотя про копировании внутри одного чертежа все ок.
http://yadi.sk/d/9vhcJ2BaDnjKE (http://yadi.sk/d/9vhcJ2BaDnjKE)
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 05-12-2013, 02:13:58
а пока что dwg с блоком. можете попробовать его скопировать в новый чертеж средствами автокада. у меня штриховка всегда идет на передний план. хотя про копировании внутри одного чертежа все ок.
Это я подтверждаю (AutoCAD 2014 SP1). Интересно теперь посмотреть на исходный файл с блоком, для которого этот баг не воспроизводится и посмотреть разницу между блоками.

Обрати внимание на эти два рисунка. Сначала я выяснил метку штриховки в блоке - 426, затем стал искать её в таблице SORTENTS - она там есть, но где-то в середине, что очень странно. По логике она должна быть или в начале или в конце.
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg689.imageshack.us%2Fimg689%2F6469%2Fx31d.png&hash=836eda73a8457f4a8f31784636f64d13)

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg18.imageshack.us%2Fimg18%2F8356%2Fqmao.png&hash=ca1b7e4f5940ab8b17516b40db6aa3a0)

Если же я копирую через буфер обмена в другой чертеж, то я получаю метку штриховки 249, а в SORTENTS для этого блока метки 249 нет вообще. В ней все метки очень удачно оказались двузначные. У меня создалось впечатление, что уже в dynblock.dwg SORTENTS для блока некорректная, т.е. метки ссылаются не на те примитивы. Ну а потом при копировании происходит трансляция меток, которая всё портит окончательно.

Название: Re: вставка блоков
Отправлено: Николай Горлов от 06-12-2013, 13:21:46
Увы, врядли я найду исходный файл с блоком. Могу описать механизм. Вручную рисуются куча блоков разными людьми в разных файлах. Потом программно они просто копируются из тех файлов в один наш.
копируются функцией (но конкретно эта функция ни на что не влияет, т.к. непосредственно в ней идут только проверки):
Код - C++ [Выбрать]
  1. int importBlockToSheetDWG(const ACHAR *pBlockName, const ACHAR *pBlockFile, const ACHAR *pSheetDWGFile)
  2. //pBlockName - имя блока, pBlockFile - файл из которого будем его брать, pSheetDWGFile - файл в который этот блок нужно скопировать
  3. {
  4.         Acad::ErrorStatus es=Acad::eOk;
  5.         AcDbDatabase* pWorkDatabase = acdbHostApplicationServices()->workingDatabase();
  6.         AcDbDatabase* pSheetDatabase = new AcDbDatabase(false,true);
  7.         AcAxDocLock docLock(pSheetDatabase);
  8.         es = pSheetDatabase->readDwgFile(pSheetDWGFile);
  9.         if(es!=Acad::eOk){delete pSheetDatabase;return 0;}
  10.  
  11.         AcDbBlockTable* pBlockTable;
  12.         es=pSheetDatabase->getSymbolTable(pBlockTable,AcDb::kForRead);
  13.         if(es!=Acad::eOk){delete pSheetDatabase;return NULL;}
  14.  
  15.         AcDbObjectId idInsRecord;      
  16.         es=pBlockTable->getAt(pBlockName,idInsRecord);
  17.         pBlockTable->close();
  18.         if(es==Acad::eOk){delete pSheetDatabase;return 2;} // такой блок уже есть. перезаписывать не нужно
  19.  
  20.         acdbHostApplicationServices()->setWorkingDatabase(pSheetDatabase);
  21.         acdbHostApplicationServices()->enableMessageDisplay(false);
  22.         AcDbObjectId iId = importBlockToCurDWGDatabase(pBlockName, pBlockFile);
  23.         acdbHostApplicationServices()->enableMessageDisplay(true);
  24.         acdbHostApplicationServices()->setWorkingDatabase(pWorkDatabase);
  25.         if (!iId.isNull())
  26.         { // сохраняем в формате 2010 акада
  27.                 pSheetDatabase->saveAs(pSheetDWGFile,true,AcDb::kDHL_1024);
  28.         }
  29.         delete pSheetDatabase;
  30.         if (!iId.isNull()) return 1;
  31.         else return 0;
  32. }
  33.  

реализация importBlockToCurDWGDatabase - в моем первом посте.
так что во всем процессе участвуют три мои функции:
- importBlockToCurDWGDatabase
- importBlockToSheetDWG
- drawSign

и автокадовский динамический блок, созданный в голом автокаде без каки-либо дополнительных средств.

и если предположить, что автокадовский блок автокадом создавался правильно :):):), то проблема в одной из моих функций.

просто иногда достаточно если отрисовка идет без учета сортировки просто открыть акадом наш файл, вставить блочек внутри него, зайти в его редакторование и поставить штриховку принудительно еще раз на задний план. потом сохранить чертеж, закрыть его. и проблема может исчезнуть. но дело в том, что может и НЕ исчезнуть. в общем на следующей неделе постараюсь смастерить демо проектик и найти dwg с блоком, который в исходном состоянии работает, а после пробега трех функций начинает чудесить :).
ну и еще интересно, если баг в моих функциях, почему неправильно рисуются не все блоки (уже больше 1000 шт., так что точного количества не знаю) а только некоторые из них? чудеса :):):)
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 06-12-2013, 20:20:06
в общем на следующей неделе постараюсь смастерить демо проектик и найти dwg с блоком, который в исходном состоянии работает, а после пробега трех функций начинает чудесить :)
Давай. А то как видишь без поллитры (т.е. dwg-файла и проекта) с этим делом не разобраться.  Как-то с этой таблицей сортировки совсем непонятно ;)
Название: Re: вставка блоков
Отправлено: Николай Горлов от 09-12-2013, 13:48:51
и так. вроде бы все получилось
http://yadi.sk/d/NY3SHnKtDzxeN (http://yadi.sk/d/NY3SHnKtDzxeN)
dwg нада кинуть в корень диска С (по умолчанию, если не редактировать пути в проекте).
в проекте 2 команды.
первая - выдерает блок из файла blockfile.dwg и копирует его в c:\mydwg.dwg (файл создается, .если его нет по указанному пути)
вторая - вставляет блок из mydwg.dwg в чертеж

PS: блок в файле blockfile лежит хороший. проверил. вставляется нормально в любой чистый чертеж правильно. после копирования его в mydwg в чертеж командой вставляется правильно, но если его там скопировать ручками и утянуть в другой чертеж, то штриховка вылазит на передний план.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 09-12-2013, 19:14:43
блок в файле blockfile лежит хороший. проверил. вставляется нормально в любой чистый чертеж правильно.
Неа. Я скопировал этот блок вручную (через буфер обмена) в другой чертеж - штриховка вылетела наверх. Метка у штриховки в исходном чертеже - 426 (в SORTENTS я такую метку не нашел)
Потом внутри блока отправил штриховку вниз, сохранил блок и выполнил сброс блока - метка у штриховки поменялось на 5FD (в SORTENTS метка появилась), но это не помогло - штриховка упрямо вылезала наверх.
Дальше я сделал такой эксперимент. Удалили для этого блока SORTENTS и отправил штриховку вниз. После этого этот блок нормально (вручную) скопировался в новый чертеж.
Осталось проверить с твоей программой.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 09-12-2013, 20:10:24
Проверил с твоей программой (уточняю - проверял в AutoCAD 2014 SP1 x86). Блок вставился нормально и так же нормально скопировался в новый пустой чертеж.
Прикладываю твой проект (я его немного обанглоязычил на случай передачи в ADN DevHelp) и чертеж с блоком.

P.S.: Кстати, когда архивируешь проект - не забывай выходить из VS
Название: Re: вставка блоков
Отправлено: Николай Горлов от 10-12-2013, 12:32:13
Цитировать
Неа. Я скопировал этот блок вручную (через буфер обмена) в другой чертеж - штриховка вылетела наверх
как это ни смешно звучит, но после этих слов и я проверил. и у меня тоже штриховка вылетела на передний план. хотя до этого три раза проверял переоткрывая автокад и всё было ок. а сегодня перегрузил компьютер )))
сегодня новые чудеса. взял и переименовал mydwg в blockfile и выполнил свои две команды (пересоздал mydwg и вставил блок в файл) тестового проекта. блок начал вставляться простым копированием правильно в любой чертеж.

Цитировать
Проверил с твоей программой (уточняю - проверял в AutoCAD 2014 SP1 x86). Блок вставился нормально и так же нормально скопировался в новый пустой чертеж.
говоря проще, моя программная часть тут не при чем. так? всё зависит от начальной корявости блока, созданного самим автокадом? если это так, то есть ли способ (не очень болезненный :) ) исправлять корявые блоки "на лету" перед затягиванием их в mydwg?

PS:
Цитировать
на случай передачи в ADN DevHelp
на них то у меня надежды мало. не так сильно я с ними дружу :):):). :) уберу ка я всё лишнее
так что заплатки, заплатки и еще раз заплатки.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 10-12-2013, 15:07:51
говоря проще, моя программная часть тут не при чем. так? всё зависит от начальной корявости блока, созданного самим автокадом?
Похоже что именно так.
всё зависит от начальной корявости блока, созданного самим автокадом? если это так, то есть ли способ (не очень болезненный :) ) исправлять корявые блоки "на лету" перед затягиванием их в mydwg?
Ну в данном случае корявость была в SORTENTS. Можно конечно её попытаться поправить на лету если сможешь понять что в ней не так. То есть проделать эти же операции вручную.
но на них то у меня надежды мало
В данном случае если бы я сам не нашел причину ошибки, то отправил в ADN DevHelp и рассчитывал бы не на исправление бага, а на workaround, который бы получил от команды инженеров.
P.S.: Обсуждать работу ADN DevHelp на этом форуме мы не будем - читай справа вверху в шапке форума при чьей поддержке этот форум функционирует. 
Название: Re: вставка блоков
Отправлено: Николай Горлов от 10-12-2013, 16:22:34
:( а DevHelp то у меня не работает, и как вспоминаю уже давненько. помню, пытался настроить, но плюнул.
Account Is Not Linked to an Active Subscription Contract и всё. дальше не пускает. пробовал и с adn-овского аккаунта и с автодесковского форумного. так что workaround (танец с бубном) будет мучительно долгим
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 10-12-2013, 16:49:09
а DevHelp то у меня не работает
По этому поводу как исправить напишу в личку.
Но вообще-то этот форум создан как раз для того, чтобы мы (Администрация) брали на себя в случае, когда сами не можем помочь, функцию передачи вопросов в ADN DevHelp.
Название: Re: вставка блоков
Отправлено: Николай Горлов от 10-12-2013, 18:24:58
угу. вернемся к блоку :)
в функции importBlockToCurDWGDatabase блок по имени берется из пользовательского чертежа и вставляется в наш (только в БД, чертежик остается пустым). делается это чтоб ничего не потерялось :):):), т.к. файлов может быть куча и искать где что лежит долго, да и сам то пользовательский файл может быть переименован или удален. короче говоря причины не важны.
в итоге проблема делится на 2 части:
1. избежать вставки "корявых" блоков в наш файлик. в идеале, не просто сказать, что блок корявый и вставлять мы его отказываемся, а вставить уже исправленный "на лету" вариант. тут скорей всего ковырять нужно функцию importBlockToCurDWGDatabase перед строкой
es=pWorkDatabase->insert(idImported,pBlockName,pTempDB); чтоб в pTempDB был уже хороший блок.
2. собственно говоря, уже много-много блоков есть и ими пользуются. значит нужно еще исправить "корявости" всех блоков файла mydwg.dwg
но с этим пробем быть не должно, если получится сделать пункт 1.

в основном содержимое блока:
1:N штриховок (по идее все на заднем плане, но могут и перекрывать друг друга. всё зависит от усидчивости человека, который блоки рисует и от того, насколько удобно залить участок внутри блока цветом, отличным от фона всего блока и наоборот, насколько удобно залить весь фон исключив островок другого цвета. часто просто заливают фон по контуру, а внутренности штришуют поверх)
1:N полилиний, дуг, окружностей и т.п. с\без глобальной толщиной или разными весами. (чем толще, тем ниже в стопке находится (чтоб гарантированно было видно тонкие линии))
о, еще ж используется стиль печати, чтоб было веселей. синие линии будут жирными черными, а голубые - тонкими черными :):):).
ну и компоненты отвечающие за динамику (растяжки, массивы и т.п)

Цитировать
Удалили для этого блока SORTENTS и отправил штриховку вниз. После этого этот блок нормально (вручную) скопировался в новый чертеж
а динамика на блоке работает? :):):)

я подозреваю что нет. и вот тут самый главный вопрос. если я тупо поудаляю штриховки и потом их пересоздам и кину на задний план программно, то врядли они станут себя хоть как-то вести при тягании динамических ручек. ну, например, есть столбик, который массивом тянется на большое расстояние. потянули, получили забор. штриховка как и контур штриховки участвуют в динамической операции. а если я грохну штриховку и пересоздам ее, это ж уже будет совсем другая штриховка, о которой динамическая операция знать ничего не будет. следовательно, при растяжке, только первый столбик будет заштрихован, а остальной забор будет только контурным.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 10-12-2013, 18:29:59
а динамика на блоке работает?
А самому проверить? ;-) Я же приложил исправленный файл-блок.
если я тупо поудаляю штриховки и потом их пересоздам и кину на задний план программно
Зачем штриховки пересоздавать? Удали SORTENTS и кинь все штриховки назад. Этого по логике должно быть достаточно.
Название: Re: вставка блоков
Отправлено: Николай Горлов от 23-12-2013, 16:19:40
удалю предыдущий пост. значит код в итоге получился такой
Код - C++ [Выбрать]
  1. // вставить после строки if(es!=Acad::eOk){delete pBlockDatabase;return NULL;}
  2. //->////////////////////////////////////////////////////////////////////////////////////////////////
  3. // заплатка ////////////////////////////////////////////////////////////////////////////////////////
  4. // в pWorkDatabase найти этот блок, убить sortents, найти все штриховки и кинуть их на задний план
  5. AcDbBlockTableRecordPointer pBadBlockRecord(pBlockName,pWorkDatabase,AcDb::kForRead);
  6. if ((es = pBadBlockRecord.openStatus()) != Acad::eOk) return NULL;
  7. //-> а теперь ищем все штриховки
  8. AcDbObjectIdArray hatchArray; hatchArray.removeAll();
  9. AcDbBlockTableRecordIterator *iter = NULL;  
  10. if ((es = pBadBlockRecord->newIterator(iter)) != Acad::eOk) return NULL;
  11. AcDbObjectId eId;
  12. for (;!iter->done(); iter->step())
  13. {
  14.         if (iter->getEntityId(eId) == Acad::eOk)
  15.         {
  16.                 AcDbObjectPointer<AcDbHatch> pHatch(eId,AcDb::kForRead);
  17.                 if ((es = pHatch.openStatus ()) == Acad::eOk)
  18.                         hatchArray.append(eId);
  19.         }
  20. }
  21. delete iter;
  22. //<-
  23. bool needReCreate = false;
  24. if (!hatchArray.isEmpty())
  25. {
  26.         AcDbSortentsTable *pSortTable;
  27.         es = pBadBlockRecord->getSortentsTable(pSortTable,AcDb::kForRead);
  28.         if (es == Acad::eOk)
  29.         {
  30.                 for (int i = 0; i < hatchArray.length(); i++)
  31.                 {
  32.                         AcDbHandle handle;
  33.                         Adesk::Boolean resHasHatch;
  34.                         resHasHatch = pSortTable->sortAs(hatchArray.at(i),handle);
  35.                         if (resHasHatch == Adesk::kFalse)
  36.                         {
  37.                                 needReCreate = true;
  38.                                 break;
  39.                         }
  40.                 }
  41.                 pSortTable->close();
  42.         }
  43. }
  44.  
  45. if (needReCreate)
  46. {
  47.         //-> словарь удалим через extensionDictionary. так проще, чем через getSortentsTable
  48.         AcDbObjectId extDictId = pBadBlockRecord->extensionDictionary();
  49.         if (extDictId.isNull()){return NULL;}
  50.         AcDbDictionaryPointer pObjectDictionary(extDictId,AcDb::kForWrite);
  51.         if (pObjectDictionary.openStatus() != Acad::eOk) {return NULL;}
  52.         AcDbDictionaryIterator* pDictIter;
  53.         pDictIter= pObjectDictionary->newIterator();
  54.         for (; !pDictIter->done(); pDictIter->next())
  55.         {
  56.                 AcDbObjectId idXrec;
  57.                 CString tmpStr = pDictIter->name();
  58.                 if (tmpStr.CompareNoCase(_T("ACAD_SORTENTS")) == 0)
  59.                 {
  60.                         if ((es = pObjectDictionary->remove(tmpStr)) != Acad::eOk)
  61.                         {
  62.                                 continue;
  63.                         }
  64.                         break;
  65.                 }
  66.         }
  67.         pObjectDictionary->close();
  68.         delete pDictIter;
  69.         //<-
  70.         if (!hatchArray.isEmpty())
  71.         {
  72.                 AcDbSortentsTable *pSortTable;
  73.                 pBadBlockRecord->getSortentsTable(pSortTable,AcDb::kForWrite,true);
  74.                 pSortTable->moveToBottom(hatchArray);
  75.                 pSortTable->close();
  76.         }
  77. }
  78. //<-////////////////////////////////////////////////////////////////////////////////////////////////
в итоге. вроде все рисует правильно. и позволяет копипастом переносить блок в другой чертеж, сохраняя штриховку на заднем плане, НО, кусок кода функции importBlockToCurDWGDatabase, которая используется и для перетягивания штриховок в мой файл и в чертеж, где идет проверка на существование штриховки в AcDbSortentsTable выдает, что штриховки нет ни в корявом блоке (blockfile.dwg), ни в файле с уже якобы исправленной штриховкой (mydwg.dwg), хотя я пересоздаю словарь sortents и сохраняю dwg.
и еще. если взять блок их файла mydwg.dwg (там его вставить и перетянуть в другой файл), то sortents у этого блока почти пустой и там нет никаких упоминаний о штриховке, хоть и рисует правильно :):):), а если вставить блок через мою команду, то sortents большая (подозреваю, что там все объекты блока), упоминание о штриховке есть (ближе к началу таблицы).
короче говоря, механизмы видать разные для вставки, ну да ладно. вопрос в том, почему при вставке блока из МОЕГО файла функция pSortTable->sortAs() говорит, что штриховку я так и не добавил, хотя при просмотре arxdbg штриховка есть. и вообще, можно ли пользоваться sortAs, если в описании говорится, что из-за своих внутренних алгоритмов результат не может быть надежным (сказочная функция).
есть еще другая функция - getSortHandle. такая же сказочная :):):). но, если певая всегда говорит, что штриховки нет, то вторая всегда говорит, что штриховка есть даже в корявом блоке :):):).
может есть какой-то надежный способ, не ковыряя словарь вручную через resbuf, получить правдивую информацию о том, есть ли штриховка в таблице сортировки или нет. а то как-то неправильно будет все-все блоки переделывать.
----------------------------------------------------------------------------------------------------------------
продолжил ковыряться.
Код - C++ [Выбрать]
  1. if (!hatchArray.isEmpty())
  2. {
  3.         AcDbSortentsTable *pSortTable;
  4.         es = pBadBlockRecord->getSortentsTable(pSortTable,AcDb::kForRead);
  5.         if (es == Acad::eOk)
  6.         {
  7.                 AcDbObjectIdArray idsDrawOrder;idsDrawOrder.removeAll();
  8.                 pSortTable->getFullDrawOrder(idsDrawOrder);
  9.  
  10.                 for (int i = 0; i < hatchArray.length(); i++)
  11.                 {
  12.                        
  13.                         if (!idsDrawOrder.contains(hatchArray.at(i)))
  14.                         {
  15.                                 needReCreate = true;
  16.                                 break;
  17.                         }
  18.                 }
  19.                 pSortTable->close();
  20.         }
  21. }
  22.  
взял всю таблицу сортировки и проверил наличие в ней моей злополучной штриховки. таки она там есть, так что getSortHandle была права. то я просто глазками не досмотрел в списке сортировки.
так что ж тогда получается. штриховка есть в блоке, штриховка есть в таблице сортировки даже в изначально корявом блоке. проверить правильная или неправильная штриховка в конкретном блоке (ну рассматриваем тот, который есть) нельзя не посмотрев на него глазами после вставки в чертеж копипастом, а ставить штриховку на задний план всех-всех блоков убивая при этом сортировку всех остальных элементов блока ... ну как-то совсем не правильно.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 23-12-2013, 20:17:37
я то вроде как доволен результатом
Вот это главное!
прям Новый год какой-то.
С Наступающим!
Название: Re: вставка блоков
Отправлено: Николай Горлов от 24-12-2013, 12:08:49
Цитировать
С Наступающим!
пасибки. и Вам того же :)
а как быть с этим?
Цитировать
так что ж тогда получается. штриховка есть в блоке, штриховка есть в таблице сортировки даже в изначально корявом блоке. проверить правильная или неправильная штриховка в конкретном блоке (ну рассматриваем тот, который есть) нельзя не посмотрев на него глазами после вставки в чертеж копипастом, а ставить штриховку на задний план всех-всех блоков убивая при этом сортировку всех остальных элементов блока ... ну как-то совсем не правильно.
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 24-12-2013, 13:27:53
Николай. Блок изначально неправильный. Как и почему это произошло - сейчас уже не установишь. Так что единственный способ - пересоздать таблицу сортировки. Ничего другого я придумать не могу. Подозреваю, что если я отправлю эту проблему в ADN DevHelp, то они (в лучшем случае) предложат этот же вариант. Хочешь проверить?
Название: Re: вставка блоков
Отправлено: Николай Горлов от 24-12-2013, 14:05:03
да отправить я и сам могу, пусть подулючаются. может на пьяную голову какая интересная идейка прийдет :):):). кстати, только что закончил подготовку проекта на отправку. доступ то мне починили, хоть и через ж..., но это отдельный разговор :)

основная проблема заключается в том, что эти блоки создаются в ГОЛОМ автокаде, и он, такой нехороший как-то их ломает. блоков больше 1000, а поломанных даже не знаю сколько, и из-за чего они ломаются. вручную все подряд перетряхивать ну, мягко говоря не комфортно :) да и не факт, что баг себя проявит. один и тот же блок по разному рисуется на разных компьютерах (автокады с 2010 по 2014 с сервиспаками и без. есть и 32 и 64-битные версии). так что сейчас эту задачу я перекинул на пользователей :):):), хоть и понимаю, что, кроме как ругаться, они ничего делать не будут :(.

PS: ну и хочется услышать хоть какой-то ответ. типа, да, о проблеме известно, происходит из-за того-то и того-то. но, если сделать так-то и так-то, потом окропить святой водой и дважды стукнуть в бубен :), то проблема исчезнет, и на будущее так не делайте, а то опять проблема вернется. ну или такой ответ, огооооооооо. а мы и не знали, что уже 4 года как минимум у нас через Ж... создаются и рисуются блоки, или поломан функционал копипаста. дайте подумать. вдруг что и придумаем.
просто, проблема есть и решить ее нельзя. обойти было б можно, если б знать из-за чего проблема. а так - гадание по фотографии идет :).

PS2: а гробить во всех подряд блоках таблицу сортировки не есть правильно. я ж писал выше. получается, что одно лечим, а другое калечим. да и не факт, что в будущем история не повторится, даже если во всех теперешних блоках пересоздать сортировку. блоки рисуют новые постоянно на тех же автокадах, что и эти блоки рисовали :), так что война с ветряными мельницами у меня будет вечной :(
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 24-12-2013, 15:40:32
кстати, только что закончил подготовку проекта на отправку.
Ты про этот баг? Сам отправишь? Можешь там дать ссылку на обсуждение в этой теме. Они по ссылкам мониторят и этот форум тоже. Подозреваю, что танцы с бубнами здесь не помогут, но чем черт не шутит...
Название: Re: вставка блоков
Отправлено: Николай Горлов от 24-12-2013, 16:41:55
Цитировать
Можешь там дать ссылку на обсуждение в этой теме
только что добавил. так что ждёмс ответа )
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 24-12-2013, 16:44:26
Наверное всё же было бы лучше если бы отправлял я - ответили бы быстрее. В любом случае до начала января ответа не жди - каникулы у них.
Название: Re: вставка блоков
Отправлено: Николай Горлов от 21-02-2014, 12:57:10
ну, собственно, запрос в ADN подошел к своему логическому концу  :'(. меня послали подождать ответа
мне рассказывали кучу новых и увлекательных идей, например, как при помощи автокадовской команды INSERT вставить блок из одного чертежа (чертеж содержит кучу блоков, а не один единственный с точкой вставки в 0,0) :):):) в другой чертеж.
также пытались подсунуть обходной путь, ведущий вникуда. увы не вышло :)
потом пытались выдать их перерисованный блок за мой в котором просто меняли порядок прорисовки. может быть и вышло б, если б я был просто пользователем. вах, блок работает, чудо :):):). но нет. натыкал носом и сказал что это липа. и вот, спустя 2 месяца (24.12.2013 - 18.02.2014) получил такой ответ (приветствия, извинения и рекламу в конце письма выкинул. оставляю саму суть):
Цитировать
As I am unable to find another workaround/fix to this myself, I have re-escalated your case to our development team for resolution.
Our development will analyse the reported behaviour and verify the results.
Additionally, I have requested for an alternative workaround, if one is available. If an alternative workaround can be found, I will forward the workaround to you.
Until feedback has been provided to me, I will put this case on hold (archive) and get back to you as soon as I receive a reply to this, from our development.

мой литературный перевод :):):)
т.к. не получилось отмазаться, я пересоздам запрос (очень странно, а почему б МОЙ запрос просто не отдать им?) нашей команде разработчиков. они проанализируют весь твой написанный бред и проверят результат. (ТОЧКА. а мне что с этого? я и сам знаю, что это баг автокада.)
также, я попросил разработчиков об альтернативном обходном пути. и если (ну мало ли, вдруг случайно получится :)) они найдут обходной путь, я тебе о нем напишу. (а почему ТЫ, почему не они. ах да, меня ж от разработчиков отрезали :):):). ну будем надеяться, что ты ничего не перепутаешь)
а пока мы все ждем с моря погоды, я закрою твой запрос, чтоб он мне не маячил перед глазами.


ну и выкину самые интересные мои вложения адээновской переписки.
fake.zip - это собственно сравнительный анализ моего корявого файла и "моего", исправленного автодеском без пересоздания блока вцелом или его составных частей. чисто порядком прорисовки игрались
blk_create.zip - видео создания блока в голом автокаде (HOWTO как сделать корявый блок)

PS: два месяца потрачены зря. единственный обходной путь в этом косяке это ПЕРЕСОЗДАНИЕ блока. кстати, повезло, если блок не динамический. и впредь, НЕЛЬЗЯ рисовать или менять порядок прорисовки объектов в окне редактора блоков. оно только для динамики.

ах да, чуть не забыл. косяк скорей всего будет и в 2015 автокаде :):):). баг им отправил, но недельное молчание говорить о том, что остальные баги, которые я заметил в бете, им отправлять нет смысла
Название: Re: вставка блоков
Отправлено: Александр Ривилис от 21-02-2014, 19:15:53
Николай. Единственную претензию, которую можно предъявить к члену ADN DevHelp, который занимался твоим вопросом, -  это то, что как только он сразу не смог оказать помощь, он не передал запрос команде разработчиков. Понятно, что если баг AutoCAD'а, то только сами разработчики, посмотрев свои же исходные коды, могут найти (или не найти) fix/workaround. Кстати, я бы на твоём месте открыл этот case по новой и попросил бы не закрывать его пока не будет ответа от команды разработчиков, так как для тебя это принципиальный вопрос, который иначе решить нельзя.
Название: Re: вставка блоков
Отправлено: Николай Горлов от 24-02-2014, 12:45:31
Ну, если речь идет о претензиях, то они появились после попытки выдать свой блок за мой давая заведомо ложные советы (им что деньги платят за ответы на мои вопросы? причем, оплата посимвольная :):):) ).
Я мирился с тем, что практически сначала меня все время тыкали носом в бету, мол там все ок, проблема  пропала. В ответ я тыкал носом в то, что проблема есть и в бете. А они, ну так мы не бета, пиши туда. тема закрыта. И так по кругу. 14 января я попросил кого-то кто имеет доступ к исходникам автокада, чтоб проверить на моем блоке копипаст. В ответ получил 27 января сообщение о том, что бетавцы обещали в третьем релизе убрать этот баг (и ни слова о моей просьбе выдать мне на растерзание кого-то поумней :)) 29 января пришел ответ, правда не на мою проблему, а на то, во что я ткнул их носом попутно. И весь февраль мне кормили липу, которую я с ироническими ответами и видеофайлами отправлял им обратно, показывая, что они или что-то упустили в своих советах, или о чем-то недоговаривают. Ну и когда я увидел свой "исправленный" блок и понял КАК его исправили, то всё остальное стало уже не важным.
Кстати, в бете еще веселей. Моему собщению об этом косяке уже 10 дней. 2 дня назад я в той же теме спросил, имеет ли вообще смысл им отправлять баги распрекрасной беты? И, как у них водится - тишина в ответ.

PS: эту тему можно рассматривать как пример обращения в ADN за помощью. У них есть два варианта помощи:
1 - в пределах недели получаешь ответ, который можно найти в инете за час, но лень было искать.
2 - переписка сама затихает через пару месяев ничем не закончившись, но, т.к. я забил на переписку, то считается, что помощь мне оказали.

Название: Re: вставка блоков
Отправлено: Александр Ривилис от 25-02-2014, 01:57:12
Николай. Я понимаю твое праведное возмущение, хотя и далеко не всегда объективное. Я тебе уже предлагал отправить Стивену Престону письмо с указанием номера case и объяснением того, что тебя не удовлетворило в ответах. Я же со своей стороны сделал всё что мог для помощи тебе. Через голову не перепрыгнешь. 
 :(
...им что деньги платят за ответы на мои вопросы? ...
Если тебя интересует их "кухня", то можешь уточнить у Владимира Ананьева (http://adn-cis.org/forum/index.php?action=profile;u=5).
Название: Re: вставка блоков
Отправлено: Николай Горлов от 12-05-2014, 12:22:13
:) поставил 2015 автокад, баг на месте (хотя про баг бетавцам писал :) но ответа от них не получил, как и сотни других тестировщиков). создал на оф. форуме тему с вопросом по этому поводу. через 2-3 часа они по моей теме создали новый запрос. и чуть не пошло всё по кругу :):):). но видать моя нецензурная брань настойчивость заставила их пропустить 2-3 недели вождения за нос и последний ответ был таким:
Цитировать
"Autodesk признает необходимость изменений в поведении продукта. Это означает, текущее поведение нуждается в модификации. Как уже упоминалось, я просил нашу инженерную команду рассмотреть этот вопрос для AutoCAD 2015 Update1."
так что, возможно, в этом году все-таки что-то с этой ситуацией решится и, возможно, в сторону устранения бага :)