Import type library

Bom, faz tempo que não posto nada, então vou postar um código que stou achando bastante útil:

;importa as funções do civil 3d para o visual lisp
(vlax-import-type-library
 :tlb-filename
 "C:\\Program Files\\AutoCAD Civil 3D 2008\\Civil\\AeccXLand.tlb"
 :methods-prefix "cvlm-"
 :properties-prefix "cvlp-"
 :constants-prefix "cvlc-")


Veja, ele importa os métodos, propriedades e constantes do Civil 3d para o visual lisp

Qual a utilidade disso? bem... você sabe programar em vba? não? sabe em visual lisp?
então.... com isso você pode manipular entidades do civil 3d via lisp!!
um exemplo:
digamos que queiramos obter uma polilinha que passe pelos pontos de um alinhamento... sei lá pra que, mas precisamos fazer isso...
o civil 3d tem um comando que faz o inverso, pega uma polilinha e cria o alinhamento, mas não tem um comando que cria uma polilinha a partir de um alinhamento!! como fazer?
Command: pline ....

bom, veja:

(defun c:alin2pline (/ ss ent)
  (
tbn:error-init nil)
  (
if (setq ss (ssget '((0 . "AECC_ALIGNMENT"))))
    (
repeat (sslength ss)
      (
setq ent (ssname ss 0))
      (
cvlm-GetLWPolyline (vlax-ename->vla-object ent))
      (
ssdel ent ss)))
  (
tbn:error-restore ))


a palavra cvlm-GetLWPolyline so existe APÓS você importar a "type library" do civil 3d que contem o método GetLWPolyline, saca?

essas "type library" estão em "C:\Program Files\AutoCAD Civil 3D 2008\Civil\", no caso do c3d2k8...
agora me pergunte COMO saber que novos métodos você dispõe??

experimente isto:

(setq tmp (atoms-family 1) file (open "d:/cvl.txt" "w"))
(
foreach x tmp
  (if (= "CVL" (strcase (substr x 1 3))) (write-line x file)))
(
close file)
(
startapp "notepad.exe" "d:/cvl.txt")



isto irá criar um arquivo de texto no drive D:\ com todos os métodos, propriedades e constantes importados...

tá, e o help de cada uma delas????????
ache este arquivo:
"C:\Program Files\AutoCAD Civil 3D 2008\Help\civilauto-reference.chm"

abra este tópico:
"AeccXLandLib Library", nele ache "IAeccAlignment Interface"
nele você acha o método que usei no exemplo (GetLWPolyline)
como usar o help?
o help deste método, é algo assim:

Gets the lightweight polyline from alignment geometry.

HRESULT GetLWPolyline(
[out, retval] IAcadLWPolyline ** ppLWPolyline
);


isto é em C, mas é fácil entender...
é quase como os métodos activex ( as famosas VL* ) do cad
ficaria em visual lisp:
(cvlm-GetLWPolyline vlaobj)
onde vlaobj é o vla-object name do alinhamento ( veja o exemplo acima!! )

outro exemplo:
(setq vla     (vlax-ename->vla-object (car (entsel "\nSelecione um alinhamento")))
      station (cvlp-get-startingstation vla)
      offset  0)
(
cvlm-PointLocation vla station offset  'x 'y)
(
prompt (strcat "o ponto inicial é " (rtos x) ", " (rtos y)))


simples né?
o método pointlocation, no help é assim:
HRESULT PointLocation(
[in] double Station,
[in] double Offset,
[out] double* Easting,
[out] double* Northing
);


em lisp, o método PointLocation ficaria:
(cvlm-PointLocation vla station offset 'x 'y)
onde:
"cvlm-" é o prefixo que eu escolho para indicar os métodos
vla é o vla-object do alignment
station é a estaca
offset é a distancia perpendicular ao alinhamento na estaca escolhida

SlideViewer

Não é bem a área, mas é relacionado... vou postar o link de um programinha q fiz para visualizar slides:

download

funciona tanto com slide como biblioteca de slides, e nestas ainda é possivel extrair os slides da mesma
digamos que foi bem interessante programar em vb.net, hehehe
pro primeiro programinha até que tá legal!!

Multiplos ProfileViews


Uma rotina para o civil 3d!!
Então, no civil 3d 2008 tem esta funcionalidade (ver imagem), mas no 2007 não tem... e muitas vezes o profileview fica enorme e é necessário subdividir ele para caber na prancha... como eu disse no 2008 tem isso é bem legal, mas no 2007... em fim, bolei um esquema parecido com o 2008, mas prerferi deixar a cargo do usuário definir os limites de cada profileview. Funciona assim: você cria uma View do alinhamento inteiro (fica enorme eu sei), configura nele tudo o que você quer que apareça, tal como as bandset, perfis que deverão aparecer etc... aí cria retângulos (com o comando rectangle mesmo) em cima que servirão de limitadores para os diversos profileviews que serão criados. Assim, pode-se defini-los com diversos tamanhos inclusive com superposições, de modo a acomodar da melhor forma e de maneira mais rápida que fazer um a um. Em seguida, é rodar a rotina e pronto... dependendo da velocidade da sua máquina pode demorar um pouco... no meu p4 ht de 3.06GB levou 10 minutos para criar 53 profileviews... na mão levei uns 10 para cada um, hehehe, então clica aí pra ver!!
a rotina...
(defun c:createmview (/ view ElevationMin VerticalScale StationStart StationEnd Name
                 minx miny pie psd minxl minyl maxxl maxyl prof ent ss
)

;inicia o controle de erros:
  (tbn:error-init nil)
  
  (
prompt "\Nselecione o profileview modelo")
  (
if (setq view (ssget ":S" '((0 . "AECC_PROFILE_VIEW"))))
    (
if (progn
      (prompt "\nSelecione as polilinhas limitadoras")
      (
setq ss (ssget '((0 . "LWPOLYLINE")))))
    (
progn
;calcula os limites do profileview "pai":
      (setq view          (vlax-ename->vla-object (ssname view 0))
        ElevationMin  (vlax-get-property view "ElevationMin")
        VerticalScale (vlax-get-property view "VerticalScale")
        StationStart  (vlax-get-property view "StationStart")
        StationEnd    (vlax-get-property view "StationEnd"))
      

;calcula a origem do gráfico:
      (vlax-invoke-method view "FindXYAtStationAndElevation" StationStart ElevationMin 'minx 'miny)
      (
setq origin (vlax-3d-point minx miny 0))

;cria os profileview "filhos":
      (repeat (sslength ss)
    (
setq ent    (ssname ss 0)
          prof   (vla-copy view)) ;clona o "pai"
;limites da polilinha:
    (vla-GetBoundingBox (vlax-ename->vla-object ent) 'pie 'psd)
    

;move o clone para o canto inferior esquerdo da polilinha:
    (vla-move prof origin pie)
    

;calcula os limites da polilinha:
    (setq minxl (vlax-safearray-get-element pie 0)
          minyl (vlax-safearray-get-element pie 1)
          maxxl (vlax-safearray-get-element psd 0)
          maxyl (vlax-safearray-get-element psd 1))

;redimensiona o clone ("filho") para os limites da polilinha:
    (mapcar '(lambda (pm pv) (vlax-put-property prof pm pv))
        '("StationLocked"   ;setar em 1 para aceitar os limites abaixo
          "ElevationLocked" ;idem
          "ElevationMin"    ;limites do profileview "filho"
          "ElevationMax"
          "StationStart"
          "StationEnd"
 )
        (
list
          1
          1
          (+ ElevationMin (/ (- minyl miny) VerticalScale))
          (
+ ElevationMin (/ (- maxyl miny) VerticalScale))
          (
+ StationStart (- minxl minx))
          (
+ StationStart (- maxxl minx))))

;libera a memoria ( precisa disso mesmo? )
    (vlax-release-object prof)

;next
    (ssdel ent ss))

;libera a memoria ( precisa disso mesmo? )
      (vlax-release-object view)
      )))


;reestabelece o cntrole de erros do cad:
  (tbn:error-restore)
)


Link(s) da(s) subrotina(s) usada(s):
tbn:error-init, tbn:error-restore