Polylinie mit Objektdaten in 3DPolylinie umwandeln / Lisp
cadoc 14. Mai. 2019, 10:33

Hallo!
Ich habe folgende Aufgabe zu lösen.
Wird derzeit per Hand gemacht, ist aber echt langwierig.

Es gibt Polylinien mit Stützpunkten auf Vermessungspunkten.
Die Stützpunkte haben natürlich nicht die richtige Z-Koordinate.
An den Polylinien hängen noch Objektdaten dran.
Diese müssen durch 3DPolylinien ersetzt und die Objektdaten
mit copy_od übergeben werden.

Ein Lisp wäre natürlich hilfreich aber es zu erstellen zu hoch für mich.

Ein Ansatz wäre womöglich:
Liste von Polylinien
Liste von Objektdaten
Liste von X,Y Koordinaten der Vermessungspunkte
Neue Stützpunkte generieren = bei identen X,Y auf Z des identen Vermessungspunktes hochziehen
3DPolylinien gemäß Polylinen mit neuem Z erstellen
Objektdaten wieder anhängen

Vielleicht hat jemand von euch einen anderen Zugang.
VD & LG

Andreas Kraus 14. Mai. 2019, 11:23

Hallo cadoc,
ich würde ja jetzt sagen "gute Idee ... mach das so" 

Was sind das denn für Daten an der Polylinie ?
Ich tippe mal auf erweiterte Elementdaten ?

Wie sind denn die Daten aufgebaut ?
Was steht denn da drin ?
Vielleicht können die Koordinaten direkt verwendet werden.

mit vla-Add3DPoly lassen sich 3D-Polylinien sehr einfach erzeugen.

cadoc 14. Mai. 2019, 11:47

Als Daten hängen einige (mit adedefdata & adeattechdata erstellte)
Datenfelder dran, sowie topografische Informationen (maptopocreate).

Andreas Kraus 14. Mai. 2019, 16:36

Ich hab nur Autocad.
adedefdata & adeattechdata kenn ich nicht.
Civil 3D ?

cadoc 14. Mai. 2019, 16:46

Hätte ich erwähnen sollen, hab AutoCAD Map 3D.
Die dem Objekt angehängten Datenfelder sind Inhalte
der späteren shp-Files.

Andreas Kraus 14. Mai. 2019, 17:07

Da weiß ich nicht ob ich helfen kann aber wenn die Daten mal da sind kann ich vielleicht beim Polylinien-erstellen wieder einsteigen.

Oder du hängst hier mal ne Beispieldatei mit Daten an und ich schau mal ob ich was lesen kann.

cadoc 14. Mai. 2019, 17:24


Info.dwg

 
Hab mal was hochgeladen.

Andreas Kraus 15. Mai. 2019, 08:31

Da hängen zwar EEDs dran aber so auf den ersten Blick kann ich da nix mit anfangen.
Sehen so aus:
("IRD"
      (1002 . "{")
      (1000 . "TPMLINK_M1-_-ade")
      (1070 . 515)
      (1071 . 1)
      (1004
.
"0100050000000400000002000000000000004C671CBF4F9328404C671CBF4F932840"
      )
      (1002 . "}")
    )

Unter 1004 steht zwar etwas dass nach "Daten" aussieht aber auch eine Umwandlung in Dezimal oder Binär bringt mich nicht wirklich weiter.
Auch in den Dictionaries hab ich erst mal nichts für mich brauchbares gefunden.
Wenn das jemand blickt ... bitte melden.

cadoc 15. Mai. 2019, 08:37


Info.JPG

 
Im Eigenschaftsfenster sieht das so aus.

Andreas Kraus 15. Mai. 2019, 09:00


PolyliniemitObjektdatenin3DPolylinieumwandeln1.JPG

 
Bei mir im "nur ACAD" so.

joern bosse 15. Mai. 2019, 10:16

Hallo,
das müßten ganz normale MAP-Objektdaten sein, sind nur bei MAP im Eigenschaftenfenster sichtbar.

Wenn MAP geladen ist können folgende Funktionen von MAP aus LISP heraus verwendet werden:

https://documentation.help/AutoCAD-Map-3D-2009-AutoLISP/ade_odaddrecord.htm

Andreas Kraus 15. Mai. 2019, 10:35

Neue Idee:
Ist es so dass an JEDEM Stützpunkt der Polylinie ein Block "VM" mit dem Einfügepunkt dieses Stützpunktes zu finden ist der Z im Attribut Höhe enthält ?
(Evtl. mit etwas Tolleranz in den Nachkommastellen)

