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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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





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

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 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 видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение