Нарезка 3D тел

Автор Тема: Нарезка 3D тел  (Прочитано 35070 раз)

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #30 : 05-06-2014, 11:25:30 »
Выборочно проверил работу в др. версиях AutoCAD: 2015, 2012, 2010 - в них работает. Т.о. не работает только в 2009-м, который мне как раз и нужен.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Нарезка 3D тел
« Ответ #31 : 05-06-2014, 13:54:18 »
Не пробовал экспериментировать в 2009-ом со значениями interval? Посмотреть, какие значения получились у interval.LowerBound и interval.UpperBound и скажем "сжать" этот интервал на 1/1000 его длины. Не исключено, что ошибка из-за попадания на границу интервала.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #32 : 05-06-2014, 16:13:29 »
Для того, чтобы ваш вариант заработал в 2009-м, приходится использовать другой перегруженный вариант метода GetSamplePoints. Иначе в 2009-м возникает исключение, обозначенное мною ранее в теме. Т.о. код будет выглядеть так:
Код - C# [Выбрать]
  1.     public static void GetVisualBoundary(this AcDb.Region region, double delta,
  2.   ref AcGe.Point2d minPoint, ref AcGe.Point2d maxPoint) {
  3.       double hord = delta;
  4.       using(AcGe.BoundBlock3d boundBlk = new AcGe.BoundBlock3d()) {
  5.         using(AcBr.Brep brep = new AcBr.Brep(region)) {
  6.           foreach(AcBr.Edge edge in brep.Edges) {
  7.             using(AcGe.Curve3d curve = edge.Curve) {
  8.               AcGe.ExternalCurve3d curve3d = curve as AcGe.ExternalCurve3d;
  9.               // Делать точный расчет нужно только если образующая - сплайн
  10.               // в противном случае достаточно получить BoundBlock
  11.               if(curve3d != null && curve3d.IsNurbCurve) {
  12.                 AcGe.Interval interval = curve.GetInterval();
  13. #if AUTOCAD_2009
  14.                 // В AutoCAD 2009 перегруженный вариант метода GetSamplePoints,
  15.                 // с сигнатурой
  16.                 //
  17.                 // public PointOnCurve3d[] GetSamplePoints(
  18.                 //  double fromParameter,
  19.                 //  double toParameter,
  20.                 //  double chordHeight);
  21.                 //
  22.                 // работает некорректно, выдавая ошибку в процессе своей
  23.                 // работы. Поэтому приходится использовать следующую
  24.                 // перегруженную версию метода:
  25.                 AcGe.Point3d[] pnts = curve.GetSamplePoints(
  26.                   (Int32)(interval.UpperBound * 0.5 / delta)); // Уменьшаем
  27.                 // количество точек в 2 раза
  28.                 foreach(AcGe.Point3d pt in pnts) {
  29.                   if(!boundBlk.IsBox)
  30.                     boundBlk.Set(pt, pt);
  31.                   else
  32.                     boundBlk.Extend(pt);
  33.                 }
  34. #else
  35.                 AcGe.PointOnCurve3d[] pnts = curve.GetSamplePoints(
  36.                   interval.LowerBound, interval.UpperBound, hord);
  37.                 foreach(AcGe.PointOnCurve3d pt in pnts) {
  38.                   if(!boundBlk.IsBox)
  39.                     boundBlk.Set(pt.Point, pt.Point);
  40.                   else
  41.                     boundBlk.Extend(pt.Point);
  42.                 }
  43. #endif
  44.               }
  45.               else {
  46.                 if(!boundBlk.IsBox) {
  47.                   boundBlk.Set(edge.BoundBlock.GetMinimumPoint(),
  48.                     edge.BoundBlock.GetMaximumPoint());
  49.                 }
  50.                 else {
  51.                   boundBlk.Extend(edge.BoundBlock.GetMinimumPoint());
  52.                   boundBlk.Extend(edge.BoundBlock.GetMaximumPoint());
  53.                 }
  54.               }
  55.             }
  56.           }
  57.         }
  58.         // Возвращаем вычисленный результат
  59.         minPoint = new AcGe.Point2d(boundBlk.GetMinimumPoint().X,
  60.           boundBlk.GetMinimumPoint().Y);
  61.         maxPoint = new AcGe.Point2d(boundBlk.GetMaximumPoint().X,
  62.           boundBlk.GetMaximumPoint().Y);
  63.       }
  64.     }
