не получается извлечь площадь штриховки

Автор Тема: не получается извлечь площадь штриховки  (Прочитано 11232 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
имеется предварительно заполненный объектами штриховки List<Hatch>
пробегаю foreach циклом по ним.. извлекается Polyline.. но никак не хочет извлекаться площадь..пишет ошибка elinvalidinput.. может надо както по транзакции обратиться?

Код - C# [Выбрать]
  1. foreach (Hatch item in hatches)
  2.             {
  3.                 HatchLoop hatchLoop = item.GetLoopAt(0);
  4.                 if (hatchLoop.IsPolyline)
  5.                 {
  6.                     Point3dCollection p3dc = new Point3dCollection();
  7.                     BulgeVertexCollection bulges = hatchLoop.Polyline;
  8.                     int nVertices = bulges.Count;
  9.                     var room = new Room();                    
  10.                     for (int i = 0; i < nVertices; i++)
  11.                     {
  12.                         var point3d = new Point3d(bulges[i].Vertex.X, bulges[i].Vertex.Y, 0);
  13.                         var point = new Point
  14.                         {
  15.                             X = bulges[i].Vertex.X,
  16.                             Y = bulges[i].Vertex.Y
  17.                         };                        
  18.                         room.edge_points.Add(point);
  19.                         room.Area = item.Area;                    
  20.                         p3dc.Add(point3d);
  21.                     }
  22.            }

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Это происходит со всеми штриховками, или только с конкретными?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Может есть самопересечения.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
имеется предварительно заполненный объектами штриховки List<Hatch>
Надеюсь, что весь этот код работает внутри транзакции?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Это происходит со всеми штриховками, или только с конкретными?
со всеми и с набором и с одиночными..причем особенность такая что в другом методе площади замечательно извлекаются..вот ищу связь
вот здесь все хорошо извлекается
Код - C# [Выбрать]
  1. public void Test()
  2.         {
  3.             var doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
  4.             var db = doc.Database;
  5.             var ed = doc.Editor;
  6.             using (Transaction tr = db.TransactionManager.StartTransaction())
  7.             {
  8.                 PromptSelectionResult psr = ed.GetSelection();
  9.                 if (psr.Status == PromptStatus.OK)
  10.                 {
  11.                     SelectionSet ss = psr.Value;
  12.                     foreach (SelectedObject item in ss)
  13.                     {
  14.                         if (item != null)
  15.                         {
  16.                             Entity ent = tr.GetObject(item.ObjectId, OpenMode.ForRead) as Entity;
  17.                             if (ent != null && ent.GetType() == typeof(Hatch))
  18.                             {
  19.                                 var hatch = (Hatch)ent;
  20.                                 ed.WriteMessage("{0}" + Environment.NewLine, hatch.Area);
  21.                             }
  22.                         }
  23.                     }
  24.                 }
  25.                 tr.Commit();
  26.             }            
  27.         }
сразу скажу что пробовал обратиться к объектам штриховки через транзакцию аналогично этому методу..но они все равно не извлекаются..

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Может есть самопересечения.
все штриховки вылизаны и грубо говоря идеальны.. ну и в другом методе извлекаются площади

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
сразу скажу что пробовал обратиться к объектам штриховки через транзакцию аналогично этому методу..но они все равно не извлекаются..
Вне транзакции ты не можешь пользоваться открытыми в транзакции примитивами, так как после окончания транзакции они закрываются.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
сразу скажу что пробовал обратиться к объектам штриховки через транзакцию аналогично этому методу..но они все равно не извлекаются..
Вне транзакции ты не можешь пользоваться открытыми в транзакции примитивами, так как после окончания транзакции они закрываются.
понял..попробую сделать это все в транзакции еще раз...просто странно почему вне транзакции извлекаются контуры на ура..

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Совсем недавно на форуме Autodesk наткнулись на ситуацию, когда для однозначно динамического блока свойство IsDynamicBlock возвращало false. Оказалось, что причина именно в работе с примитивами вне транзакции. А если бы ты еще и пытался что-то в этих примитивах менять, то мог бы словить Fatal Error.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Совсем недавно на форуме Autodesk наткнулись на ситуацию, когда для однозначно динамического блока свойство IsDynamicBlock возвращало false. Оказалось, что причина именно в работе с примитивами вне транзакции. А если бы ты еще и пытался что-то в этих примитивах менять, то мог бы словить Fatal Error.
к сожалению все не так просто оказалось.. не работает даже такой код
Код - C# [Выбрать]
  1. public void Test()
  2.         {
  3.             var doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
  4.             var db = doc.Database;
  5.             var ed = doc.Editor;
  6.             using (Transaction tr = db.TransactionManager.StartTransaction())
  7.             {
  8.                 PromptSelectionResult psr = ed.GetSelection();
  9.                 if (psr.Status == PromptStatus.OK)
  10.                 {
  11.                     SelectionSet ss = psr.Value;
  12.                     foreach (SelectedObject item in ss)
  13.                     {
  14.                         if (item != null)
  15.                         {
  16.                             Entity ent = tr.GetObject(item.ObjectId, OpenMode.ForRead) as Entity;
  17.                             if (ent != null && ent.GetType() == typeof(Hatch))
  18.                             {
  19.                                 var hatch = (Hatch)ent;
  20.                                 ed.WriteMessage("{0} ",hatch.Area);
  21.                             }
  22.                         }
  23.                     }
  24.                 }              
  25.             }            
  26.         }

если выбирается один объект площадь вылезает если 2 и более возникает ошибка
Приложение не поддерживает оперативную (JIT)
отладку. Подробная информацию приводится в конце данного сообщения.

************** Текст исключения **************
Autodesk.AutoCAD.Runtime.Exception: eInvalidInput
   в Autodesk.AutoCAD.DatabaseServices.Hatch.get_Area()
   в electricalPlugin.test.Test() в C:\Users\Илья\documents\visual studio 2015\Projects\electricalPlugin\electricalPlugin\electricalPlugin.cs:строка 182
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()


пробовал в релизе вместо дебага не помогает..

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
У меня твой код отработал нормально если штриховка не имеет самопересечений, при наличии самопересечений вываливается твоя ошибка

Извините, вам запрещён просмотр содержимого спойлеров.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
ultracontrol
1. Создай тестовый проект.
2. Выложи пример чертежа, в котором это происходит.
3. Укажи версию AutoCAD.

Ну и не забывай про Transaction.Commit()
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Александр Ривилис, Владимир Шу
версия автокада 2015-64
проект и пример файла приложил.

обнаружилась такая ситуация.
при первом вызове TEST и выделении всех штриховок парочка таки выдает площадь, остальные - ошибки.
далее если взять любую ошибочную штриховку выделить ее, захватить мышкой одну из точек контура и переместить ее (даже на прежнее место) и снова вызвать TEST на этой штриховке, она выдаст площадь, хотя казалось бы, она не изменилась.. каким то образом обновился контур может..не могу понять..
пробовал в коде перемещать на нулевое расстояние, обновлять, пересчитывать (evaluatehatch) ничего не помогает..

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
обнаружилась такая ситуация.
при первом вызове TEST и выделении всех штриховок парочка таки выдает площадь, остальные - ошибки.
Ты бы для начала обратил внимание, что и AutoCAD не может посчитать площадь этих штриховок (за исключением указанной парочки):





Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Для твоего случая годится такой код:
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.DatabaseServices;
  9. using Autodesk.AutoCAD.Runtime;
  10. using System.IO;
  11.  
  12. namespace electricalPlugin
  13. {
  14.   public class test : IExtensionApplication
  15.   {
  16.     [CommandMethod("test")]
  17.     public void Test()
  18.     {
  19.       Document doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null) return;
  21.       Database db = doc.Database;
  22.       Editor ed = doc.Editor;
  23.  
  24.       TypedValue[] tv = new TypedValue[1];
  25.       tv.SetValue(new TypedValue((int)DxfCode.Start, "HATCH"), 0);
  26.       SelectionFilter sf = new SelectionFilter(tv);
  27.  
  28.       PromptSelectionResult psr = ed.GetSelection(sf);
  29.       if (psr.Status != PromptStatus.OK) return;
  30.  
  31.       using (Transaction tr = db.TransactionManager.StartTransaction())
  32.       {
  33.         foreach (ObjectId id in psr.Value.GetObjectIds())
  34.         {
  35.           if (id.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Hatch))))
  36.           {
  37.             Hatch ent = tr.GetObject(id, OpenMode.ForRead) as Hatch;
  38.             double area = GetHatchArea(ent);
  39.             ed.WriteMessage("\nArea[{0}]={1}",id,area);
  40.           }
  41.         }
  42.         tr.Commit();
  43.       }
  44.     }
  45.  
  46.     double GetHatchArea(Hatch pHatch)
  47.     {
  48.       double area = 0;
  49.       try
  50.       {
  51.         area = pHatch.Area;
  52.       } catch
  53.       {
  54.         int nLoop = pHatch.NumberOfLoops;
  55.         int loopType;
  56.         for (int i = 0; i < nLoop; i++)
  57.         {
  58.           double looparea = 0;
  59.           loopType = (int)pHatch.LoopTypeAt(i);
  60.           if ((loopType & (int)HatchLoopTypes.Polyline) > 0)
  61.           {
  62.             HatchLoop hatchLoop = pHatch.GetLoopAt(i);
  63.             BulgeVertexCollection bulgeVertex = hatchLoop.Polyline;
  64.             using (Polyline pPoly = new Polyline(bulgeVertex.Count))
  65.             {
  66.               for (int j = 0; j < bulgeVertex.Count; j++)
  67.               {
  68.                 pPoly.AddVertexAt(j, bulgeVertex[j].Vertex, bulgeVertex[j].Bulge, 0, 0);
  69.               }
  70.               pPoly.Closed = (loopType & (int)HatchLoopTypes.NotClosed) == 0;
  71.               looparea = pPoly.Area;
  72.               if ((loopType & (int)HatchLoopTypes.External) > 0)
  73.                 area += Math.Abs(looparea);
  74.               else
  75.                 area -= Math.Abs(looparea);
  76.             }
  77.           }
  78.         }
  79.       }
  80.       return Math.Abs(area);
  81.     }
  82.  
  83.     public void Initialize()
  84.     {
  85.     }
  86.  
  87.     public void Terminate()
  88.     {
  89.     }
  90.  
  91.   }
  92. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Александр Ривилис,
