Как получить имя сети для трубы или колодца через COM?

Автор Тема: Как получить имя сети для трубы или колодца через COM?  (Прочитано 2289 раз)

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

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

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2444
  • Карма: 689
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Здравствуйте!
То ли действительно есть такой недочёт в Civil 3D COM API, то ли я куда-то не туда смотрю... Но мне не удалось найти никакого относительно простого способа узнать имя сети, к которой принадлежит труба или колодец на чертеже. В .NET вообще нет с этим проблем, есть специальное свойство: http://docs.autodesk.com/CIV3D/2019/ENU/API_Reference_Guide/html/755b6e1e-e16a-ac8f-6086-f1db4a32bc74.htm. А вот в COM - ничего! Ни ссылку на сеть не получить, ни имя её, ни каких-то ещё данных, по которым её можно быстро вычислить... Единственный способ, которым мне удалось получить имя сети - это перебор всех сетей чертежа и перебор объектов этих сетей, пока не найдётся элемент с именем, которое соответствует элементу, для которого ищется сеть (lisp для Civil 3d 2020):
Код - Auto/Visual Lisp [Выбрать]
  1. (defun c:GetPartNetName (/              part      isPipe    partName  pipeApp
  2.                       pipeDoc   nets      i         j         net
  3.                       parts     curPartName         netName
  4.                      )
  5.  
  6.   (setq
  7.     part     (vlax-ename->vla-object (car (entsel)))
  8.     isPipe   (= (vla-get-ObjectName part) "AeccDbPipe")
  9.     partName (vla-get-Name part)
  10.   )
  11.  
  12.   (setq pipeApp (vlax-get-or-create-object
  13.                   "AeccXUiPipe.AeccPipeApplication.13.2"
  14.                 )
  15.   )
  16.   (setq pipeDoc (vlax-get-property pipeApp 'ActiveDocument))
  17.   (setq nets (vlax-get-property pipeDoc 'PipeNetworks))
  18.   (setq i (vla-get-Count nets))
  19.   (while (and (> i 0) (not netName))
  20.     (setq
  21.       i   (- i 1)
  22.       net (vla-item nets i)
  23.     )
  24.  
  25.     (setq
  26.       parts (if isPipe
  27.               (vlax-get-property net 'Pipes)
  28.               (vlax-get-property net 'Structures)
  29.             )
  30.     )
  31.  
  32.     (setq j (vla-get-count parts))
  33.     (while (and (> j 0) (not netName))
  34.       (setq j (- j 1)
  35.             curPartName
  36.              (vla-get-Name (vla-item parts j))
  37.       )
  38.       (if (= curPartName partName)
  39.         (setq netName (vla-get-Name net))
  40.       )
  41.     )
  42.   )
  43.  
  44.   (alert netName)
  45.  
  46.   (princ)
  47. )
Может быть, я что-то упускаю?
Пример дампа для трубы:
; IAeccPipe: Интерфейс "Труба"
; Значения свойств:
;   Alignment = nil
;   Application (RO) = #<VLA-OBJECT IAeccApplication 00000276ae9237f0>
;   ClosestPointTo (RO) = ...Индексированное содержимое не выводится...
;   Connectors (RO) = #<VLA-OBJECT IAeccConnectors 00000276ae924480>
;   Description = "300 ПЭ КОРСИС ID SN8"
;   DisplayName (RO) = "Труба-(283)"
;   Document (RO) = #<VLA-OBJECT IAeccDocument 00000276ae9240c0>
;   EGLDown = 0.0
;   EGLUp = 0.0
;   EndPoint (RO) = #<VLA-OBJECT 00000276ae9251d0>
;   EndStructure (RO) = #<VLA-OBJECT IAeccStructure 00000276a46e6870>
;   EntityTransparency = "ПоСлою"
;   FlowDirection (RO) = 1
;   FlowDirectionMethod = 1
;   Handle (RO) = "20555"
;   HasExtensionDictionary (RO) = 0
;   HGLDown = 0.0
;   HGLUp = 0.0
;   HoldOnResize = 0
;   Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 00000276aea11478>
;   InnerDiameterOrWidth (RO) = 0.3
;   InnerHeight (RO) = 0.3
;   IsMaxCoverViolated (RO) = ...Индексированное содержимое не выводится...
;   IsMinCoverViolated (RO) = ...Индексированное содержимое не выводится...
;   Labels (RO) = #<VLA-OBJECT IAeccPipeLabels 00000276ae9d49d0>
;   Layer = "К2П_План"
;   Length2D (RO) = 39.7856
;   Length3D (RO) = 39.7856
;   Linetype = "ByLayer"
;   LinetypeScale = 1.0
;   Lineweight = -1
;   Material = "Global"
;   MaximumCover (RO) = 0.0
;   MinimumCover (RO) = 0.0
;   Name = "Труба-(283)"
;   ObjectID (RO) = 42
;   ObjectName (RO) = "AeccDbPipe"
;   OuterDiameterOrWidth (RO) = 0.364
;   OuterHeight (RO) = 0.364
;   OwnerID (RO) = 43
;   ParamsBool (RO) = #<VLA-OBJECT 00000276ae926970>
;   ParamsDouble (RO) = #<VLA-OBJECT 00000276ae926610>
;   ParamsLong (RO) = #<VLA-OBJECT 00000276ae926340>
;   ParamsString (RO) = #<VLA-OBJECT 00000276ae9262e0>
;   PartDataRecord = #<VLA-OBJECT IAeccPartDataRecord 00000276ae926370>
;   PartFamily (RO) = #<VLA-OBJECT IAeccPartFamily 0000027695e4e750>
;   PartSizeName (RO) = "300 ПЭ КОРСИС ID SN8"
;   PartType (RO) = 10
;   PlotStyleName = "ByLayer"
;   PointAtParam (RO) = ...Индексированное содержимое не выводится...
;   Position (RO) = #<VLA-OBJECT IAeccPoint3d 00000276ae926a00>
;   ProfileNetworkParts (RO) = #<VLA-OBJECT IAeccGraphProfileNetworkParts 00000276ae9d4fc0>
;   Radius (RO) = 0.0
;   ShowToolTip = -1
;   Slope (RO) = 0.0
;   StartPoint (RO) = #<VLA-OBJECT 00000276ae927210>
;   StartStructure (RO) = #<VLA-OBJECT IAeccStructure 00000276a46e4470>
;   STMPipeMetadata = неподдерживаемый тип результата: 65
;   Style = #<VLA-OBJECT IAeccPipeStyle 0000027695e4d310>
;   SubEntityType (RO) = 0
;   Surface = nil
;   SweptShape (RO) = 2
;   TrueColor = #<VLA-OBJECT IAcadAcCmColor 00000276aea11890>
;   Visible = -1
;   WallThickness (RO) = 0.032
; Поддерживаемые методы:
;   ArrayPolar (3)
;   ArrayRectangular (6)
;   ConnectToPipe (3)
;   ConnectToStructure (2)
;   Copy ()
;   Delete ()
;   Disconnect (1)
;   GetBoundingBox (2)
;   GetExtensionDictionary ()
;   GetXData (3)
;   Highlight (1)
;   IntersectWith (2)
;   IsReferenceObject ()
;   IsReferenceStale ()
;   IsReferenceSubObject ()
;   IsReferenceValid ()
;   Mirror (2)
;   Mirror3D (3)
;   Move (2)
;   Project2dPointVertically (1)
;   ResizeByInnerDiaOrWidth (3)
;   Rotate (2)
;   Rotate3D (3)
;   ScaleEntity (2)
;   SetStartAndEndPoints (2)
;   SetXData (2)
;   SwapPartFamilyAndSize (2)
;   TransformBy (1)
;   Update ()
Пример дампа для колодца:
; IAeccStructure: Интерфейс "Колодец"
; Значения свойств:
;   Alignment = nil
;   Application (RO) = #<VLA-OBJECT IAeccApplication 00000276af19a680>
;   AutomaticRimSurfaceAdjustment = 1
;   BoundingShape (RO) = 1
;   ConnectedPipe (RO) = ...Индексированное содержимое не выводится...
;   ConnectedPipeNames (RO) = "Труба-(295)"
;   ConnectedPipesCount (RO) = 1
;   Connectors (RO) = #<VLA-OBJECT IAeccConnectors 00000276af19a740>
;   ControlSumpBy = 0
;   Description = "Колодец 1 000 мм"
;   DisplayName (RO) = "Л-(132)"
;   Document (RO) = #<VLA-OBJECT IAeccDocument 00000276af19a920>
;   EntityTransparency = "ПоСлою"
;   Handle (RO) = "205E1"
;   HasExtensionDictionary (RO) = 0
;   Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 00000276af0a2db8>
;   InnerDiameter (RO) = ...Индексированное содержимое не выводится...
;   InnerLength (RO) = ...Индексированное содержимое не выводится...
;   InnerWidth (RO) = ...Индексированное содержимое не выводится...
;   Labels (RO) = #<VLA-OBJECT IAeccStructureLabels 00000276af27c880>
;   Layer = "К2П_План"
;   Linetype = "ByLayer"
;   LinetypeScale = 1.0
;   Lineweight = -1
;   Material = "ByLayer"
;   Name = "Л-(132)"
;   ObjectID (RO) = 44
;   ObjectName (RO) = "AeccDbStructure"
;   OwnerID (RO) = 43
;   ParamsBool (RO) = #<VLA-OBJECT 00000276af19a290>
;   ParamsDouble (RO) = #<VLA-OBJECT 00000276af19a650>
;   ParamsLong (RO) = #<VLA-OBJECT 00000276af199db0>
;   ParamsString (RO) = #<VLA-OBJECT 00000276af19a5c0>
;   PartDataRecord = #<VLA-OBJECT IAeccPartDataRecord 00000276af19a950>
;   PartFamily (RO) = #<VLA-OBJECT IAeccPartFamily 00000276af22dd60>
;   PartSizeName (RO) = "Колодец 1 000 мм"
;   PartType (RO) = 102
;   PipeCenterDepth (RO) = ...Индексированное содержимое не выводится...
;   PipeInnerDiaOrWidth (RO) = ...Индексированное содержимое не выводится...
;   PipeInvertDepth (RO) = ...Индексированное содержимое не выводится...
;   PipeLowestBottomDepth (RO) = 0.425
;   PipeOuterBottomDepth (RO) = ...Индексированное содержимое не выводится...
;   PipeOuterTopDepth (RO) = ...Индексированное содержимое не выводится...
;   PipeUpperTopDepth (RO) = 0.2
;   PipeWallThickness (RO) = ...Индексированное содержимое не выводится...
;   PlotStyleName = "ByLayer"
;   Position (RO) = #<VLA-OBJECT IAeccPoint3d 00000276af19a860>
;   ProfileNetworkParts (RO) = #<VLA-OBJECT IAeccGraphProfileNetworkParts 00000276af27c6a0>
;   RimElevation = 0.3125
;   Rotation = 5.84866
;   ShowToolTip = -1
;   StructureDiameterOrWidth (RO) = 1.004
;   StructureHeight (RO) = 0.4375
;   StructureInnerDiameterOrWidth (RO) = 1.0
;   StructureInnerLength (RO) = 0.0
;   StructureLength (RO) = 0.0
;   Style = #<VLA-OBJECT IAeccStructureStyle 00000276af22e6f0>
;   SumpDepth = 0.0
;   SumpElevation = -0.1
;   Surface = nil
;   SurfaceAdjustmentValue = 0.0
;   TrueColor = #<VLA-OBJECT IAcadAcCmColor 00000276af0a32f0>
;   Visible = -1
; Поддерживаемые методы:
;   ArrayPolar (3)
;   ArrayRectangular (6)
;   ConnectToPipe (2)
;   Copy ()
;   Delete ()
;   Disconnect (1)
;   GetBoundingBox (2)
;   GetExtensionDictionary ()
;   GetNextPipeElevation ()
;   GetXData (3)
;   Highlight (1)
;   IntersectWith (2)
;   IsConnectedPipeFlowingIn (1)
;   IsConnectedPipeFlowingOut (1)
;   IsPointInsideStructureRegion (1)
;   IsReferenceObject ()
;   IsReferenceStale ()
;   IsReferenceSubObject ()
;   IsReferenceValid ()
;   Mirror (2)
;   Mirror3D (3)
;   Move (2)
;   ResizeByPipeDepths ()
;   ResizeJunctionStructureByRimAndSumpElevations (3)
;   Rotate (2)
;   Rotate3D (3)
;   ScaleEntity (2)
;   SetLocation (1)
;   SetXData (2)
;   SwapPartFamilyAndSize (2)
;   TransformBy (1)
;   Update ()
В Object Browser та же картина (ниже - скрины имён свойств для труб)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 944
  • Карма: 154
Тебе именно лисп нужен??
Я когда игрался с объектами ADT (ныне AA), приходилось считывать словарные записи - и с документа, и с объектов. Может, так сработает?
P.S. Civil'a нет, работать в нем не умею, и вообще компьютеров боюсь ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • Administrator
  • *****
  • Сообщений: 12750
  • Карма: 1647
  • Рыцарь ObjectARX
  • Skype: rivilis
Дмитрий Загорулькин,
OwnerID ссылается на ModelSpace?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2444
  • Карма: 689
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Тебе именно лисп нужен??
Нет, нужен VBA для создания дополнительных свойств. Продолжение этой темы, по сути: https://adn-cis.org/forum/index.php?topic=8952.0
Но т.к. LISP и VBA используют COM практически одинаково, то не особо принципиально на чём тестировать. А на LISP мне удобнее :)
Я когда игрался с объектами ADT (ныне AA), приходилось считывать словарные записи - и с документа, и с объектов. Может, так сработает?
А у них нет словарей, и XData пустая :(
OwnerID ссылается на ModelSpace?
Да :(

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

  • Administrator
  • *****
  • Сообщений: 12750
  • Карма: 1647
  • Рыцарь ObjectARX
  • Skype: rivilis
Дмитрий Загорулькин,
Похоже связь в COM односторонняя. Т.е. из Pipe получить Network напрямую нельзя. Интересно, а в .NET Pipe хранит ObjectId Network? Ты это можешь проверить сделав DxfOut в ReferenceFiler. Если там не окажется ObjectId Network, то это будет значить, что и в .NET свойство NetworkName работает аналогично тому, как ты это сделал на lisp'е.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2444
  • Карма: 689
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Я так понимаю, что это подтверждает наличие сети в HardReferences в ARXDBG и MGDDBG? Сеть там есть у трубы и у колодца.

Отмечено как Решение Дмитрий Загорулькин 25-12-2019, 14:47:34

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

  • Administrator
  • *****
  • Сообщений: 12750
  • Карма: 1647
  • Рыцарь ObjectARX
  • Skype: rivilis
Я так понимаю, что это подтверждает наличие сети в HardReferences в ARXDBG и MGDDBG?
Да.
Сеть там есть у трубы и у колодца.
Значит действительно ограничение в COM-модели.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение


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

  • Administrator
  • *****
  • Сообщений: 12750
  • Карма: 1647
  • Рыцарь ObjectARX
  • Skype: rivilis
Интересно, а в COM нет какого-то способа получить объекты из HardReferences?
100% нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Nutson

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
У себя решал проблему аналогично, перебором всех элементов.
Позже додумался что из коллекции Network.Pipes / Network.Structures можно получать элемент по имени.
Таким образом получается нужно обойти только все трубопроводные сети, а их количество гораздо меньше чем элементов в каждой из них.

Код - Visual Basic [Выбрать]
  1. Public Function network_from_select_part1(p_doc As AeccPipeDocument, ByRef struct As AeccStructure)
  2.     Dim Network As AeccPipeNetwork
  3.     Dim existStruct As AeccStructure
  4.    
  5.     On Error Resume Next
  6.    
  7.     If p_doc.PipeNetworks.Count > 0 Then
  8.         For Each Network In p_doc.PipeNetworks
  9.             Set existStruct = Network.structures(struct.Name) 'пробую получить элемент по имени из коллекции
  10.            If Err = 0 Then ' если вылетела ошибка, значит элемента нет в коллекции
  11.                If Not existStruct Is Nothing And existStruct.Handle = struct.Handle Then 'если получил элемент то проверяю хендлы, так как у элементов в разных сетях могут быть одинаковые имена
  12.                        Set network_from_select_part = Network
  13.                         Exit Function
  14.                 End If
  15.             End If
  16.             Err.Clear
  17.         Next
  18.     End If
  19. End Function
  20.  
  21.  

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2444
  • Карма: 689
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Таким образом получается нужно обойти только все трубопроводные сети, а их количество гораздо меньше чем элементов в каждой из них.
С точки зрения сокращения количества кода - да, наверное, так меньше получается. Но вот насчёт того, будет ли это быстрее работать - есть сомнения.
Во-первых, возможно, что получение элемента коллекции по имени внутри работает по такому же принципу перебора.
Во-вторых, обработка ошибок - затратная по ресурсам операция.