В случае AutoCAD 2009 обрабатываться будет гораздо больше точек, чем для др. версий AutoCAD, т.к. используем др. перегруженный вариант метода GetSamplePoints, поэтому делим их на два (по вашему совету).

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Нарезка 3D тел
« Ответ #33 : 08-06-2014, 01:34:40 »
Еще немного потестировал и пришел к выводу, что так будет лучше:
Код - C# [Выбрать]
  1. private void GetVisualBoundary(AcDb.Region region, double delta,
  2.   ref AcGe.Point2d minPoint, ref AcGe.Point2d maxPoint)
  3. {
  4.   using (AcGe.BoundBlock3d boundBlk = new AcGe.BoundBlock3d()) {
  5.     using (AcBr.Brep brep = new AcBr.Brep(region)) {
  6.       foreach (AcBr.Edge edge in brep.Edges) {
  7.         using (AcGe.Curve3d curve = edge.Curve) {
  8.           AcGe.ExternalCurve3d curve3d = curve as AcGe.ExternalCurve3d;
  9.           // Делать точный расчет нужно только если образующая - сплайн
  10.           // в противном случае достаточно получить BoundBlock
  11.           if (curve3d != null && curve3d.IsNurbCurve) {
  12.             using (AcGe.NurbCurve3d nurbCurve = curve3d.NativeCurve as AcGe.NurbCurve3d) {
  13.               AcGe.Interval interval = nurbCurve.GetInterval();
  14.               for (double par = interval.LowerBound; par <= interval.UpperBound; par += (delta * 2.0)) {
  15.                 AcGe.Point3d p = nurbCurve.EvaluatePoint(par);
  16.                 if (!boundBlk.IsBox)
  17.                   boundBlk.Set(p, p);
  18.                 else
  19.                   boundBlk.Extend(p);
  20.               }
  21.             }
  22.           } else {
  23.             if (!boundBlk.IsBox) {
  24.               boundBlk.Set(edge.BoundBlock.GetMinimumPoint(), edge.BoundBlock.GetMaximumPoint());
  25.             } else {
  26.               boundBlk.Extend(edge.BoundBlock.GetMinimumPoint());
  27.               boundBlk.Extend(edge.BoundBlock.GetMaximumPoint());
  28.             }
  29.           }
  30.         }
  31.       }
  32.     }
  33.     // Возвращаем вычисленный результат
  34.     minPoint = new AcGe.Point2d(boundBlk.GetMinimumPoint().X, boundBlk.GetMinimumPoint().Y);
  35.     maxPoint = new AcGe.Point2d(boundBlk.GetMaximumPoint().X, boundBlk.GetMaximumPoint().Y);
  36.   }
  37. }
По непонятной для меня причине NurbCurve3d.EvaluatePoint вычисляется на порядок быстрее, чем ExternalCurve3d.EvaluatePoint, хотя в данном случае это вроде бы одно и тоже. По результатам этот вариант в AutoCAD 2014 работает приблизительно с той же скоростью, что и вариант (недоступный в AutoCAD 2009 из-за  бага) c GetSamplePoints(startParam, endParam, hord).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #34 : 09-06-2014, 10:56:06 »
По непонятной для меня причине NurbCurve3d.EvaluatePoint вычисляется на порядок быстрее, чем ExternalCurve3d.EvaluatePoint
И при этом данный вариант корректно работает в AutoCAD 2009. :) Спасибо!

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #35 : 09-06-2014, 12:37:41 »
AutoCAD 2009.

Обнаружилась проблема при использовании обозначенного выше варианта GetVisualBoundary: при его использовании в коде моего метода CloneAndMesh, генерируется исключение при определённых значениях параметра delta. Проблему наблюдаю при обработке одного из сплайнов (показан на скрине). Все прочие регионы отработаны корректно.

Если delta равен 0.1, то возникает исключение, показанное на скрине. Но если delta, к примеру, равен 1, то указанный сплайн режется корректно. Предыдущий вариант GetVisualBoundary от Александра Наумовича (тот, в котором я добавил директивы препроцессора для 2009-го), выдаёт такую же проблему.