да, действительно, не заметил..

для меня остается загадкой, почему после любых манипуляций с контуром (даже которые ничего не меняют) площадь начинает вычисляться?..и каким образом можно программно их сымитировать? я уже кучу методов hatch перебрал..

понял! воспользуюсь пока этим кодом.. спасибо! нечто похожее у меня есть для запоминания координат контура..встрою частично туда..огромное спасибо!

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
понял! воспользуюсь пока этим кодом.. спасибо!
Код не отлаживал. Я взял его из GeomProps и перевёл с ObjectARX (C++) на AutoCAD .NET API (C#). На всякий случай исходник:

Код - C++ [Выбрать]
  1. double GetHatchArea(AcDbHatch *pHatch)
  2. {
  3.   double area = 0;
  4.   int nLoop = pHatch->numLoops();
  5.   Adesk::Int32 loopType;
  6.   for (int i = 0; i < nLoop; i++) {
  7.     double looparea = 0;
  8.     if ((loopType = pHatch->loopTypeAt(i)) & AcDbHatch::kPolyline) {
  9.       AcGePoint2dArray  vertices;
  10.       AcGeDoubleArray   bulges;
  11.       if (pHatch->getLoopAt(i, loopType, vertices, bulges) == Acad::eOk) {
  12.         AcDbPolyline *pPoly = new AcDbPolyline(vertices.length());
  13.         for (int j = 0; j < vertices.length(); j++) {
  14.           pPoly->addVertexAt(j, vertices[j], (bulges.length() < vertices.length()) ? 0.0 : bulges[j]);
  15.         }
  16.         pPoly->setClosed(!(loopType & AcDbHatch::kNotClosed));
  17.         pPoly->getArea(looparea);
  18.         if (loopType & AcDbHatch::kExternal) area += fabs(looparea); else area -= fabs(looparea);
  19.         delete pPoly;
  20.       }
  21.     }
  22.     else {
  23.       AcGeVoidPointerArray edgePtrs;
  24.       AcGeIntArray edgeTypes;
  25.       pHatch->getLoopAt(i, loopType, edgePtrs, edgeTypes);
  26.       AcGeCompositeCurve2d compCurve(edgePtrs);
  27.       AcGeInterval interval;  compCurve.getInterval(interval);
  28.       double pmin, pmax; interval.getBounds(pmin, pmax);
  29.       if (fabs(pmax - pmin) > 1e-6) {
  30.         if (compCurve.area(interval.lowerBound(), interval.upperBound(), looparea)) {
  31.           if (loopType & AcDbHatch::kExternal) area += fabs(looparea); else area -= fabs(looparea);
  32.         }
  33.         else {
  34.           AcGePoint2dArray pts; AcGeDoubleArray pars;
  35.           AcGePoint2d pmin, pmax;
  36.           AcGeBoundBlock2d blk2d = compCurve.boundBlock(interval);
  37.           blk2d.getMinMaxPoints(pmin, pmax);
  38.           double diag = pmin.distanceTo(pmax);
  39.           compCurve.getSamplePoints(interval.lowerBound(), interval.upperBound(), 1e-6 * max(1.0, diag), pts, pars);
  40.           int np = pts.length();
  41.           for (int i = 0; i < np; i++) {
  42.             looparea += 0.5 * pts[i][X] * (pts[(i + 1) % np][Y] - pts[(i + np - 1) % np][Y]);
  43.           }
  44.           if (loopType & AcDbHatch::kExternal) area += fabs(looparea); else area -= fabs(looparea);
  45.         }
  46.       }
  47.     }
  48.   }
  49.   return fabs(area);
  50. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Александр Ривилис,
большое спасибо! а по поводу этого есть какие-нибудь версии у вас?
Цитировать
для меня остается загадкой, почему после любых манипуляций с контуром (даже которые ничего не меняют) площадь начинает вычисляться?..и каким образом можно программно их сымитировать? я уже кучу методов hatch перебрал..

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
а по поводу этого есть какие-нибудь версии у вас?
Версии есть, но до проверок озвучивать их не буду. Одно могу сказать, что программные игры с ручками для этих штриховок не получатся - через API у этих штриховок только по одной ручке.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 9
  • Карма: 0
Александр Ривилис, тоже покопаюсь

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Во вложении файлик, код из http://adn-cis.org/forum/index.php?topic=8128.msg28881#msg28881
вернет для штриховки площадь равную 0
Если удалить самопересечение во внутреннем углу, то все считается нормально

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Во вложении файлик, код из http://adn-cis.org/forum/index.php?topic=8128.msg28881#msg28881
вернет для штриховки площадь равную 0
А GeomProps обрабатывает:



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
И не сомневаюсь, что обрабатывает, однако .Net код нет, а очень хотелось бы.
Причина, я так понимаю в 60 строке и в том, что hatchLoop.Polyline == null
Как обойти и все таки получить площадь?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Как обойти и все таки получить площадь?
Переделать весь мой код на C++ в код на C#, а не только ту часть, которую я переделал под конкретный случай.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Ривилис 14-11-2017, 18:51:31

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Решил сам переделать мой код из C++ в C#. Как всегда оказалось, что кое что в AutoCAD .NET API не работает из того, что работает в ObjectARX. В частности не срабатывает метод Curve2d.GetSamplePoints(double, double, double). Так что пришлось его заменить. В результате код выглядит так:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6. using System;
  7.  
  8. namespace electricalPlugin
  9. {
  10.   public class test : IExtensionApplication
  11.   {
  12.     [CommandMethod("test")]
  13.     public void Test()
  14.     {
  15.       Document doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
  16.       if (doc == null) return;
  17.       Database db = doc.Database;
  18.       Editor ed = doc.Editor;
  19.  
  20.       TypedValue[] tv = new TypedValue[1];
  21.       tv.SetValue(new TypedValue((int)DxfCode.Start, "HATCH"), 0);
  22.       SelectionFilter sf = new SelectionFilter(tv);
  23.  
  24.       PromptSelectionResult psr = ed.GetSelection(sf);
  25.       if (psr.Status != PromptStatus.OK) return;
  26.  
  27.       using (Transaction tr = db.TransactionManager.StartTransaction())
  28.       {
  29.         foreach (ObjectId id in psr.Value.GetObjectIds())
  30.         {
  31.           if (id.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Hatch))))
  32.           {
  33.             Hatch ent = tr.GetObject(id, OpenMode.ForRead) as Hatch;
  34.             double area = GetHatchArea(ent);
  35.             ed.WriteMessage("\nArea[{0}]={1}",id,area);
  36.           }
  37.         }
  38.         tr.Commit();
  39.       }
  40.     }
  41.  
  42.     double GetHatchArea(Hatch pHatch)
  43.     {
  44.       double area = 0;
  45.       try
  46.       {
  47.         area = pHatch.Area;
  48.       } catch
  49.       {
  50.         int nLoop = pHatch.NumberOfLoops;
  51.         int loopType;
  52.         for (int i = 0; i < nLoop; i++)
  53.         {
  54.           double looparea = 0;
  55.           loopType = (int)pHatch.LoopTypeAt(i);
  56.           if ((loopType & (int)HatchLoopTypes.Polyline) > 0)
  57.           {
  58.             HatchLoop hatchLoop = pHatch.GetLoopAt(i);
  59.             BulgeVertexCollection bulgeVertex = hatchLoop.Polyline;
  60.             using (Polyline pPoly = new Polyline(bulgeVertex.Count))
  61.             {
  62.               for (int j = 0; j < bulgeVertex.Count; j++)
  63.               {
  64.                 pPoly.AddVertexAt(j, bulgeVertex[j].Vertex, bulgeVertex[j].Bulge, 0, 0);
  65.               }
  66.               pPoly.Closed = (loopType & (int)HatchLoopTypes.NotClosed) == 0;
  67.               looparea = pPoly.Area;
  68.               if ((loopType & (int)HatchLoopTypes.External) > 0)
  69.                 area += Math.Abs(looparea);
  70.               else
  71.                 area -= Math.Abs(looparea);
  72.             }
  73.           } else
  74.           {
  75.             HatchLoop hatchLoop = pHatch.GetLoopAt(i);
  76.             Curve2d[] cur2ds = new Curve2d[hatchLoop.Curves.Count];
  77.             hatchLoop.Curves.CopyTo(cur2ds, 0);
  78.             using (CompositeCurve2d compCurve = new CompositeCurve2d(cur2ds))
  79.             {
  80.               Interval interval = compCurve.GetInterval();
  81.               double dMin = interval.GetBounds()[0], dMax = interval.GetBounds()[1];
  82.               if (Math.Abs(dMax - dMin) > 1e-6)
  83.               {
  84.                 try
  85.                 {
  86.                   looparea = compCurve.GetArea(dMin, dMax);
  87.                   if ((loopType & (int)HatchLoopTypes.External) > 0)
  88.                     area += Math.Abs(looparea);
  89.                   else
  90.                     area -= Math.Abs(looparea);
  91.                 }
  92.                 catch
  93.                 {
  94.                   // Разбиваем кривую на 1000000 точек. Надеюсь, что такой точности
  95.                   // будет достаточно.
  96.                   Point2d[] pts = compCurve.GetSamplePoints((int)1e+6);
  97.                   int np = pts.Length;
  98.                   for (int j = 0; j < np; j++)
  99.                   {
  100.                     looparea += 0.5 * pts[j].X * (pts[(j + 1) % np].Y - pts[(j + np - 1) % np].Y);
  101.                   }
  102.                   if ((loopType & (int)HatchLoopTypes.External) > 0)
  103.                     area += Math.Abs(looparea);
  104.                   else
  105.                     area -= Math.Abs(looparea);
  106.                 }
  107.               }
  108.             }
  109.           }
  110.         }
  111.       }
  112.       return Math.Abs(area);
  113.     }
  114.  
  115.     public void Initialize()
  116.     {
  117.     }
  118.  
  119.     public void Terminate()
  120.     {
  121.     }
  122.  
  123.   }
  124. }



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Спасибо огромное! Попробовал сам разобраться, получилось не очень.

Оффлайн alz

  • ADN OPEN
  • **
  • Сообщений: 93
  • Карма: 11
Решил сам переделать мой код из C++ в C#. Как всегда оказалось, что кое что в AutoCAD .NET API не работает из того, что работает в ObjectARX. В частности не срабатывает метод Curve2d.GetSamplePoints(double, double, double). Так что пришлось его заменить. В результате код выглядит так:

Я так понимаю код не учитывает вложенность петель, типы петель текстов и различные стили решения островков. Когда он писался этого еще не было или он так и задумывался для самых простейших штриховок?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Решил сам переделать мой код из C++ в C#. Как всегда оказалось, что кое что в AutoCAD .NET API не работает из того, что работает в ObjectARX. В частности не срабатывает метод Curve2d.GetSamplePoints(double, double, double). Так что пришлось его заменить. В результате код выглядит так:

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