создание MultiSheet PDF из листов в модели

Автор Тема: создание MultiSheet PDF из листов в модели  (Прочитано 9532 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
Доброго времени суток.

Возникла такая задача:
В модели куча "листов" самых разных размеров. координаты рамок всех листов известны.
Нужно все листы отправить на перчать в 1 PDF (MultiSheet).

С Layout работал и acplPublishExecute замечательно справляется.

Думал перед печатью создавать Layout для все листов, исползовать стандартный алгоритм и потом удалять листы.
Промлема: листы всякие разные по размеру.

Autocad позволяет создавать Page Setup и потом через PUBLISH указать эго, тогда можно печатать по типу "Window", т.е. по координатам
Проблема: как создавать эти Page Setup програмно?

Может я чего-то не знаю и в AcPlDSDEntry можно координаты указывать?
или создавать физический DSD фаил и эго считывать, там побольше параметров можно указать?

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
нашел такую штуку, попробую как пойдет..
https://adndevblog.typepad.com/autocad/2013/10/publishing-model-views-to-a-multi-sheet-dwfpdf.html

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
begiz,
А может пойти другим путём - выполнить печать в отдельные PDF-файлы, а потом воспользоваться какой-нибудь библиотекой, которая позволит их все объединить в один файл?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
тоже вариант,
тогда нужно менять настроику Layout (Model) на Window для каждой рамки и отправлять на печать...
интересно сколько займет времени..

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Тут есть варианты для объединения PDF-файлов на C++: https://stackoverflow.com/questions/370543/combining-two-pdf-files-in-c
А тут даже код (с использованием библиотеки PoDoFo): https://cppsecrets.com/users/931049711497106109971151165748485664103109971051084699111109/C00-program-to-merge-PDF-files.php
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение begiz 07-05-2020, 14:02:01

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
вот такая страшилка получилась, но вроде работает

Код - C++ [Выбрать]
  1. #pragma once
  2. #ifndef PRINTOOLS_H
  3. #define PRINTOOLS_H
  4.  
  5. namespace PrintTools
  6. {
  7.         struct Page
  8.         {
  9.                 CString PageName;
  10.                 double minx;
  11.                 double miny;
  12.                 double maxx;
  13.                 double maxy;
  14.         };
  15.  
  16.         inline AcPlDSDData createDSD(AcPlDSDEntries entries,
  17.                                                                  CString projectPath,
  18.                                                                  CString destinationPath,
  19.                                                                  CString promptForFile)
  20.         {
  21.                 AcPlDSDData dsdDataObj;
  22.                 CString full_file_path_name = projectPath;
  23.  
  24.                 CString dsd = projectPath;
  25.                 dsd.Replace(_T(".dwg"), _T(".dsd"));
  26.  
  27.                 CString path = full_file_path_name;
  28.                 path.Truncate(path.ReverseFind('\\'));
  29.  
  30.                 CString file = full_file_path_name;
  31.                 file = file.Mid(file.ReverseFind('\\') + 1);
  32.                 file.Replace(_T(".dwg"), _T(""));
  33.  
  34.                 WORD wBOM = 0xFEFF;
  35.                 DWORD NumberOfBytesWritten;
  36.  
  37.                 HANDLE hFile = ::CreateFile(dsd, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); //for UTF16 little endian
  38.                 ::WriteFile(hFile, &wBOM, sizeof(WORD), &NumberOfBytesWritten, NULL);
  39.                 ::CloseHandle(hFile);
  40.  
  41.                 WritePrivateProfileString(_T("DWF6Version"), _T("Ver"), _T("1"), dsd);
  42.                 WritePrivateProfileString(_T("DWF6MinorVersion"), _T("MinorVer"), _T("1"), dsd);
  43.  
  44.                 for (int i = 0; i < entries.length(); i++)
  45.                 {
  46.                         WritePrivateProfileString(_T("DWF6Sheet:") + file + _T("-") + entries[i].title(), _T("DWG"), full_file_path_name, dsd);
  47.                         WritePrivateProfileString(_T("DWF6Sheet:") + file + _T("-") + entries[i].title(), _T("Layout"), entries[i].layout(), dsd);
  48.                         WritePrivateProfileString(_T("DWF6Sheet:") + file + _T("-") + entries[i].title(), _T("Setup"), entries[i].NPS(), dsd);
  49.                         WritePrivateProfileString(_T("DWF6Sheet:") + file + _T("-") + entries[i].title(), _T("OriginalSheetPath"), full_file_path_name, dsd);
  50.                         WritePrivateProfileString(_T("DWF6Sheet:") + file + _T("-") + entries[i].title(), _T("Has Plot Port"), _T("0"), dsd);
  51.                 }
  52.  
  53.                 WritePrivateProfileString(_T("Target"), _T("Type"), _T("6"), dsd);
  54.                 WritePrivateProfileString(_T("Target"), _T("DWF"), destinationPath, dsd);
  55.                 WritePrivateProfileString(_T("Target"), _T("OUT"), path, dsd);
  56.  
  57.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("IsSheetSet"), _T("FALSE"), dsd);
  58.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("IsHomogeneous"), _T("FALSE"), dsd);
  59.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("SheetSet Name"), _T(""), dsd);
  60.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("NoOfCopies"), _T("1"), dsd);
  61.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("PlotStampOn"), promptForFile, dsd);
  62.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("JobID"), _T("0"), dsd);
  63.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("SelectionSetName"), _T(""), dsd);
  64.  
  65.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("CategoryName"), _T(""), dsd);
  66.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("LogFilePath"), _T(""), dsd);
  67.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("IncludeLayer"), _T("FALSE"), dsd);
  68.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("PromptForDwfName"), _T("FALSE"), dsd);
  69.                 WritePrivateProfileString(_T("SheetSet Properties"), _T("GenerateDwfName"), _T("FALSE"), dsd);
  70.  
  71.                 WritePrivateProfileString(_T("PdfOptions"), _T("ConvertTextToGeometry"), _T("FALSE"), dsd);
  72.                 WritePrivateProfileString(_T("PdfOptions"), _T("LineMerge"), _T("FALSE"), dsd);
  73.                 WritePrivateProfileString(_T("PdfOptions"), _T("EmbedTtf"), _T("TRUE"), dsd);
  74.                 WritePrivateProfileString(_T("PdfOptions"), _T("ImageAntiAliasing"), _T("TRUE"), dsd);
  75.                 WritePrivateProfileString(_T("PdfOptions"), _T("JPEGImageCompression"), _T("TRUE"), dsd);
  76.  
  77.                 dsdDataObj.readDSD(dsd);
  78.  
  79.                 DeleteFile(dsd);
  80.  
  81.                 return dsdDataObj;
  82.         }
  83.  
  84.         inline void PublishViews2MultiSheet(std::vector<Page> pages, bool promptForFile = false)
  85.         {
  86.                 Acad::ErrorStatus es = Acad::eOk;
  87.                 AcDbDatabase* pDb = acdbCurDwg();
  88.  
  89.                 // Create page setup based on the views
  90.  
  91.                 AcDbLayoutManager* layoutManager = acdbHostApplicationServices()->layoutManager();
  92.                 CString activeLayout = layoutManager->findActiveLayout(true);
  93.                 AcDbObjectId layoutId = layoutManager->findLayoutNamed(activeLayout);
  94.  
  95.                 AcDbObjectPointer<AcDbLayout> layout(layoutId, AcDb::OpenMode::kForWrite);
  96.  
  97.                 CString deviceName = _T("DWG To PDF.pc3");
  98.                 TCHAR* layoutName_t = NULL;
  99.  
  100.                 es = layout->getLayoutName(layoutName_t);
  101.  
  102.                 CString layoutName(layoutName_t);
  103.                 delete layoutName_t;
  104.  
  105.                 for(int i = 0 ; i < pages.size(); i ++)
  106.                 {
  107.                         AcDbPlotSettings* plotSettings = new AcDbPlotSettings(layout->modelType());
  108.                         es = plotSettings->copyFrom(layout);
  109.  
  110.                         AcDbPlotSettingsValidator* pPSV = NULL;
  111.                         pPSV = acdbHostApplicationServices()->plotSettingsValidator();
  112.  
  113.                         es = pPSV->setPlotCfgName(plotSettings, deviceName);
  114.                         pPSV->refreshLists(plotSettings);
  115.                         es = pPSV->setPlotType(plotSettings, PlotType::kWindow);
  116.                         es = pPSV->setUseStandardScale(plotSettings, true);
  117.                         es = pPSV->setStdScaleType(plotSettings, StdScaleType::kScaleToFit);
  118.                         es = pPSV->setPlotCentered(plotSettings, true);
  119.                         es = pPSV->setPlotRotation(plotSettings, PlotRotation::k0degrees);
  120.                         es = pPSV->setPlotPaperUnits(plotSettings, AcDbPlotSettings::kMillimeters);
  121.                         plotSettings->setPrintLineweights(Adesk::kTrue);
  122.                         es = pPSV->setPlotViewName(plotSettings, pages[i].PageName);
  123.  
  124.                         AcGePoint2d min_pt(min(pages[i].minx, pages[i].maxx), min(pages[i].miny, pages[i].maxy));
  125.                         AcGePoint2d max_pt(max(pages[i].minx, pages[i].maxx), max(pages[i].miny, pages[i].maxy));
  126.                        
  127.                         //rotate portrait/landscape
  128.                         if(max_pt.x - min_pt.x < max_pt.y - min_pt.y)
  129.                                 pPSV->setPlotRotation(plotSettings, PlotRotation::k90degrees);
  130.  
  131.                         resbuf fromrb, torb;
  132.  
  133.                         fromrb.restype = RTSHORT;
  134.                         fromrb.resval.rint = 0; // WCS
  135.  
  136.                         torb.restype = RTSHORT;
  137.                         torb.resval.rint = 2; // DCS
  138.  
  139.                         acedTrans(asDblArray(min_pt), &fromrb, &torb, FALSE, asDblArray(min_pt));
  140.                         acedTrans(asDblArray(max_pt), &fromrb, &torb, FALSE, asDblArray(max_pt));
  141.  
  142.                         es = pPSV->setPlotWindowArea(plotSettings, min_pt.x, min_pt.y, max_pt.x, max_pt.y);
  143.                         es = plotSettings->setPlotSettingsName(pages[i].PageName + _T("PS"));
  144.                         es = plotSettings->addToPlotSettingsDict(pDb);
  145.                         pPSV->refreshLists(plotSettings);
  146.                         es = layout->copyFrom(plotSettings);
  147.                         es = plotSettings->close();
  148.                 }
  149.  
  150.                 layout->close();
  151.  
  152.                 //put the plot in foreground
  153.  
  154.                 resbuf bp_old = { 0,0 }, bp_0 = { 0,0 };
  155.                 acedGetVar(_T("BACKGROUNDPLOT"), &bp_old);
  156.                 bp_0 = bp_old; bp_0.resval.rint = 0;
  157.                 acedSetVar(_T("BACKGROUNDPLOT"), &bp_0);
  158.  
  159.                 CString dwgFileName = curDoc()->fileName();
  160.                 CString dwgPath = dwgFileName.Mid(0, dwgFileName.ReverseFind(_T('\\')) + 1);   
  161.                 CString output = dwgFileName; output.Replace(_T(".dwg"), _T(".pdf"));
  162.  
  163.                 AcPlDSDEntries collection;
  164.  
  165.                 for (int i = 0; i < pages.size(); i++)
  166.                 {
  167.                         AcPlDSDEntry entry;
  168.                         entry.setDwgName(dwgFileName);
  169.                         entry.setLayout(layoutName);
  170.                         entry.setTitle(pages[i].PageName);
  171.                         entry.setNPSSourceDWG(entry.dwgName());
  172.                         entry.setNPS(pages[i].PageName + _T("PS"));
  173.                         collection.append(entry);
  174.                 }
  175.  
  176.                 AcPlDSDData dsdData = createDSD(collection, dwgFileName, output, promptForFile ? _T("TRUE") : _T("FALSE"));
  177.  
  178.                 AcPlPlotConfig* plotConfig = NULL;
  179.                 acplPlotConfigManager->setCurrentConfig(plotConfig, deviceName);
  180.  
  181.                 //acedArxLoad(L"AcPublish.arx"); if not loaded yet
  182.  
  183.                 // Publish it
  184.                 acplPublishExecute(dsdData, plotConfig, true);
  185.  
  186.                 //reset the background plot value
  187.                 acedSetVar(_T("BACKGROUNDPLOT"), &bp_old);
  188.  
  189.                 //cleanup
  190.                 AcDbDictionary* pPlotSetDict = NULL;
  191.                 es = pDb->getPlotSettingsDictionary(pPlotSetDict, AcDb::kForWrite);
  192.                 if (es == Acad::eOk)
  193.                 {
  194.                         for (int i = 0 ; i < collection.length(); i++)
  195.                         {
  196.                                 CString NPS = collection[i].NPS();
  197.                                 pPlotSetDict->remove(NPS);
  198.                         }
  199.                         pPlotSetDict->close();
  200.                 }
  201.  
  202.                 if (MessageBox(NULL, _T("Открыть PDF?"), _T("Информация"), MB_YESNO) == IDYES)
  203.                         ShellExecute(NULL, NULL, output, NULL, NULL, SW_SHOW);
  204.  
  205.         }
  206. }
  207.  
  208. #endif
  209.