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

ADN Club => AutoCAD .NET API => Тема начата: Andrey от 28-05-2014, 11:48:38

Название: Площадь Polyline и Hatch
Отправлено: Andrey от 28-05-2014, 11:48:38
Добрый день!
Необходимо получить площади Polyline и Hatch. Вроде ничего сложного, т.к. оба объекта имеют свойства Area.
Но...
Если полилиния не пересекает саму себя, то проблем нет.

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs28.postimg.org%2F5ttwn1nxl%2FPoly_Acad_1.jpg&hash=d9a51f63f320c1e08b94bbdcd0474b2b) (http://postimg.org/image/5ttwn1nxl/)

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs28.postimg.org%2F7x4bupnqh%2FPoly_VS_1.jpg&hash=f2e481c831b7e45408b0473934e10074) (http://postimg.org/image/7x4bupnqh/)

Если есть пересечение, то площадь не соответствует значению в Property.

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs28.postimg.org%2Fbzvctshux%2FPoly_Acad_2.jpg&hash=c2ca04cc415444803203d2dd2938b059) (http://postimg.org/image/bzvctshux/)

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs28.postimg.org%2Fv68jwyycp%2FPoly_VS_2.jpg&hash=3e73fa3bb3d0c86bad57f6ccca5da8e6) (http://postimg.org/image/v68jwyycp/)

С площадью заливок тоже не понятно. При создании заливки из полилинии - значение Area отсутствует.
Код - C# [Выбрать]
  1. Polyline pl = tr.GetObject(ids[i], OpenMode.ForWrite) as Polyline;
  2. if (!plClosed)
  3.     pl.Closed = true;
  4. ObjectIdCollection acObjIdColl = new ObjectIdCollection();
  5. acObjIdColl.Add(pl.ObjectId);
  6. Hatch acHatch = new Hatch();
  7. acBlkTblRec.AppendEntity(acHatch);
  8. tr.AddNewlyCreatedDBObject(acHatch, true);
  9. acHatch.SetDatabaseDefaults();
  10. acHatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
  11. acHatch.Associative = false;
  12. acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
  13. acHatch.EvaluateHatch(true);
  14.  

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs15.postimg.org%2F98ygtr2o7%2Fhatch_vs.jpg&hash=0814a667ce40c129c13efd0a9a74bfe8) (http://postimg.org/image/98ygtr2o7/)

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs15.postimg.org%2Fdw4iviq13%2Fhatch.jpg&hash=07d515fe735fd1c08f376aa021f666df) (http://postimg.org/image/dw4iviq13/)

При создании заливки в ручную проблем нет.

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs27.postimg.org%2Fwlf6ivimn%2Fhatch.jpg&hash=b81419dc6e0c8f58f43f35c2fb8c53e5) (http://postimg.org/image/wlf6ivimn/)
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 12:22:08
Если есть пересечение, то площадь не соответствует значению в Property.
Если есть самопересечение, то площадь не имеет смысла. Да и не думаю, что с такими полилиниями имеет смысл работать. Я бы сообщил пользователю, что полилиния некорректная. А на рисунках у тебя вообще как я понял разомкнутые полилинии.
Что касается штриховок, то площадь у них есть и при создании программно.
Нужен полный код, пример полилинии из которой создаешь штриховку (в dwg-файле), версия AutoCAD
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 28-05-2014, 12:51:35
Работать с такими полилиниями есть смысл: необходимо получить программу суммирования длин и площадей выбранных полилиний.
Т.к. с area полилиний не получилось решил пробовать через создание штриховок.
Вне зависимости от разомкнутости и самопересечения - поле area даёт точную характеристику.
Версия 2014.
         
Код - C# [Выбрать]
  1.    DocumentCollection acDocMgr = acApp.DocumentManager;
  2.             Document acDoc = acDocMgr.MdiActiveDocument;
  3.             Database acCurDb = acDoc.Database;
  4.             Editor ed = acDoc.Editor;
  5.             int polies = 0;
  6.             double totalArea = 0;
  7.             double totalLength = 0;
  8.             using (DocumentLock docLock = acDoc.LockDocument())
  9.             {
  10.                 using (Transaction tr = acCurDb.TransactionManager.StartTransaction())
  11.                 {
  12.                     BlockTable acBlkTbl = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  13.                     BlockTableRecord acBlkTblRec = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  14.  
  15.                     TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") };
  16.                     SelectionFilter filter = new SelectionFilter(filList);
  17.                     PromptSelectionOptions opts = new PromptSelectionOptions();
  18.                     opts.MessageForAdding = "Select polylines: ";
  19.                     PromptSelectionResult res = ed.GetSelection(opts, filter);
  20.                      if (res.Status != PromptStatus.OK)
  21.                         return;
  22.                     SelectionSet selSet = res.Value;
  23.                     ObjectId[] ids = selSet.GetObjectIds();
  24.                     for (int i = 0; i < ids.Length; i++)
  25.                     {
  26.                         Polyline pl = tr.GetObject(ids[i], OpenMode.ForWrite) as Polyline;
  27.                         totalLength += pl.Length;
  28.                         bool plClosed = pl.Closed;
  29.  
  30.                         if (!plClosed)
  31.                             pl.Closed = true;
  32.                         ObjectIdCollection acObjIdColl = new ObjectIdCollection();
  33.                         acObjIdColl.Add(pl.ObjectId);
  34.  
  35.                         Hatch acHatch = new Hatch();
  36.                         acBlkTblRec.AppendEntity(acHatch);
  37.                         tr.AddNewlyCreatedDBObject(acHatch, true);
  38.  
  39.                         acHatch.SetDatabaseDefaults();
  40.                         acHatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
  41.                         acHatch.Associative = false;
  42.                         acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
  43.                         acHatch.EvaluateHatch(true);
  44.                         totalArea += acHatch.Area;
  45.  
  46.                         if (!plClosed)
  47.                             pl.Closed = false;
  48.  
  49.                         pl.Highlight();
  50.                         polies++;
  51.                     }
  52.                     ed.SetImpliedSelection(ids);
  53.                     tr.Commit();
  54.                 }
  55.                 totalLength = Math.Round(totalLength, 4);
  56.                 totalArea = Math.Round(totalArea, 4);
  57.                 ed.WriteMessage("\nPolylines - {0}. Total Length = {1}. Total Area = {2}.",
  58.                            polies.ToString(), totalLength.ToString(), totalArea.ToString());
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 13:38:05
Попробуй без штриховки:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Interop;
  8. using Autodesk.AutoCAD.Interop.Common;
  9. using AcRx = Autodesk.AutoCAD.Runtime;
  10. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  11. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  12. using AcGe = Autodesk.AutoCAD.Geometry;
  13. using AcEd = Autodesk.AutoCAD.EditorInput;
  14. using AcInt = Autodesk.AutoCAD.Interop;
  15. using AcIntCom = Autodesk.AutoCAD.Interop.Common;
  16.  
  17. [assembly: CommandClass(typeof(TestArea.MyCommands))]
  18.  
  19. namespace TestArea
  20. {
  21.   public class MyCommands
  22.   {
  23.     [CommandMethod("TestArea", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
  24.     public void test()
  25.     {
  26.       DocumentCollection acDocMgr = AcAp.Application.DocumentManager;
  27.       Document acDoc = acDocMgr.MdiActiveDocument;
  28.       Database acCurDb = acDoc.Database;
  29.       Editor ed = acDoc.Editor;
  30.       int polies = 0;
  31.       double totalArea = 0, totalAreaCOM = 0;
  32.       double totalLength = 0;
  33.       ObjectId[] ids;
  34.       using (DocumentLock docLock = acDoc.LockDocument()) {
  35.         using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) {
  36.           TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") };
  37.           SelectionFilter filter = new SelectionFilter(filList);
  38.           PromptSelectionOptions opts = new PromptSelectionOptions();
  39.           opts.MessageForAdding = "Select polylines: ";
  40.           PromptSelectionResult res = ed.GetSelection(opts, filter);
  41.           if (res.Status != PromptStatus.OK)
  42.             return;
  43.           SelectionSet selSet = res.Value;
  44.           ids = selSet.GetObjectIds();
  45.           for (int i = 0; i < ids.Length; i++) {
  46.             Polyline pl = tr.GetObject(ids[i], OpenMode.ForRead) as Polyline;
  47.             AcIntCom.AcadLWPolyline plCOM = pl.AcadObject as AcIntCom.AcadLWPolyline;
  48.             totalArea += pl.Area;
  49.             totalAreaCOM += plCOM.Area;
  50.             totalLength += pl.Length;
  51.             pl.Highlight();
  52.             polies++;
  53.           }
  54.           tr.Commit();
  55.         }
  56.       }
  57.       ed.SetImpliedSelection(ids);
  58.       totalLength = Math.Round(totalLength, 4);
  59.       totalArea = Math.Round(totalArea, 4);
  60.       ed.WriteMessage("\nPolylines - {0}. Total Length = {1}. Total Area = {2}.  Total Area COM = {3}.",
  61.                  polies.ToString(), totalLength.ToString(), totalArea.ToString(), totalAreaCOM.ToString());
  62.     }
  63.   }
  64. }
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 13:39:57
P.S.: Но если ты не будешь сообщать пользователю, что полилиния самопересекающаяся - это будет очень плохо.
Название: Re: Площадь Polyline и Hatch
Отправлено: Андрей Бушман от 28-05-2014, 14:06:35
Код - C# [Выбрать]
  1. Document acDoc = acDocMgr.MdiActiveDocument;
  2. Database acCurDb = acDoc.Database;
  3. Editor ed = acDoc.Editor;
Рекомендую взять за правило выполнять проверку MdiActiveDocument на равенство null, прежде чем начинать работать с ним.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 28-05-2014, 14:36:40
Спасибо, работает! Есть  какая либо документация о разнице объектов NET и COM?
P.S.: Но если ты не будешь сообщать пользователю, что полилиния самопересекающаяся - это будет очень плохо.
В моём случае могут быть контуры одной полилинией
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs1.postimg.org%2Fogmxompjv%2Fimage.jpg&hash=05435a3e41da3dd65e368842f2490b7e) (http://postimg.org/image/ogmxompjv/)
Заливки. Сейчас заметил, что заливки, полученные из MPolygon (по предыдущей теме) тоже получаются без геометрии Area.
Если их создавать как COM
Код - C# [Выбрать]
  1. Hatch h = new Hatch();
  2. AcIntCom.AcadHatch acHatch = h.AcadObject as AcIntCom.AcadHatch;
то как добавлять в транзакцию? Или есть другие способы?
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 28-05-2014, 14:39:24
Рекомендую взять за правило выполнять проверку MdiActiveDocument на равенство null, прежде чем начинать работать с ним.
Буду иметь в виду.
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 14:43:14
Спасибо, работает! Есть  какая либо документация о разнице объектов NET и COM?
Есть документация по AutoCAD AciveX/COM API и есть по AutoCAD .NET API. Это независимые API, но имеют некоторое пересечение по функциональности.
Заливки. Сейчас заметил, что заливки, полученные из MPolygon (по предыдущей теме) тоже получаются без геометрии Area.
Странно, но почему так я предположить не могу.
то как добавлять в транзакцию? Или есть другие способы?
Зачем? По этим обрывкам мыслей и кода я не могу понять что ты собираешься получить в конце.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 28-05-2014, 16:07:53
что ты собираешься получить в конце.
Получить надо Hatch из Polyline или MPolygon с геометрией Area
Код
Код - C# [Выбрать]
  1. MPolygon plg = trans.GetObject(id, OpenMode.ForWrite, false) as AcDb.MPolygon;
  2. Hatch acHatch = plg.Hatch.Clone() as Hatch;
  3. BlockTblRec.AppendEntity(acHatch);
  4. trans.AddNewlyCreatedDBObject(acHatch, true);
и
Код - C# [Выбрать]
  1. Polyline pl = tr.GetObject(ids[i], OpenMode.ForWrite) as Polyline;
  2. bool plClosed = pl.Closed;
  3. if (!plClosed)
  4.    pl.Closed = true;
  5. ObjectIdCollection acObjIdColl = new ObjectIdCollection();
  6. acObjIdColl.Add(pl.ObjectId);
  7. Hatch acHatch = new Hatch();
  8. acBlkTblRec.AppendEntity(acHatch);
  9. tr.AddNewlyCreatedDBObject(acHatch, true);
  10. acHatch.SetDatabaseDefaults();
  11. acHatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
  12. acHatch.Associative = false;
  13. acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
  14. acHatch.EvaluateHatch(true);
Не позволяют этого сделать
Можно ли решить эту задачу с помощью COM? Если да, то каким образом объекты COM подтверждаются в транзакции?
Название: Re: Площадь Polyline и Hatch
Отправлено: Андрей Бушман от 28-05-2014, 16:19:44
каким образом объекты COM подтверждаются в транзакции?
Несколько раз прочёл, но так и не понял этой фразы.
Название: Re: Площадь Polyline и Hatch
Отправлено: Дима_ от 28-05-2014, 16:22:16
Если да, то каким образом объекты COM подтверждаются в транзакции?
Никаим - они друг о друге ничего не знают, все "общее"здесь - это COM может объявить о начале и конце отмены - метод Document'а Start/EndUndoMark.
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 16:44:07
Получить надо Hatch из Polyline или MPolygon с геометрией Area
Похоже это в общем случае нереально. Я посмотрел что штриховки (Hatch) достаточно часто не имеют площади. Так что считать тебе придется самостоятельно не полагаясь на свойство Area (ни из AutoCAD .NET API, ни из AutoCAD ActiveX/COM). Во всяком случае если они приводят к exception или значения Hatch.Area и AcadHatch.Area не совпадают.
Алгоритма полного у меня нет, но эти статьи могут помочь:
Периметр штриховки с помощью ObjectARX и .NET API (http://adn-cis.org/perimetr-shtrixovki-s-pomoshhyu-objectarx-i-.net-api.html)
Как восстановить потерянные границы штриховки? (http://adn-cis.org/kak-vosstanovit-poteryannyie-graniczyi-shtrixovki.html)
Название: Re: Площадь Polyline и Hatch
Отправлено: Андрей Бушман от 28-05-2014, 16:49:15
Ещё площади есть у областей (Region).
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 16:56:59
Ещё площади есть у областей (Region).
Насколько мне известно точность вычисления площади у Region значительно ниже, чем у Polyline/Hatch. Относительная погрешность не меньше чем 1e-6. Во всяком случае если мне не изменяет память.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 28-05-2014, 17:12:27
С заливками удобнее работать в, при выборе нескольких автоматически вычисляется общая площадь
на рисунке заливки, созданные вручную
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs18.postimg.org%2Fljwaoqz1x%2Fhatches.jpg&hash=f9cd07e557a4f64316b8961502cb7d33) (http://postimg.org/image/ljwaoqz1x/)
у "программных" такого нет
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs28.postimg.org%2Fikjv9c1gp%2Fhatches2.jpg&hash=e9b74d1f4dc11a2e145810fe3952c9c2) (http://postimg.org/image/ikjv9c1gp/)
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 28-05-2014, 19:47:30
на рисунке заливки, созданные вручную
И? Судя во всему программно так сделать не получится. Впрочем по возможности проверю.
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 29-05-2014, 01:01:47
Итак вот этот код у меня на основе выбранных полилиний создает нормальную штриховку - у которой в панели свойств есть ненулевая площадь:
Код - C# [Выбрать]
  1. [CommandMethod("CrHatch")]
  2. public void TestCrHatch()
  3. {
  4.   Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  5.   Database db = doc.Database;
  6.   Editor ed = doc.Editor;
  7.   ObjectIdCollection ids;
  8.   ObjectId idHatch;
  9.   try {
  10.     using (DocumentLock docLock = doc.LockDocument()) {
  11.       TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") };
  12.       SelectionFilter filter = new SelectionFilter(filList);
  13.       PromptSelectionOptions opts = new PromptSelectionOptions();
  14.       opts.SinglePickInSpace = true; opts.SingleOnly = true;
  15.       opts.MessageForAdding = "Выберите полилинию: ";
  16.       PromptSelectionResult res = ed.GetSelection(opts, filter);
  17.       if (res.Status != PromptStatus.OK)
  18.         return;
  19.       SelectionSet selSet = res.Value;
  20.       ids = new ObjectIdCollection(selSet.GetObjectIds());
  21.       using (Hatch hatch = new Hatch()) {
  22.         using (BlockTableRecord btr = db.CurrentSpaceId.Open(OpenMode.ForWrite) as BlockTableRecord) {
  23.           hatch.SetDatabaseDefaults(db);
  24.           hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
  25.           idHatch = btr.AppendEntity(hatch);
  26.           hatch.Associative = true;
  27.           hatch.AppendLoop(HatchLoopTypes.External, ids);
  28.           hatch.EvaluateHatch(false);
  29.           ed.WriteMessage("\nПлощадь={0}", hatch.Area);
  30.         }
  31.       }
  32.     }
  33.   } catch { };
  34. }
Похоже главное отличие в том, что у меня hatch.AppendLoop(HatchLoopTypes.External, ids);
Если выбранная полилиния не замкнутая или самопересекающаяся, то площади нет.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 29-05-2014, 13:19:26
Отлично!
Получается из самопересекающейся полилинии тоже можно сделать заливку с площадью, если получить полилинии между пересечениями.
А как решить проблему с полигонами? У MPolygon уже не подправить HatchLoopTypes.
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 29-05-2014, 13:22:57
А как решить проблему с полигонами? У MPolygon уже не подправить HatchLoopTypes.
Почему же не подправить? Нужно проанализировать получившийся Hatch и на основе его сделать новый, но с правильными Loop.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 29-05-2014, 17:30:38
Нужно проанализировать получившийся Hatch и на основе его сделать новый, но с правильными Loop.
Да, так и получилось из MPolygon получить заливку с площадью
Код - C# [Выбрать]
  1. AcDb.MPolygon plg = trans.GetObject(id, OpenMode.ForWrite, false) as AcDb.MPolygon;
  2. Hatch acHatch = new Hatch();
  3. BlockTblRec.AppendEntity(acHatch);
  4.  trans.AddNewlyCreatedDBObject(acHatch, true);
  5.  
  6. acHatch.SetDatabaseDefaults();
  7. acHatch.SetHatchPattern(HatchPatternType.PreDefined, "ZIGZAG");
  8. acHatch.Associative = false;
  9. int numloop = plg.Hatch.NumberOfLoops;
  10. for (int l = 0; l < numloop; l++)
  11.       {
  12.         HatchLoop hatchlloop = plg.Hatch.GetLoopAt(l);
  13.         BulgeVertexCollection vertcol = hatchlloop.Polyline;
  14.          Polyline polyloop = new Polyline();
  15.           for (int v = 0; v < vertcol.Count; v++)
  16.                 {
  17.                     BulgeVertex vert = vertcol[v];
  18.                      polyloop.AddVertexAt(v, vert.Vertex, 0, 0, 0);
  19.                  }
  20.          BlockTblRec.AppendEntity(polyloop);
  21.         trans.AddNewlyCreatedDBObject(polyloop, true);
  22.         if (!polyloop.Closed)
  23.              polyloop.Closed = true;
  24.  
  25.           ObjectIdCollection acObjIdColl = new ObjectIdCollection();
  26.           acObjIdColl.Add(polyloop.ObjectId);
  27.  
  28.          acHatch.AppendLoop(HatchLoopTypes.External, acObjIdColl);
  29.  
  30.           polyloop.Erase(true);
  31.         }
  32. acHatch.HatchStyle = HatchStyle.Normal;
  33. acHatch.EvaluateHatch(true);
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 29-05-2014, 17:46:18
Код не проверял, но есть пару замечаний:
1. Если штриховка содержит несколько петель (Loop), то толко одна из них может быть HatchLoopTypes.External. Остальные рекомендуется ставить HatchLoopTypes.Default
2. Можно обойтись без создания временных полилиний, которые потом еще и удаляются если воспользоваться методом
Hatch.AppendLoop Method (HatchLoopTypes, Point2dCollection, DoubleCollection)
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 30-05-2014, 11:34:19
1. Если штриховка содержит несколько петель (Loop), то толко одна из них может быть HatchLoopTypes.External. Остальные рекомендуется ставить HatchLoopTypes.Default
2. Можно обойтись без создания временных полилиний, которые потом еще и удаляются если воспользоваться методом
Hatch.AppendLoop Method (HatchLoopTypes, Point2dCollection, DoubleCollection)
1. MPolygon приходят из MapInfo и все Loop имеет тип Polyline, даже если состоят из одного контура. А при добавлении всех Loop как HatchLoopTypes.Default пропадает Area.
2. Так действительно лучше:
Код - C# [Выбрать]
  1.                                     for (int l = 0; l < plg.Hatch.NumberOfLoops; l++)
  2.                                     {
  3.                                         HatchLoop hatchlloop = plg.Hatch.GetLoopAt(l);
  4.                                         BulgeVertexCollection bulgeVertexCol = hatchlloop.Polyline;
  5.                                         Point2dCollection vertexCol = new Point2dCollection();
  6.                                         DoubleCollection bulgeCol = new DoubleCollection();
  7.                                         for (int v = 0; v < bulgeVertexCol.Count; v++)
  8.                                         {
  9.                                             BulgeVertex bulgeVertex = bulgeVertexCol[v];
  10.                                             vertexCol.Add(bulgeVertex.Vertex);
  11.                                             bulgeCol.Add(bulgeVertex.Bulge);  
  12.                                         }
  13.                                         acHatch.AppendLoop(HatchLoopTypes.External, vertexCol, bulgeCol);
  14.                                     }
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 30-05-2014, 13:07:24
А при добавлении всех Loop как HatchLoopTypes.Default пропадает Area.
Я имел в виду что внешний контур добавляется как HatchLoopTypes.External, а остальные как HatchLoopTypes.Default
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 30-05-2014, 13:22:09
MPolygon приходят из MapInfo
Кстати, это утверждение не верно в общем случае, так как MPolygon можно создать в чистом AutoCAD средствами ObjectARX/AutoCAD .NET API.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 30-05-2014, 15:18:46
Имел ввиду, что "мои" MPolygon приходят из MapInfo и у них все контуры HatchLoopTypes.Polyline
Пример
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 30-05-2014, 21:04:45
Имел ввиду, что "мои" MPolygon приходят из MapInfo и у них все контуры HatchLoopTypes.Polyline
Пример
Андрей. Ты не понимаешь о чем я говорю. Вот код:
Код - C# [Выбрать]
  1. [CommandMethod("MPtoHatch")]
  2. public void TestMPtoHatch()
  3. {
  4.   Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  5.   Database db = doc.Database;
  6.   Editor ed = doc.Editor;
  7.   ObjectIdCollection ids;
  8.   ObjectId idHatch;
  9.   try {
  10.     using (DocumentLock docLock = doc.LockDocument()) {
  11.       TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "MPOLYGON") };
  12.       SelectionFilter filter = new SelectionFilter(filList);
  13.       PromptSelectionOptions opts = new PromptSelectionOptions();
  14.       opts.MessageForAdding = "Выберите MPolygon'ы: ";
  15.       PromptSelectionResult res = ed.GetSelection(opts, filter);
  16.       if (res.Status != PromptStatus.OK)
  17.         return;
  18.       SelectionSet selSet = res.Value;
  19.       ids = new ObjectIdCollection(selSet.GetObjectIds());
  20.       using (BlockTableRecord btr = db.CurrentSpaceId.Open(OpenMode.ForWrite) as BlockTableRecord) {
  21.         foreach (ObjectId id in ids) {
  22.           using (MPolygon mp = id.Open(OpenMode.ForRead) as MPolygon) {
  23.             using (Hatch hatch = new Hatch()) {
  24.               hatch.SetDatabaseDefaults(db);
  25.               hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
  26.               idHatch = btr.AppendEntity(hatch);
  27.               hatch.Associative = false;
  28.               for (int i = 0; i < mp.NumMPolygonLoops; i++) {
  29.                 MPolygonLoop mpLoop = mp.GetMPolygonLoopAt(i);
  30.                 Point2dCollection vertexCol = new Point2dCollection();
  31.                 DoubleCollection bulgeCol = new DoubleCollection();
  32.                 for (int j = 0; j < mpLoop.Count; j++) {
  33.                   vertexCol.Add(mpLoop[j].Vertex);
  34.                   bulgeCol.Add(mpLoop[j].Bulge);
  35.                 }
  36.                 HatchLoopTypes loopType = (i == 0) ? HatchLoopTypes.External : HatchLoopTypes.Default;
  37.                 hatch.AppendLoop(loopType, vertexCol, bulgeCol);
  38.               }
  39.               hatch.EvaluateHatch(false);
  40.               ed.WriteMessage("\nПлощадь={0}", hatch.Area);
  41.             }
  42.           }
  43.         }
  44.       }
  45.     }
  46.   } catch { };
  47. }
  48.  
Обрати внимание на строку:
Код - C# [Выбрать]
  1. HatchLoopTypes loopType = (i == 0) ? HatchLoopTypes.External : HatchLoopTypes.Default;
Т.е. первый контур (внешний) идет с HatchLoopTypes.External, а остальные с HatchLoopTypes.Default
На твоём чертеже проверил. Площади исходных MPolygon и полученных штриховок совпадают.
Название: Re: Площадь Polyline и Hatch
Отправлено: Andrey от 02-06-2014, 12:11:51
Получается, что внешним идет всегда только первый контур и в заливках, и в полигонах.
Название: Re: Площадь Polyline и Hatch
Отправлено: MDA от 18-08-2020, 16:39:06
Здравствуйте коллеги!

Посмотрел статью, но пока не нашел ответа на свой вопрос. Как дать понять что параметр "Area" отсутствует. Пробовал через if (htc.Area != double.NaN) не помогло.
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 18-08-2020, 17:21:44
Посмотрел статью, но пока не нашел ответа на свой вопрос. Как дать понять что параметр "Area" отсутствует.
Что имеется в виду под отсутствующей площадью?
Название: Re: Площадь Polyline и Hatch
Отправлено: MDA от 18-08-2020, 20:22:17
Посмотрел статью, но пока не нашел ответа на свой вопрос. Как дать понять что параметр "Area" отсутствует.
Что имеется в виду под отсутствующей площадью?

При выборе штриховки отсутствует свойство площади. А мне нужно дать понять в условии что если отсутствует этот атрибут, то выполнять другое условие.
            if (htc.Area != double.NaN)
            ExportWord.ExportTableMinEnergo1(pLines, htc.Area, mtt1[0].ToString().Trim(), posf);
            else
            ExportWord.ExportTableMinEnergo2(pLines, mtt1[0].ToString().Trim(), posf);
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 18-08-2020, 21:37:16
Посмотрел статью, но пока не нашел ответа на свой вопрос. Как дать понять что параметр "Area" отсутствует.
Что имеется в виду под отсутствующей площадью?

При выборе штриховки отсутствует свойство площади. А мне нужно дать понять в условии что если отсутствует этот атрибут, то выполнять другое условие.
            if (htc.Area != double.NaN)
            ExportWord.ExportTableMinEnergo1(pLines, htc.Area, mtt1[0].ToString().Trim(), posf);
            else
            ExportWord.ExportTableMinEnergo2(pLines, mtt1[0].ToString().Trim(), posf);
А какое у тебя значение получается в этом случае?
Название: Re: Площадь Polyline и Hatch
Отправлено: Александр Ривилис от 18-08-2020, 21:49:37
Вообще посмотри вот этот код, который вычисляет площадь штриховки, которую сам AutoCAD не вычисляет: https://adn-cis.org/forum/index.php?topic=8128.msg29013#msg29013
Название: Re: Площадь Polyline и Hatch
Отправлено: MDA от 20-08-2020, 23:11:27
Огромное спасибо. Проблема решена!