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

ADN Club => AutoCAD .NET API => Тема начата: vermesser от 14-06-2018, 00:51:32

Название: Переопределение подсветки сегмента полилинии
Отправлено: vermesser от 14-06-2018, 00:51:32
Здравствуйте!

На сайте ADN Open CIS опубликован (http://adn-cis.org/podsvetka-segmenta-polilinii.html) код, демонстрирующий использование subentitypath для подсветки сегмента полилинии.

Возможно ли как-нибудь переопределить эту подсветку? Например, у меня есть необходимость в подсветке сегмента определённым цветом.

Спасибо!
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: Владимир Шу от 14-06-2018, 06:49:41
Я не сосем понял что значит подсветить, но когда мне нужно было, что бы некоторый сегмент выбранной полилинии отличался от остальных (временно), то я просто поверх выбранного элемента, транзитной графикой, рисовал жирную линию нужного цвета...
Получилось просто и надежно.
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: Александр Ривилис от 14-06-2018, 09:28:12
vermesser,
Вопрос не понял. Переформулируй так, чтобы было понятно чего ты добиваешься.
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: vermesser от 14-06-2018, 16:45:30
Вопрос не понял. Переформулируй так, чтобы было понятно чего ты добиваешься.
Извините. В моём плагине у пользователя есть возможность для работы выбрать как полилинию целиком, так и её сегмент.
Для визуализации выбора всей полилинии я использую класс, производный от DrawableOverrule, который позволяет подсвечивать всю полилинию необходимым мне цветом.
Для подсветки мой класс принимает ObjectId полилинии, но к сожалению сегменты полилинии - это такие объекты, которые ObjectId не имеют.
Пока для подсветки сегмента я использую переработанный код с ADN Open CIS:
Код - vb.net [Выбрать]
  1. <Extension()>
  2. Public Sub SegmentHighlight(ByVal pline As Polyline, ByVal segNum As Integer, ByVal highlightAll As Boolean)
  3.   Dim doc As Document = Core.Application.DocumentManager.MdiActiveDocument
  4.   Dim db As Database = doc.Database
  5.   segNum += 1 'Нумерация Subentity начинается с 1?
  6.   pline.Unhighlight()
  7.   Dim ids As ObjectId() = New ObjectId() {pline.ObjectId}
  8.   Dim segId As New SubentityId(SubentityType.Edge, New IntPtr(segNum))
  9.   Dim path As FullSubentityPath = New FullSubentityPath(ids, segId)
  10.   pline.Highlight(path, True)
  11. End Sub
Хотелось бы также иметь возможность использовать подсветку нужным мне цветом.
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: Владимир Шу от 14-06-2018, 16:52:07
Так нужно: youtu.be/B6n-sic02I8?t=31s (http://youtu.be/B6n-sic02I8?t=31s)  (с 31 по 39 секунды)?
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: vermesser от 14-06-2018, 16:52:32
Я не сосем понял что значит подсветить, но когда мне нужно было, что бы некоторый сегмент выбранной полилинии отличался от остальных (временно), то я просто поверх выбранного элемента, транзитной графикой, рисовал жирную линию нужного цвета...
Получилось просто и надежно.
При зуме, или перемещении вида транзитная графика пропадает (ну, разве что кроме Xline).
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: vermesser от 14-06-2018, 16:58:00
Так нужно: youtu.be/B6n-sic02I8?t=31s  (с 31 по 39 секунды)?
Нет. На видео сначала подсвечивается вся полилиния, а потом её сегмент подсвечивается другим цветом.
мне нужно, чтобы сразу подсвечивался только сегмент и подсветка не пропадала как транзитная графика.
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: Александр Ривилис от 14-06-2018, 16:59:39
Для визуализации выбора всей полилинии я использую класс, производный от DrawableOverrule, который позволяет подсвечивать всю полилинию необходимым мне цветом.
Точно также можно использовать этот класс для подсветки цветом одного сегмента, если номер сегмента известен заранее. Т.е. рисуешь через base.WorldDraw саму полилинию, а затем своим цветом только один сегмент.
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: vermesser от 15-06-2018, 02:34:24
Точно также можно использовать этот класс для подсветки цветом одного сегмента, если номер сегмента известен заранее. Т.е. рисуешь через base.WorldDraw саму полилинию, а затем своим цветом только один сегмент.
Спасибо! Всё получилось.
Код - vb.net [Выбрать]
  1. Imports Autodesk.AutoCAD.ApplicationServices
  2. Imports app = Autodesk.AutoCAD.ApplicationServices.Core.Application
  3. Imports Autodesk.AutoCAD.DatabaseServices
  4. Imports Autodesk.AutoCAD.EditorInput
  5. Imports gi = Autodesk.AutoCAD.GraphicsInterface
  6. Imports Autodesk.AutoCAD.Runtime
  7. Imports Autodesk.AutoCAD.Colors
  8. Imports Autodesk.AutoCAD.Geometry
  9.  
  10. Public Class SegmentHighlight
  11.  
  12.     <CommandMethod("HLIGHTPLINESEGMENT")>
  13.     Public Sub HighlightPolylineSegment()
  14.  
  15.         Dim doc As Document = app.DocumentManager.MdiActiveDocument
  16.         Dim db As Database = doc.Database
  17.         Dim ed As Editor = doc.Editor
  18.  
  19.         Dim plineId As ObjectId
  20.         Dim seg As Integer
  21.  
  22.         Using docLock As DocumentLock = doc.LockDocument
  23.  
  24.             Dim hl As New Highlighting
  25.  
  26.             Do
  27.  
  28.                 Dim plineOpt As New PromptEntityOptions("")
  29.                 With plineOpt
  30.                     .AllowNone = False
  31.                     .AllowObjectOnLockedLayer = True
  32.                     .Message = vbCrLf & "Укажите сегмент полилинии: "
  33.                     .SetRejectMessage(vbCrLf & "Указанный объект недопустим. ")
  34.                     .AddAllowedClass(GetType(Polyline), False)
  35.                 End With
  36.  
  37.                 Dim plineRes As PromptEntityResult
  38.                 plineRes = ed.GetEntity(plineOpt)
  39.  
  40.                 Select Case plineRes.Status
  41.                     Case PromptStatus.OK
  42.                         plineId = plineRes.ObjectId
  43.                         Using tr As Transaction = db.TransactionManager.StartTransaction
  44.                             Dim pline As Polyline = DirectCast(plineRes.ObjectId.GetObject(OpenMode.ForRead), Polyline)
  45.                             Dim pickPt As Point3d = pline.GetClosestPointTo(plineRes.PickedPoint, True)
  46.                             Dim param As Double = pline.GetParameterAtPoint(pickPt)
  47.                             seg = Math.Truncate(param)
  48.                             tr.Commit()
  49.                         End Using
  50.                         If hl.Started Then hl.Stop(True)
  51.                     Case PromptStatus.Cancel
  52.                         ed.WriteMessage(vbCrLf & "Операция прервана пользователем. ")
  53.                         Exit Do
  54.                 End Select
  55.  
  56.                 hl.SetObject(plineId, seg)
  57.                 hl.Start(True)
  58.  
  59.             Loop
  60.  
  61.             hl.Stop(True)
  62.  
  63.         End Using
  64.  
  65.     End Sub
  66.  
  67.     Public Class Highlighting : Inherits gi.DrawableOverrule
  68.  
  69.         Private _hColor As New EntityColor(255, 204, 51)
  70.         Private _originalOverruling As Boolean = False
  71.         Private _plineId As ObjectId = ObjectId.Null
  72.         Private _started As Boolean
  73.         Private _segNum = -1
  74.  
  75.         Public ReadOnly Property Started As Boolean
  76.             Get
  77.                 Return _started
  78.             End Get
  79.         End Property
  80.  
  81.         Public Sub New()
  82.             MyBase.New
  83.         End Sub
  84.  
  85.         Public Sub SetObject(plineId As ObjectId, segNum As Integer)
  86.             If _started Then Throw New Exception("Выполняется подсветка. Нельзя добавить объект.")
  87.             _plineId = plineId
  88.             _segNum = segNum
  89.         End Sub
  90.  
  91.         Public Sub Start(regen As Boolean)
  92.             If _plineId = ObjectId.Null Then Throw New Exception("Отсутствует объект для подсветки.")
  93.             _originalOverruling = Overruling
  94.             AddOverrule(GetClass(GetType(Polyline)), Me, True)
  95.             Overruling = True
  96.             _started = True
  97.             If regen Then
  98.                 app.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbCrLf)
  99.                 app.DocumentManager.MdiActiveDocument.Editor.Regen()
  100.             End If
  101.         End Sub
  102.  
  103.         Public Sub [Stop](regen As Boolean)
  104.             RemoveOverrule(GetClass(GetType(Polyline)), Me)
  105.             Overruling = _originalOverruling
  106.             _plineId = ObjectId.Null
  107.             _segNum = -1
  108.             _started = False
  109.             If regen Then
  110.                 app.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbCrLf)
  111.                 app.DocumentManager.MdiActiveDocument.Editor.Regen()
  112.             End If
  113.         End Sub
  114.  
  115.         Public Overrides Function WorldDraw(drawable As gi.Drawable, wd As gi.WorldDraw) As Boolean
  116.             If Not _plineId = ObjectId.Null Then
  117.                 Dim ent As Entity = TryCast(drawable, Entity)
  118.                 If Not ent Is Nothing Then
  119.                     If _plineId = ent.ObjectId Then
  120.                         Dim pline As Polyline = DirectCast(ent, Polyline)
  121.                         MyBase.WorldDraw(drawable, wd)
  122.                         wd.SubEntityTraits.TrueColor = _hColor
  123.                         wd.Geometry.Polyline(pline, _segNum, 1)
  124.                         Return True
  125.                     End If
  126.                 End If
  127.             End If
  128.             Return MyBase.WorldDraw(drawable, wd)
  129.         End Function
  130.  
  131.     End Class
  132.  
  133. End Class
Название: Re: Переопределение подсветки сегмента полилинии
Отправлено: vermesser от 17-06-2018, 21:34:12
Off-Topic: показать
Кстати, обнаружил, что с помощью класса, производного от DrawableOverrule можно дополнять Arc до Circle во время подсветки. Мне как раз это тоже было необходимо.
(https://media.giphy.com/media/8wdyjwlVQufQw3s1DL/giphy.gif)