Dann kann man für jeden Punkt den entsprechenden Block filtern, auslesen und hat die Höhe.
Warum hab ich das nicht gleich gesehen 

cadoc 15. Mai. 2019, 10:42

Ja, jeder Stützpunkt hat eine Höhe durch einen Vermessungspunkt.
Akzeptiert die "normale" Polylinie unterschiedliche Z-Werte?

[Diese Nachricht wurde von cadoc am 15. Mai. 2019 editiert.]

Andreas Kraus 15. Mai. 2019, 11:32

Aha.
Dann sollte das hier (mal eben schnell hässlich zusammengetippt) helfen.

Bei mir funktionierts. Die Daten bekomm ich aber mit meinen Mitteln nicht an die 3D-Polylinie.

Bei Fragen zu Lisp ... einfach fragen  

Code:
(defun k_->obj_name (name)
;;; VLA-OBJECT zurückgeben
  (cond
    ((= (type name) 'ENAME)
     (vlax-ename->vla-object name)
    )
    ((= (type name) 'VLA-OBJECT)
     name
    )
    ((= (type name) 'STRING)
     (vlax-ename->vla-object (handent name))
    )
    ((= (type name) 'LIST)
     (vlax-ename->vla-object (cdr (assoc -1 name)))
    )
  )
)

(defun k_satz->entlist (satz)
;;; Elementliste aus Auswahlsatz erstellen
  (if (= (type satz) 'PICKSET)
    (vl-remove-if-not
      '(lambda (dummy) (= (type dummy) 'ENAME))
      (mapcar 'cadr (ssnamex satz))
    )
  )
)

(defun k_get_att (ins name)
;;; Attributinhalt zurückgeben
  (setq ins (k_->obj_name ins))
  (if (and (vlax-property-available-p ins "hasattributes")
   (= (vla-get-hasattributes ins) :vlax-true)
   (not (minusp (vlax-safearray-get-u-bound
  (vlax-variant-value
    (vla-getattributes ins)
  )
  1
)
)
   )
      )
    (vla-get-textstring
      (car (vl-remove-if-not
     '(lambda (att) (= (vla-get-tagstring att) name))
     (vlax-invoke ins 'GetAttributes)
   )
      )
    )
  )
)

(vl-load-com)
(setq ins_list
       (mapcar
'entget
(k_satz->entlist (ssget "x" '((0 . "INSERT") (2 . "VM"))))
       )
)

(foreach ent_data
(mapcar 'entget
(k_satz->entlist (ssget '((0 . "LWPOLYLINE"))))
)
  (setq p_list
(mapcar
   '(lambda (p)
      (append
p
(list
  (atof
    (k_get_att
      (cdr
(assoc
  -1
  (car
    (vl-remove-if-not
      '(lambda (ins)
(equal p
(k_3d->2d (cdr (assoc 10 ins)))
0.01
)
       )
      ins_list
    )
  )
)
      )
      "HOEHE"
    )
  )
)
      )
    )
   (mapcar 'cdr
   (vl-remove-if-not
     '(lambda (data) (= (car data) 10))
     ent_data
   )
   )
)
  )

  (setq points (vlax-make-safearray
vlax-vbDouble
(cons 0 (1- (* (length p_list) 3)))
       )
  )
  (vlax-safearray-fill
    points
    (apply 'append p_list)
  )
  (setq plineObj
(vla-Add3DPoly
   (vla-get-block (vla-get-activelayout (k_ac-doc)))
   points
)
  )
)


cadoc 15. Mai. 2019, 12:10

Also erst mal vielen Dank aber bei mir tut sich da nichts.
Das Lisp fragt nach dem Objekt.
Klicke Polylinie an - wird aber nicht umgewandelt.

Zum Daten dranghängen ist das erwähnte Lisp recht gut.


;;;

Andreas Kraus 15. Mai. 2019, 15:00

Gibts irgendeine Fehlermeldung ?
Ich hab vielleicht eine Funktion vergessen zu kopieren.

Die hier fehlt noch hab ich grade gesehen.

Code:
(defun k_ac-doc ()
  (vla-get-activedocument (vlax-get-acad-object))
)

cadoc 16. Mai. 2019, 08:01

Erstmal ein Danke für deine Arbeit.
Bekomme noch folgende Fehlermeldung:

Befehl:
Objekte wählen: 1 gefunden
Objekte wählen:
; Fehler: no function definition: K_3D->2D

LG

Andreas Kraus 16. Mai. 2019, 08:37

Ich bin aber auch ein Schussel 

Code:
(defun k_3d->2d (wert / dummy)
  (if (vl-every '(lambda (dummy) (= (type dummy) 'LIST)) wert)
    (mapcar '(lambda (dummy) (list (car dummy) (cadr dummy)))
    wert
    )
    (list (car wert) (cadr wert))
  )
)

cadoc 16. Mai. 2019, 08:58

WOW - Also es funktioniert schon mal.
Wo es noch nicht funzt ist:

Objekte wählen: 1 gefunden
Objekte wählen: 1 gefunden, 2 gesamt
Objekte wählen: 1 gefunden, 3 gesamt
Objekte wählen:
; Fehler: Überzählige rechte Klammer in Eingabe

Er zeichnet nur die letzte hoch.

Andreas Kraus 16. Mai. 2019, 09:56

Hm, komisch.
Ich stells hier nochmal komplett rein. Bei mir funktionierts.
Den Namen der Funktion kannst du ja ändern wie du willst.

[CODE][
(defun c  oly->3d-poly (/ DUMMY INS_LIST P PLINEOBJ POINTS P_LIST)
  (defun k_ac-doc ()
    (vla-get-activedocument (vlax-get-acad-object))
  )

  (defun k_3d->2d (wert / dummy)
    (if (vl-every '(lambda (dummy) (= (type dummy) 'LIST)) wert)
      (mapcar '(lambda (dummy) (list (car dummy) (cadr dummy)))
      wert
      )
      (list (car wert) (cadr wert))
    )
  )

  (defun k_->obj_name (name)
;;; VLA-OBJECT zurückgeben
    (cond
      ((= (type name) 'ENAME)
       (vlax-ename->vla-object name)
      )
      ((= (type name) 'VLA-OBJECT)
       name
      )
      ((= (type name) 'STRING)
       (vlax-ename->vla-object (handent name))
      )
      ((= (type name) 'LIST)
       (vlax-ename->vla-object (cdr (assoc -1 name)))
      )
    )
  )

  (defun k_satz->entlist (satz)
;;; Elementliste aus Auswahlsatz erstellen
    (if (= (type satz) 'PICKSET)
      (vl-remove-if-not
'(lambda (dummy) (= (type dummy) 'ENAME))
(mapcar 'cadr (ssnamex satz))
      )
    )
  )

  (defun k_get_att (ins name)
;;; Attributinhalt zurückgeben
    (setq ins (k_->obj_name ins))
    (if (and (vlax-property-available-p ins "hasattributes")
     (= (vla-get-hasattributes ins) :vlax-true)
     (not (minusp (vlax-safearray-get-u-bound
    (vlax-variant-value
      (vla-getattributes ins)
    )
    1
  )
  )
     )
)
      (vla-get-textstring
(car (vl-remove-if-not
       '(lambda (att) (= (vla-get-tagstring att) name))
       (vlax-invoke ins 'GetAttributes)
     )
)
      )
    )
  )

  (vl-load-com)
  (setq ins_list
(mapcar
   'entget
   (k_satz->entlist (ssget "x" '((0 . "INSERT") (2 . "VM"))))
)
  )

  (foreach ent_data
   (mapcar 'entget
   (k_satz->entlist (ssget '((0 . "LWPOLYLINE"))))
   )
    (setq p_list
   (mapcar
     '(lambda (p)
(append
  p
  (list
    (atof
      (k_get_att
(cdr
  (assoc
    -1
    (car
      (vl-remove-if-not
'(lambda (ins)
   (equal p
  (k_3d->2d (cdr (assoc 10 ins)))
  0.01
   )
)
ins_list
      )
    )
  )
)
"HOEHE"
      )
    )
  )
)
      )
     (mapcar 'cdr
     (vl-remove-if-not
       '(lambda (data) (= (car data) 10))
       ent_data
     )
     )
   )
    )

    (setq points (vlax-make-safearray
   vlax-vbDouble
   (cons 0 (1- (* (length p_list) 3)))
)
    )
    (vlax-safearray-fill
      points
      (apply 'append p_list)
    )
    (setq plineObj
   (vla-Add3DPoly
     (vla-get-block (vla-get-activelayout (k_ac-doc)))
     points
   )
    )
  )
  (princ)
)
/CODE]

Edit:
Hab grade gesehen dass in der Zeile wo der Programmcode zuende ist noch die letzte Klammer steht. Vielleicht hast du die nicht mitkopiert.
Ich habs hier mal geändert.

cadoc 16. Mai. 2019, 10:21

   
Perfekt vielen Dank
Das Umwandeln der Polylinie ist damit geschafft.