В чём может быть причина возникновения eGeneralModelingFailure в данном случае? Насколько я понимаю, если даже вдруг окажется, что оба региона не пересекаются, то в этом случае у обоих IsNull будет true. А тут возникает исключение...

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #36 : 09-06-2014, 12:56:34 »
Мой "Топорный" вариант отработал корректно. Сейчас попробую скомпилировать для 2009-го последний вариант Дима_, предложенный в соседней ветке и проверить на нём.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Нарезка 3D тел
« Ответ #37 : 09-06-2014, 13:29:57 »
И при этом данный вариант корректно работает в AutoCAD 2009. :) Спасибо!
И тоже даёт приличный выигрыш в скорости?
В чём может быть причина возникновения eGeneralModelingFailure в данном случае?
Причина в ограничениях ACIS. :( Видимо слишком близко расположенные линии должны пересечься, а точность выходит за максимальную в 1e-6.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #38 : 09-06-2014, 13:32:47 »
И тоже даёт приличный выигрыш в скорости?
Да, но толку-то, если это работает лишь от случая к случаю.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Нарезка 3D тел
« Ответ #39 : 09-06-2014, 13:35:24 »
Да, но толку-то, если это работает лишь от случая к случаю.
Как я понял сам метод работает не от случая к случаю, а постоянно и даёт более точный результат за меньшее время. Другое дело, что эта точность приводит к проблемам в другом месте твоего кода.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #40 : 09-06-2014, 13:39:41 »
Да, но толку-то, если это работает лишь от случая к случаю.
Как я понял сам метод работает не от случая к случаю, а постоянно и даёт более точный результат за меньшее время. Другое дело, что эта точность приводит к проблемам в другом месте твоего кода.
Да, несомненно, сам по себе метод работает. Однако в данном случае мне приходится рассматривать использование полученных им результатов в контексте работы метода BooleanOperation... :(

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Нарезка 3D тел
« Ответ #41 : 09-06-2014, 13:51:56 »
1. Смотрим размеры области, которую ты пытаешься сечь с шагом 0.1:

Очевидно, что ты находишься на пределе допустимой точности.
2. Что можно посоветовать? Во-первых, не разрешать такой мелкий шаг. Во-вторых, если такое исключение возникло, то немного изменить секущий прямоугольник и попробовать с ним. Кстати, для BoundBlock3d есть специальный метод для этого: BoundBlock3d.Swell
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #42 : 10-06-2014, 11:54:23 »
Кстати, для BoundBlock3d есть специальный метод для этого: BoundBlock3d.Swell
Оно!
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Получить координаты границ левого нижнего и правого верхнего углов для
  3. /// визуального "GeometricExtents" региона.
  4. /// </summary>
  5. /// <param name="region">Регион, для которого следует получить координаты
  6. /// границ визуального "GeometricExtents".</param>
  7. /// <param name="delta">Предельная арифметическая погрешность вычислений.
  8. /// </param>
  9. /// <param name="minPoint">Ссылка на переменную Point2d, в которой следует
  10. /// сохранить координаты левого нижнего угла визуального
  11. /// "GeometricExtents".</param>
  12. /// <param name="maxPoint">Ссылка на переменную Point2d, в которой следует
  13. /// сохранить координаты правого верхнего угла визуального
  14. /// "GeometricExtents".</param>
  15. public static void GetVisualBoundary(this Db.Region region, double delta,
  16. ef Gm.Point2d minPoint, ref Gm.Point2d maxPoint) {
  17.   using(Gm.BoundBlock3d boundBlk = new Gm.BoundBlock3d()) {
  18.     using(Br.Brep brep = new Br.Brep(region)) {
  19.       foreach(Br.Edge edge in brep.Edges) {
  20.         using(Gm.Curve3d curve = edge.Curve) {
  21.           Gm.ExternalCurve3d curve3d = curve as Gm.ExternalCurve3d;
  22.           // Делать точный расчет нужно только если образующая - сплайн
  23.           // в противном случае достаточно получить BoundBlock
  24.           if(curve3d != null && curve3d.IsNurbCurve) {
  25.             using(Gm.NurbCurve3d nurbCurve = curve3d.NativeCurve
  26.               as Gm.NurbCurve3d) {
  27.               Gm.Interval interval = nurbCurve.GetInterval();
  28.               for(double par = interval.LowerBound; par <=
  29.                 interval.UpperBound; par += (delta * 2.0)) {
  30.                 Gm.Point3d p = nurbCurve.EvaluatePoint(par);
  31.                 if(!boundBlk.IsBox)
  32.                   boundBlk.Set(p, p);
  33.                 else
  34.                   boundBlk.Extend(p);
  35.               }
  36.             }
  37.           }
  38.           else {
  39.             if(!boundBlk.IsBox) {
  40.               boundBlk.Set(edge.BoundBlock.GetMinimumPoint(),
  41.                 edge.BoundBlock.GetMaximumPoint());
  42.             }
  43.             else {
  44.               boundBlk.Extend(edge.BoundBlock.GetMinimumPoint());
  45.               boundBlk.Extend(edge.BoundBlock.GetMaximumPoint());
  46.             }
  47.           }
  48.         }
  49.       }
  50.     }
  51.     boundBlk.Swell(delta);
  52.     // Возвращаем вычисленный результат
  53.     minPoint = new Gm.Point2d(boundBlk.GetMinimumPoint().X,
  54.       boundBlk.GetMinimumPoint().Y);
  55.     maxPoint = new Gm.Point2d(boundBlk.GetMaximumPoint().X,
  56.       boundBlk.GetMaximumPoint().Y);
  57.   }
  58. }

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Нарезка 3D тел
« Ответ #43 : 10-06-2014, 11:56:14 »
И как? Теперь исключение не возникает?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Нарезка 3D тел
« Ответ #44 : 10-06-2014, 12:58:28 »
И как? Теперь исключение не возникает?
Нет, я же написал: "Оно!". :) Но... Возникает другая проблема: выполняю публикацию в PDF, посредством использования Window и полученных с помощью этого метода (GetVisualBoundary) границ.

Однако на выходе часть изображения усекается (см. прикреплённые файлы)... Я полагал, что изображение должно чётко вписаться, однако результат не тот, который ожидался. С чем это может быть связано?

Код публикации региона в PDF:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Печать объекта области (region)
  3. /// </summary>
  4. /// <param name="regionId">Идентификатор области, подлежащей публикации.
  5. /// </param>
  6. /// <param name="pcsFileName">Наименование PC3 файла</param>
  7. /// <param name="mediaName">Наименование выбранного формата листа</param>
  8. /// <param name="outputFileName">Имя файла, в котором сохраняется результат
  9. /// печати.</param>
  10. public static void PlotRegion(Db.ObjectId regionId, String pcsFileName,
  11.   String mediaName, String outputFileName) {
  12.  
  13.   if(regionId.IsNull)
  14.     throw new ArgumentException("regionId.IsNull == true");
  15.   if(!regionId.IsValid)
  16.     throw new ArgumentException("regionId.IsValid == false");
  17.  
  18.   if(regionId.ObjectClass.Name != "AcDbRegion")
  19.     throw new ArgumentException("regionId.ObjectClass.Name != AcDbRegion");
  20.  
  21.   if(pcsFileName == null)
  22.     throw new ArgumentNullException("pcsFileName");
  23.   if(pcsFileName.Trim() == String.Empty)
  24.     throw new ArgumentException("pcsFileName.Trim() == String.Empty");
  25.  
  26.   if(mediaName == null)
  27.     throw new ArgumentNullException("mediaName");
  28.   if(mediaName.Trim() == String.Empty)
  29.     throw new ArgumentException("mediaName.Trim() == String.Empty");
  30.  
  31.   if(outputFileName == null)
  32.     throw new ArgumentNullException("outputFileName");
  33.   if(outputFileName.Trim() == String.Empty)
  34.     throw new ArgumentException("outputFileName.Trim() == String.Empty");
  35.  
  36.   Db.Database previewDb = Hs.WorkingDatabase;
  37.   Db.Database db = null;
  38.   Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  39.   if(doc == null || doc.IsDisposed)
  40.     return;
  41.  
  42.   Ed.Editor ed = doc.Editor;
  43.   try {
  44.     if(regionId.Database != null && !regionId.Database.IsDisposed) {
  45.       Hs.WorkingDatabase = regionId.Database;
  46.       db = regionId.Database;
  47.     }
  48.     else {
  49.       db = doc.Database;
  50.     }
  51.  
  52.     using(doc.LockDocument()) {
  53.       using(Db.Transaction tr = db.TransactionManager.StartTransaction()) {
  54.         Db.Region region = tr.GetObject(regionId,
  55.         Db.OpenMode.ForRead) as Db.Region;
  56.  
  57.         Db.Extents3d extends = region.GeometricExtents;
  58.         Db.ObjectId modelId = Us.GetBlockModelSpaceId(db);
  59.         Db.BlockTableRecord model = tr.GetObject(modelId,
  60.         Db.OpenMode.ForRead) as Db.BlockTableRecord;
  61.  
  62.         Db.Layout layout = tr.GetObject(model.LayoutId,
  63.         Db.OpenMode.ForRead) as Db.Layout;
  64.  
  65.         using(Pt.PlotInfo pi = new Pt.PlotInfo()) {
  66.           pi.Layout = model.LayoutId;
  67.  
  68.           using(Db.PlotSettings ps = new Db.PlotSettings(layout.ModelType)
  69.             ) {
  70.             Db.PlotSettingsValidator psv = Db.PlotSettingsValidator
  71.               .Current;
  72.  
  73.             Gm.Point2d bottomLeft = Gm.Point2d.Origin;
  74.             Gm.Point2d topRight = Gm.Point2d.Origin;
  75.  
  76.             region.GetVisualBoundary(RegionTools.Delta, ref bottomLeft,
  77.               ref topRight);
  78.  
  79.             Db.Extents2d extents = new Db.Extents2d(bottomLeft.X,
  80.               bottomLeft.Y, topRight.X, topRight.Y);
  81.  
  82.             // Прежде чем методу SetPlotType присвоить в качестве второго
  83.             // параметра значение PlotType.Window, необходимо вызвать метод
  84.             // SetPlotWindowArea, указав через него границы Window.
  85.             // В противном случае возникнет runtime error.
  86.             psv.SetPlotWindowArea(ps, extents);
  87.             psv.SetPlotType(ps, Db.PlotType.Window);
  88.  
  89.             psv.SetUseStandardScale(ps, true);
  90.             psv.SetStdScaleType(ps, Db.StdScaleType.ScaleToFit);
  91.             psv.SetPlotCentered(ps, true);
  92.  
  93.             // We'll use the standard DWF PC3, as
  94.             // for today we're just plotting to file
  95.             psv.SetPlotConfigurationName(ps, pcsFileName, mediaName);
  96.  
  97.             // We need to link the PlotInfo to the
  98.             // PlotSettings and then validate it
  99.             pi.OverrideSettings = ps;
  100.             Pt.PlotInfoValidator piv = new Pt.PlotInfoValidator();
  101.             piv.MediaMatchingPolicy = Pt.MatchingPolicy.MatchEnabled;
  102.             piv.Validate(pi);
  103.  
  104.             // A PlotEngine does the actual plotting
  105.             // (can also create one for Preview)
  106.             if(Pt.PlotFactory.ProcessPlotState == Pt.ProcessPlotState
  107.               .NotPlotting) {
  108.               Pt.PlotEngine pe = Pt.PlotFactory.CreatePublishEngine();
  109.               using(pe) {
  110.                 // Create a Progress Dialog to provide info
  111.                 // and allow thej user to cancel
  112.  
  113.                 using(Pt.PlotProgressDialog ppd =
  114.                   new Pt.PlotProgressDialog(false, 1, true)) {
  115.                   ppd.set_PlotMsgString(
  116.                   Pt.PlotMessageIndex.DialogTitle, "Custom Plot Progress");
  117.  
  118.                   ppd.set_PlotMsgString(
  119.                     Pt.PlotMessageIndex.CancelJobButtonMessage,
  120.                     "Cancel Job");
  121.  
  122.                   ppd.set_PlotMsgString(
  123.                   Pt.PlotMessageIndex.CancelSheetButtonMessage,
  124.                   "Cancel Sheet");
  125.  
  126.                   ppd.set_PlotMsgString(
  127.                   Pt.PlotMessageIndex.SheetSetProgressCaption,
  128.                   "Sheet Set Progress");
  129.  
  130.                   ppd.set_PlotMsgString(
  131.                     Pt.PlotMessageIndex.SheetProgressCaption,
  132.                    "Sheet Progress");
  133.  
  134.                   ppd.LowerPlotProgressRange = 0;
  135.                   ppd.UpperPlotProgressRange = 100;
  136.                   ppd.PlotProgressPos = 0;
  137.  
  138.                   // Let's start the plot, at last
  139.                   ppd.OnBeginPlot();
  140.                   ppd.IsVisible = true;
  141.                   pe.BeginPlot(ppd, null);
  142.  
  143.                   // We'll be plotting a single document
  144.                   pe.BeginDocument(pi, doc.Name, null, 1, true,
  145.                     // Let's plot to file
  146.                    outputFileName);
  147.                   // Which contains a single sheet
  148.                   ppd.OnBeginSheet();
  149.                   ppd.LowerSheetProgressRange = 0;
  150.                   ppd.UpperSheetProgressRange = 100;
  151.                   ppd.SheetProgressPos = 0;
  152.                   Pt.PlotPageInfo ppi = new Pt.PlotPageInfo();
  153.                   pe.BeginPage(ppi, pi, true, null);
  154.                   pe.BeginGenerateGraphics(null);
  155.                   pe.EndGenerateGraphics(null);
  156.  
  157.                   // Finish the sheet
  158.                   pe.EndPage(null);
  159.                   ppd.SheetProgressPos = 100;
  160.                   ppd.OnEndSheet();
  161.  
  162.                   // Finish the document
  163.                   pe.EndDocument(null);
  164.  
  165.                   // And finish the plot
  166.                   ppd.PlotProgressPos = 100;
  167.                   ppd.OnEndPlot();
  168.                   pe.EndPlot(null);
  169.                 }
  170.               }
  171.             }
  172.             else {
  173.               ed.WriteMessage("\nAnother plot is in progress.");
  174.             }
  175.           }
  176.         }
  177.         tr.Commit();
  178.       }
  179.     }
  180.   }
  181.   finally {
  182.     Hs.WorkingDatabase = previewDb;
  183.   }
  184. }

Команда, использующая обозначенный выше код:

Код - C# [Выбрать]
  1. /// <summary>
  2. /// Опубликовать указанную пользователем область (объект Region) в PDF
  3. /// формат.
  4. /// </summary>
  5. [Rt.CommandMethod("plotRegion", Rt.CommandFlags.Modal)]
  6. public void PlotRegion() {
  7.   Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  8.   if(doc == null || doc.IsDisposed)
  9.     return;
  10.  
  11.   Ed.Editor ed = doc.Editor;
  12.   Db.Database db = doc.Database;
  13.  
  14.   using(doc.LockDocument()) {
  15.     Ed.PromptEntityOptions peo = new Ed.PromptEntityOptions(
  16.      "Укажите область (объект Region), подлежащую публикации в PDF формат."
  17.      );
  18.  
  19.     peo.SetRejectMessage("Указанный объект не является областью (region)."
  20.       );
  21.     peo.AddAllowedClass(typeof(Db.Region), false);
  22.  
  23.     Ed.PromptEntityResult per = ed.GetEntity(peo);
  24.  
  25.     if(per.Status != Ed.PromptStatus.OK) {
  26.       ed.WriteMessage("\nВыполнение команды прервано.\n");
  27.       return;
  28.     }
  29.  
  30.     Db.ObjectId regionId = per.ObjectId;
  31.  
  32.     Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32
  33.       .SaveFileDialog();
  34.     saveFileDialog.Title =
  35.       "Публикация выбранной области (Region) в файл формата PDF";
  36.     saveFileDialog.Filter = "PDF-файлы|*.pdf";
  37.     bool? result = saveFileDialog.ShowDialog();
  38.  
  39.     if(!result.HasValue || !result.Value) {
  40.       ed.WriteMessage("\nВыполнение команды прервано, т.к. не был указан "
  41.         + "PDF-файл.");
  42.       return;
  43.     }
  44.  
  45.     String pdfFileName = saveFileDialog.FileName;
  46.  
  47.     RegionTools.PlotRegion(regionId, "DWG To PDF.pc3",
  48.       "ISO_A4_(210.00_x_297.00_MM)", pdfFileName);
  49.  
  50.     ed.WriteMessage("\nВыбранная Вами область опубликована в файл " +
  51.           "\"{0}\"\n", pdfFileName);
  52.   }
  53. }