Boa noite pessoal!!!
Hoje vou fazer um tutorialzinho maroto, daqueles da época do Blog do Neyton!!
Pra ficar legal, vamos fazer um bem difícil: Colocar o valor do degrau em um PiorNetwork
Pra começar, desenha aí uma rede usando o Pipenetowork e coloca também um profileview, mostrando a rede:
Observe que adicionei uma label simples de perfil para mostrar o degrau. O objetivo é criar uma label que contem a informação do Degrau.
O degrau é dado por:
Degrau = [ Cota da geratriz interna Inferior do tubo ] – [ Cota de fundo do PV de jusante ]
No estilo de label de tubo, não temos a propriedade “Degrau”. Mas por alguma razão, temos acesso ao PropertySet. E aí é que está a mágica toda!!! Veja só:
Até aí acredito que você já tenha visto. Mas… e como calcula o property set?
Primeiro, chame o comando PROPERTYDATA e escolhe a opção “Sets” no menu. Eu criei 2 Property Sets:
- TuboPlanta – para poder adicionar a label no estilo de label em planta e filtre para Pipe
- ProjecaoTubo – para poder adicionar a label no estilo de label em perfil
Note que é necessário separar os estilos (Até dá pra fazer num só, mas ia complicar o script que veremos abaixo)
No property set, crie uma Propriedade Automática para obter o ObjectID do item a ser processado:
Agora, crie uma propriedade do tipo fórmula:
Vamos inserir o seguinte código VBScript (Chupa essa manga C#):
RESULT=0
Set oApp = GetObject(, "AutoCAD.Application")
Set oCivilApp = oApp.GetInterfaceObject("AeccXUiLand.AeccApplication.13.2")
Set aecApp = oApp.GetInterfaceObject("AecX.AecBaseApplication.8.2")
aecApp.Init (oApp)
Set tubo = oCivilApp.ActiveDocument.ObjectIDToObject([ObjectID])
zFinal = aecApp.ActiveDocument.Utility.ConvertToVariantArray(tubo.PointAtParam(1))(2)
diametro = tubo.InnerDiameterOrWidth
SumpElevation = tubo.EndStructure.SumpElevation
RESULT = zFinal - diametro/2 - SumpElevation
Agora, as considerações:
- RESULT – é a variável que recebe o valor calculado pelo script e será preenchido no propertyset.
- Set oApp = GetObject(, “AutoCAD.Application”) – obtemos acesso ao AutoCAD em si
- Set oCivilApp = oApp.GetInterfaceObject(“AeccXUiLand.AeccApplication.13.2”) – obtemos acesso ao Civil 3D 2020
- Set aecApp = oApp.GetInterfaceObject(“AecX.AecBaseApplication.8.2”) – obtemos acesso à aplicação AecBase, para usar certas funções
- aecApp.Init (oApp) – é necessário inicializar a aplicação, com o AutoCAD
- Set tubo = oCivilApp.ActiveDocument.ObjectIDToObject([ObjectID]) – Obtemos a instância do tubo em si, através do seu ObjectID. Note que aqui, você deve adicionar o [ObjectID] dentro do parênteses, fazendo duplo clique no “ObjectID” que aparece na caixa inferior esquerda, a “Insert Property Definitions” e ele ficará sombreado no código:
- zFinal = aecApp.ActiveDocument.Utility.ConvertToVariantArray(tubo.PointAtParam(1))(2) – o Valor de Z do EndPoint do tubo
- tubo.PointAtParam(1) – devolve o EndPoint como um Variant Value
- aecApp.ActiveDocument.Utility.ConvertToVariantArray – converte um valor do tipo Variant Value em uma Safe Array. Desse array, obtemos o valor no índice 2, como sendo Z. Note que isso é no centro da seção do tubo
- diametro = tubo.InnerDiameterOrWidth – obtemos o diâmetro/altura interna do tubo
- SumpElevation = tubo.EndStructure.SumpElevation – obtemos a cota de fundo do PV de jusante
- RESULT = zFinal – diametro/2 – SumpElevation – Finalmente calculamos o valor do degrau
Observe que obter a coordenada do EndPoint do tubo, não é tão simples.
Aqui, um parênteses: a API ACTIVEX do tubo (IaeccPipe) fornece a propriedade EndPoint, mas ela simplesmente NÃO FUNCIONA!!!
Um comentário, como saber a versão correta a colocar no AeccXUiLand.AeccApplication.13.2? Vá até a pasta C:\Program Files\Common Files\Autodesk Shared. Lá Localize a pasta Civil Engineering XXX. Esse XXX indica a versão, no meu caso, o Civil 3D 2020 é o 13.2 (XX.X, percebe?). Se tiver mais versões desta pasta, são as versões do CIvil 3D que você tem instalado na sua máquina. Já para AecX.AecBaseApplication.8.2, nesta pasta procure por AecXBaseYY.tlb. O YY indica a versão que você deve colocar: Y.Y
Para saber esse “EndStructure”, copie e cole na linha de comando:
(vlax-dump-object (vlax-ename->vla-object (car(entsel “Selecione o tubo”))) t)
Vai aparecer algo assim:
Command: (vlax-dump-object (vlax-ename->vla-object (car(entsel "Selecione o tubo"))) t) Selecione o tubo; IAeccPipe: Pipe interface
; Property values:
; Alignment = nil
; Application (RO) = #<VLA-OBJECT IAeccApplication 000001a40bed51a0>
; ClosestPointTo (RO) = ...Indexed contents not shown...
; Connectors (RO) = #<VLA-OBJECT IAeccConnectors 000001a40bed4f60>
; Description = "BSTC"
; DisplayName (RO) = "Pipe - (1)"
; Document (RO) = #<VLA-OBJECT IAeccDocument 000001a40bed5110>
; EGLDown = 0.0
; EGLUp = 0.0
; EndPoint (RO) = #<VLA-OBJECT 000001a40bed5230>
; EndStructure (RO) = #<VLA-OBJECT IAeccStructure 000001a417164410>
; EntityTransparency = "ByLayer"
; FlowDirection (RO) = 1
; FlowDirectionMethod = 1
; Handle (RO) = "F90"
; HasExtensionDictionary (RO) = -1
; HGLDown = 0.0
; HGLUp = 0.0
; HoldOnResize = 0
; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 000001a417266e28>
; InnerDiameterOrWidth (RO) = 0.5
; InnerHeight (RO) = 0.5
; IsMaxCoverViolated (RO) = ...Indexed contents not shown...
; IsMinCoverViolated (RO) = ...Indexed contents not shown...
; Labels (RO) = #<VLA-OBJECT IAeccPipeLabels 000001a486a0d760>
; Layer = "0"
; Length2D (RO) = 11.5374
; Length3D (RO) = 11.5585
; Linetype = "ByLayer"
; LinetypeScale = 1.0
; Lineweight = -1
; Material = "ByLayer"
; MaximumCover (RO) = 0.0
; MinimumCover (RO) = 0.0
; Name = "Pipe - (1)"
; ObjectID (RO) = 42
; ObjectName (RO) = "AeccDbPipe"
; OuterDiameterOrWidth (RO) = 0.61
; OuterHeight (RO) = 0.61
; OwnerID (RO) = 43
; ParamsBool (RO) = #<VLA-OBJECT 000001a40bed4db0>
; ParamsDouble (RO) = #<VLA-OBJECT 000001a40bed4cf0>
; ParamsLong (RO) = #<VLA-OBJECT 000001a40bed5440>
; ParamsString (RO) = #<VLA-OBJECT 000001a40bed4c60>
; PartDataRecord = #<VLA-OBJECT IAeccPartDataRecord 000001a40bed5410>
; PartFamily (RO) = #<VLA-OBJECT IAeccPartFamily 000001a40bbc8b10>
; PartSizeName (RO) = "BSTC 500 x 55 mm"
; PartType (RO) = 10
; PlotStyleName = "ByLayer"
; PointAtParam (RO) = ...Indexed contents not shown...
; Position (RO) = #<VLA-OBJECT IAeccPoint3d 000001a40bed4e70>
; ProfileNetworkParts (RO) = #<VLA-OBJECT IAeccGraphProfileNetworkParts 000001a486a0ca90>
; Radius (RO) = 0.0
; ShowToolTip = -1
; Slope (RO) = 0.0605369
; StartPoint (RO) = #<VLA-OBJECT 000001a40bed5020>
; StartStructure (RO) = #<VLA-OBJECT IAeccStructure 000001a417164610>
; STMPipeMetadata = unsupported result type: 65
; Style = #<VLA-OBJECT IAeccPipeStyle 000001a40bbc8a80>
; SubEntityType (RO) = 0
; Surface = nil
; SweptShape (RO) = 2
; TrueColor = #<VLA-OBJECT IAcadAcCmColor 000001a417265a40>
; Visible = -1
; WallThickness (RO) = 0.055
; Methods supported:
; 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 ()
Viu na lista o EndStructure? O mesmo Vale para InnerDiameterOrWidth e SumpElevation no caso das estruturas.
O que realmente deu trabalho, foi achar esse aecApp.ActiveDocument.Utility.ConvertToVariantArray, achei aqui
Daí é só associar o PropertySet ao tubo:
Muito bem, agora tu vai entender porque precisei 2 propertysets, um pro tubo e outro para sua projeção em perfil:
O tubo, tem um ObjectID. A projeção no perfil também tem e não tem nada a ver com o tubo, por isso, é necessário obter o tubo a partir do ObjectID da projeção:
RESULT = -1
On Error Resume Next
Set oApp = GetObject(, "AutoCAD.Application")
Set oCivilApp=oApp.GetInterfaceObject("AeccXUiLand.AeccApplication.13.2")
Set aecApp = oApp.GetInterfaceObject("AecX.AecBaseApplication.8.2")
aecApp.Init (oApp)
Set projecao = oCivilApp.ActiveDocument.ObjectIDToObject( [ObjectID])
Set tubo = projecao.GetModelNetworkPart
zFinal = aecApp.ActiveDocument.Utility.ConvertToVariantArray(tubo.PointAtParam(1))(2)
diametro = tubo.InnerDiameterOrWidth
SumpElevation = tubo.EndStructure.SumpElevation
RESULT = zFinal - diametro/2 - SumpElevation
Observe o código. Após obter a instância da projeção, chamei o método GetModelNetworkPart para obter a instância do tubo. O resto é idêntico. A mesma observação quanto a preencher o [ObjectID] de forma que ele fique sombreado se aplica. Descobri tentando!!!
Associe o PropertySet à projeção em perfil e você terá o mesmo valor do degrau:
Por fim, adicione label ao tubo e sua projeção:
Notou que não usei nenhum plugin, apenas funções NATIVAS do Civil 3D? Sim, ainda me cheira a gambiarra, mas funciona!!
E no SOLIDOS? Como faríamos? Ah bem… Isso é pra outro tutorial…
Outra fonte legal:
https://www.symetri.co.uk/insights/blog/civil-3d-property-set-secrets/