Выделение и отображение примитива Civil

Автор Тема: Выделение и отображение примитива Civil  (Прочитано 12627 раз)

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

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

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

Отмечено как Решение D_TRex 28-02-2023, 12:52:32

Оффлайн alz

  • ADN OPEN
  • **
  • Сообщений: 97
  • Карма: 11
Гугл сломался? ))) Задача то простая, накидал по быстрому, вроде работает, может даже когда-то пригодится)

Код - C# [Выбрать]
  1. Document aDoc = Application.DocumentManager.MdiActiveDocument;
  2. Editor ed = aDoc.Editor;
  3. Database db = aDoc.Database;
  4. using (Transaction tr = db.TransactionManager.StartTransaction())
  5. {
  6.     //получаем трубу
  7.     using (Pipe pipe = tr.GetObject(obid, OpenMode.ForRead, false, true) as Pipe)
  8.     {
  9.         if (!pipe.OwnerId.Equals(db.CurrentSpaceId))
  10.                 {
  11.                     tr.Commit();
  12.                     return;
  13.                 }
  14.         //если у трубы есть границы, фиг знает в каких случаях их нет но походу это возможно
  15.         if (pipe.Bounds.HasValue)
  16.         {                      
  17.             Extents3d extents = pipe.Bounds.Value;
  18.             //получаем текущий вид
  19.             using (ViewTableRecord view = ed.GetCurrentView())
  20.             {
  21.                 // Translate WCS coordinates to DCS
  22.                 // кусок кода из интернета, получает матрицу для перевода координат мировой системы
  23.                 // в систему координат экрана и переводит координаты границ трубы в координаты экрана
  24.                 // как работает хз, разбираться надо
  25.                 Matrix3d matWCS2DCS;                          
  26.                 matWCS2DCS = Matrix3d.PlaneToWorld(view.ViewDirection);                                      
  27.                 matWCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin) * matWCS2DCS;                        
  28.                 matWCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) * matWCS2DCS;                          
  29.                 matWCS2DCS = matWCS2DCS.Inverse();
  30.                 extents.TransformBy(matWCS2DCS);
  31.                 //устанавливаем центральную точку на центр объекта и габариты экрана на габариты объекта
  32.                 view.CenterPoint = new Point2d((extents.MinPoint.X + extents.MaxPoint.X)/2, (extents.MinPoint.Y + extents.MaxPoint.Y) / 2);
  33.                 view.Height = extents.MaxPoint.Y - extents.MinPoint.Y;
  34.                 view.Width = extents.MaxPoint.X - extents.MinPoint.X;                            
  35.                 //устанавливаем вид по исправленному
  36.                 ed.SetCurrentView(view);                        
  37.             }
  38.         }  
  39.     }
  40.     ed.SetImpliedSelection(new List<ObjectId> { obid } .ToArray());
  41.     tr.Commit();
  42. }
« Последнее редактирование: 28-02-2023, 07:02:48 от alz »

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

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Здравствуйте, нет гугл не сломался, просто может потому что я ищу на VB потому и не нахожу, может запрос не верно пишу, спасибо Вам и за ответ и за намёк что лучше искать чем спрашивать на специализированном форуме. Нашёл я решение почти в тот же день в справке, вот может тоже кому пригодится
Код - vb.net [Выбрать]
  1. Public Sub Zoom(ByVal pMin As Point3d, ByVal pMax As Point3d, ByVal pCenter As Point3d, ByVal dFactor As Double)
  2.         '' Get the current document and database
  3.         Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
  4.         Dim acCurDb As Database = acDoc.Database
  5.  
  6.         Dim nCurVport As Integer = System.Convert.ToInt32(Application.GetSystemVariable("CVPORT"))
  7.  
  8.         '' Get the extents of the current space when no points
  9.         '' or only a center point is provided
  10.         '' Check to see if Model space is current
  11.         If acCurDb.TileMode = True Then
  12.             If pMin.Equals(New Point3d()) = True And
  13.                 pMax.Equals(New Point3d()) = True Then
  14.  
  15.                 pMin = acCurDb.Extmin
  16.                 pMax = acCurDb.Extmax
  17.             End If
  18.         Else
  19.             '' Check to see if Paper space is current
  20.             If nCurVport = 1 Then
  21.                 If pMin.Equals(New Point3d()) = True And
  22.                     pMax.Equals(New Point3d()) = True Then
  23.  
  24.                     pMin = acCurDb.Pextmin
  25.                     pMax = acCurDb.Pextmax
  26.                 End If
  27.             Else
  28.                 '' Get the extents of Model space
  29.                 If pMin.Equals(New Point3d()) = True And
  30.                     pMax.Equals(New Point3d()) = True Then
  31.  
  32.                     pMin = acCurDb.Extmin
  33.                     pMax = acCurDb.Extmax
  34.                 End If
  35.             End If
  36.         End If
  37.  
  38.         '' Start a transaction
  39.         Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  40.             '' Get the current view
  41.             Using acView As ViewTableRecord = acDoc.Editor.GetCurrentView()
  42.                 Dim eExtents As Extents3d
  43.  
  44.                 '' Translate WCS coordinates to DCS
  45.                 Dim matWCS2DCS As Matrix3d
  46.                 matWCS2DCS = Matrix3d.PlaneToWorld(acView.ViewDirection)
  47.                 matWCS2DCS = Matrix3d.Displacement(acView.Target - Point3d.Origin) * matWCS2DCS
  48.                 matWCS2DCS = Matrix3d.Rotation(-acView.ViewTwist,
  49.                                                acView.ViewDirection,
  50.                                                acView.Target) * matWCS2DCS
  51.  
  52.                 '' If a center point is specified, define the min and max
  53.                 '' point of the extents
  54.                 '' for Center and Scale modes
  55.                 If pCenter.DistanceTo(Point3d.Origin) <> 0 Then
  56.                     pMin = New Point3d(pCenter.X - (acView.Width / 2),
  57.                                        pCenter.Y - (acView.Height / 2), 0)
  58.  
  59.                     pMax = New Point3d((acView.Width / 2) + pCenter.X,
  60.                                        (acView.Height / 2) + pCenter.Y, 0)
  61.                 End If
  62.  
  63.                 '' Create an extents object using a line
  64.                 Using acLine As Line = New Line(pMin, pMax)
  65.                     eExtents = New Extents3d(acLine.Bounds.Value.MinPoint,
  66.                                              acLine.Bounds.Value.MaxPoint)
  67.                 End Using
  68.  
  69.                 '' Calculate the ratio between the width and height of the current view
  70.                 Dim dViewRatio As Double
  71.                 dViewRatio = (acView.Width / acView.Height)
  72.  
  73.                 '' Tranform the extents of the view
  74.                 matWCS2DCS = matWCS2DCS.Inverse()
  75.                 eExtents.TransformBy(matWCS2DCS)
  76.  
  77.                 Dim dWidth As Double
  78.                 Dim dHeight As Double
  79.                 Dim pNewCentPt As Point2d
  80.  
  81.                 '' Check to see if a center point was provided (Center and Scale modes)
  82.                 If pCenter.DistanceTo(Point3d.Origin) <> 0 Then
  83.                     dWidth = acView.Width
  84.                     dHeight = acView.Height
  85.  
  86.                     If dFactor = 0 Then
  87.                         pCenter = pCenter.TransformBy(matWCS2DCS)
  88.                     End If
  89.  
  90.                     pNewCentPt = New Point2d(pCenter.X, pCenter.Y)
  91.                 Else '' Working in Window, Extents and Limits mode
  92.                     '' Calculate the new width and height of the current view
  93.                     dWidth = eExtents.MaxPoint.X - eExtents.MinPoint.X
  94.                     dHeight = eExtents.MaxPoint.Y - eExtents.MinPoint.Y
  95.  
  96.                     '' Get the center of the view
  97.                     pNewCentPt = New Point2d(((eExtents.MaxPoint.X + eExtents.MinPoint.X) * 0.5),
  98.                                              ((eExtents.MaxPoint.Y + eExtents.MinPoint.Y) * 0.5))
  99.                 End If
  100.  
  101.                 '' Check to see if the new width fits in current window
  102.                 If dWidth > (dHeight * dViewRatio) Then dHeight = dWidth / dViewRatio
  103.  
  104.                 '' Resize and scale the view
  105.                 If dFactor <> 0 Then
  106.                     acView.Height = dHeight * dFactor
  107.                     acView.Width = dWidth * dFactor
  108.                 End If
  109.  
  110.                 '' Set the center of the view
  111.                 acView.CenterPoint = pNewCentPt
  112.  
  113.                 '' Set the current view
  114.                 acDoc.Editor.SetCurrentView(acView)
  115.             End Using
  116.  
  117.             '' Commit the changes
  118.             acTrans.Commit()
  119.         End Using
  120.     End Sub
Вы мне в своё время очень помогли (если я правильно помню), потому что я после простого автокада ни как не мог понять как и к чему обращаться, но Ваш ответ не полный, мне нужно было не только приблизить, но и выделить элемент. Поэтому пометить решением ни как не могу.

Оффлайн alz

  • ADN OPEN
  • **
  • Сообщений: 97
  • Карма: 11
мне нужно было не только приблизить, но и выделить элемент
Сори, не заметил про выделение, добавил одну строчку перед коммитом)

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

Код - C# [Выбрать]
  1. if (!pipe.OwnerId.Equals(db.CurrentSpaceId))
  2.                     {
  3.                         tr.Commit();
  4.                         return;
  5.                     }

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

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Обязательно попробую, правда пока по написанному не похожу на выделение элемента.
Я не то что бы работаю, для нормальной работы надо как то таблицу обновлять при изменении, просто родная кадовская таблица ужасно тормозит при перемещении, нет возможности группового редактирования семейства труб (колодцев) нет возможности задать глубину заложения - иногда отсутствует поверхность (не выдали ещё топографы) и все трубы и колодцы в отметке ноль (может я конечно просто не умею) но нет функции поднять трубы, только колодцы подтягиваются.

Не смог конвертировать эту строку, но без неё тоже работает, там ссылка на SelectionSet.
Код - vb.net [Выбрать]
  1.  ed.SetImpliedSelection(new List<ObjectId> { obid } .ToArray());

а под выбором я вот что имел в виду, конечно это не критично, но тогда не надо панорамировать объект что бы изменить его свойства.
« Последнее редактирование: 28-02-2023, 10:31:26 от D_TRex »

Оффлайн alz

  • ADN OPEN
  • **
  • Сообщений: 97
  • Карма: 11
В общем немного непонятно что же надо, код выше прекрасно выделяет и фокусирует на объекте

Остальные вопросы к этой теме не относятся, по правилам нужно создавать отдельные темы, но просто советую изучить информацию отсюда
http://docs.autodesk.com/CIV3D/2018/ENU/API_Reference_Guide/index.html  вот тут я нашел больше всего полезной информации
Autodesk.Civil.DatabaseServices Namespace в этом разделе по элементам(колодцы трубы сети поверхности)
Autodesk.Civil.DatabaseServices.Styles Namespace тут по стилям отображения всего что было выше указано

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

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Видео с ограниченным доступом - в общем мне не доступно.
У меня почему то код только фокусирует экран, но не выделяет, может быть огрехи конвертации - буду пробовать.
За ссылку отдельное спасибо.
Вопросов больше не было, просто Вы спросили что это, я в двух словах описал.

Хотя возможно вот тут недопонимание
Код - vb.net [Выбрать]
  1. using (Pipe pipe = tr.GetObject(obid, OpenMode.ForRead, false, true) as Pipe)
Код - vb.net [Выбрать]
  1. obid
я беру из списка труб, у Вас я может не заметил где объявлен

Оффлайн alz

  • ADN OPEN
  • **
  • Сообщений: 97
  • Карма: 11
Видео давно не выкладывал, там теперь доступ открывать, возрастные ограничения тд, вроде открыл. По поводу obid - это был кусок кода с конкретно этим функционалом obid это ObjectId трубы, каким образом его получать это другой вопрос, я получал из формы, вот полный код немного причесанный

Код - 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.Collections.Generic;
  7.  
  8.  
  9. namespace test2
  10. {    public class Test99
  11.      {
  12.         //переменная для принятия Id трубы с формы
  13.         public static ObjectId part_id = ObjectId.Null;    
  14.         [CommandMethod("p_view")]
  15.         public void start10012()
  16.         {
  17.             //обнуляем переменную
  18.             part_id = ObjectId.Null;
  19.             //создаем форму
  20.             get_part get_Part = new get_part();
  21.             get_Part.ShowDialog();
  22.             //если с формы ObjectId не пришло то прекращаем
  23.             if (part_id == ObjectId.Null) return;
  24.             Document aDoc = Application.DocumentManager.MdiActiveDocument;
  25.             Editor ed = aDoc.Editor;
  26.             Database db = aDoc.Database;
  27.            
  28.             using (Transaction tr = db.TransactionManager.StartTransaction())
  29.             {
  30.                 //получаем объект, решил сделать через entyty что бы по отдельности трубы колодцы не обрабатывать
  31.                 using (Entity ent = tr.GetObject(part_id, OpenMode.ForRead, false, true) as Entity)
  32.                 {
  33.                     if (!ent.OwnerId.Equals(db.CurrentSpaceId))
  34.                     {
  35.                         tr.Commit();
  36.                         return;
  37.                     }
  38.  
  39.                     //если есть границы, фиг знает в каких случаях их нет но походу это возможно
  40.                     if (ent.Bounds.HasValue)
  41.                     {                      
  42.                         Extents3d extents = ent.Bounds.Value;
  43.                         //получаем текущий вид
  44.                         using (ViewTableRecord view = ed.GetCurrentView())
  45.                         {
  46.                             // Translate WCS coordinates to DCS
  47.                             // кусок кода из интернета, получает матрицу для перевода координат мировой системы
  48.                             // в систему координат экрана и переводит координаты границ трубы в координаты экрана
  49.                             // как работает хз, разбираться надо
  50.                             Matrix3d matWCS2DCS;                          
  51.                             matWCS2DCS = Matrix3d.PlaneToWorld(view.ViewDirection);                                      
  52.                             matWCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin) * matWCS2DCS;                        
  53.                             matWCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) * matWCS2DCS;                          
  54.                             matWCS2DCS = matWCS2DCS.Inverse();
  55.                             extents.TransformBy(matWCS2DCS);
  56.                             //устанавливаем центральную точку на центр объекта и габариты экрана на габариты объекта
  57.                             view.CenterPoint = new Point2d((extents.MinPoint.X + extents.MaxPoint.X)/2, (extents.MinPoint.Y + extents.MaxPoint.Y) / 2);
  58.                             view.Height = extents.MaxPoint.Y - extents.MinPoint.Y;
  59.                             view.Width = extents.MaxPoint.X - extents.MinPoint.X;                            
  60.                             //устанавливаем вид по исправленному
  61.                             ed.SetCurrentView(view);                        
  62.                         }
  63.                     }  
  64.                 }  
  65.                 ed.SetImpliedSelection(new List<ObjectId> { part_id } .ToArray());
  66.                 tr.Commit();
  67.             }
  68.         }
  69.  
  70.     }
  71. }


Код - C# [Выбрать]
  1. ed.SetImpliedSelection(new List<ObjectId> { part_id } .ToArray());
здесь нужно передать массив с ObjectId элементов и они будут выделены, как создать массив элементов со значениями напрямую фиг знает поэтому использую список, вот все по шагам
Код - C# [Выбрать]
  1. List<ObjectId> list = new List<ObjectId>();
  2. list.Add(part_id);
и передаю этот список в виде массива
Код - C# [Выбрать]
  1. ed.SetImpliedSelection(list.ToArray())






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

  • ADN OPEN
  • ***
  • Сообщений: 104
  • Карма: 0
Код - vb.net [Выбрать]
  1.         Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  2.         Dim selectP(0 To grdPipe.RowCount - 1) As ObjectId
  3.         For i = 0 To grdPipe.RowCount - 1
  4.             ' grdPipe.Item(colPIds.Index, i).Value тут я записал все элементы коллекции
  5.             selectP(i) = grdPipe.Item(colPIds.Index, i).Value
  6.         Next
  7.         ed.SetImpliedSelection(selectP)
Всё разобрался, может кому пригодится, просто идея была выбирать элемент без фокусировки внимания, ну и фокусировка тоже нужна. В общем там нужна по любому коллекция, в Вашем случае это был один элемент, в моем случае был только ObjectId, но надо что бы это была коллекция пусть даже с одним элементом.  Теперь сделаю выбор в таблице строк и выделенные строки буду помещать в массив