convert 2d polyline to 3d polyline from bloc point elevations

convert 2d polyline to 3d polyline from bloc point elevations

mihai_bantas
Enthusiast Enthusiast
571 Views
4 Replies
Message 1 of 5

convert 2d polyline to 3d polyline from bloc point elevations

mihai_bantas
Enthusiast
Enthusiast

hello everyone, I'm bringing up a problem that I face daily.
I have various files received from geodetic engineers that contain points in the form of blocks with attribute (COTA) and 2d polylines that do not contain elevation on Z (0.000).
What I want to do is to transform these 2d polylines that pass through the attribute blocks into 3d polylines.

 

I have a lisp code that helps me do this operation, but it only applies to 3D points and not to attribute blocks...if there is someone more willing to help me with the modification of this code, I would be deeply grateful. (I attach it below the lisp code and  example file)

Good day everyone and I appreciate every help received.
Thank you.

0 Likes
Accepted solutions (1)
572 Views
4 Replies
Replies (4)
Message 2 of 5

Kent1Cooper
Consultant
Consultant
Accepted solution

If, as it appears, the Blocks have their insertion points at the XY locations of the vertices of the Polylines, with the only difference being the Z coordinate, and since the DXF 10-code entry is the same for Block insertion points as for Point locations, does it work to just add INSERT to the entity types that the Fence selection is looking for?

(setq ss (ssget "f" co-ordsxy (list (cons 0 "POINT,INSERT"))))

Kent Cooper, AIA
Message 3 of 5

mihai_bantas
Enthusiast
Enthusiast

thank you for your time, it works perfectly.

0 Likes
Message 4 of 5

CADaSchtroumpf
Advisor
Advisor

An another.

(vl-load-com)
(defun c:test ( / ss_pl AcDoc Space n ent dxf_ent prm lst_pt pt ss_blk obj lst_att val)
  (princ "\nSelect polylines")
  (setq ss_pl
    (ssget
      (list
        (cons 0 "*POLYLINE")
        (cons 67 (if (eq (getvar "CVPORT") 2) 0 1))
        (cons 410 (if (eq (getvar "CVPORT") 2) "Model" (getvar "CTAB")))
        (cons -4 "<NOT")
         (cons -4 "&") (cons 70 126)
        (cons -4 "NOT>")
      )
    )
  )
  (setq
    AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
    Space
    (if (eq (getvar "CVPORT") 1)
      (vla-get-PaperSpace AcDoc)
      (vla-get-ModelSpace AcDoc)
    )
  )
  (cond
    (ss_pl
      (repeat (setq n (sslength ss_pl))
        (setq
          ent (ssname ss_pl (setq n (1- n)))
          dxf_ent (entget ent)
          prm -1
          lst_pt nil
        )
        (repeat
          (if (zerop (cdr (assoc 70 dxf_ent)))
            (1+ (fix (vlax-curve-getEndParam ent)))
            (fix (vlax-curve-getEndParam ent))
          )
          (setq
            pt (vlax-curve-GetPointAtParam ent (setq prm (1+ prm)))
            ss_blk
            (ssget "_X"
              (list
                '(0 . "INSERT")
                '(2 . "Punct")
                '(-4 . "<AND")
                  '(-4 . ">=,>=,*") (cons 10 pt)
                  '(-4 . "<=,<=,*") (cons 10 pt)
                '(-4 . "AND>")
              )
            )
            val
            (cond
              ((and ss_blk (eq (sslength ss_blk) 1))
                (setq
                  obj (vlax-ename->vla-object (ssname ss_blk 0))
                  lst_att
                  (mapcar
                    '(lambda (x) (cons (vla-get-TagString x) (vla-get-TextString x)))
                    (vlax-invoke Obj 'GetAttributes)
                  )
                  val (atof (cdr (assoc "COTA" lst_att)))
                  lst_pt (cons (list (car pt) (cadr pt) val) lst_pt)
                )
              )
            )
          )
        )
        (if (> (length lst_pt) 1)
          (vlax-invoke Space 'Add3DPoly (apply 'append lst_pt))
        )
      )
    )
  )
  (prin1)
)

 

0 Likes
Message 5 of 5

Kent1Cooper
Consultant
Consultant

Further things occur to me....  The extracting of vertex locations from the selected Polyline, to use for the fence selection of Points/Blocks, can be quite a bit simpler, making it unnecessary to differentiate between whether it's lightweight or heavy to divide up a 'Coordinates list into either 2- or 3-coordinate lists.  And it's not necessary to then make a list of Point/Block insertion points before drawing the 3DPolyline with them -- they can be pulled from the selected objects right out of the selection set.

This is about 1/3 the length of your original, but works for me in your sample drawing:

(defun c:plverts (/ ent n co-ords ss oldsnap oldzsnap x)
  (setq ent (car (entsel "\nplease pick pline")))
  (repeat (setq n (1+ (fix (vlax-curve-getEndParam ent))))
    (setq co-ords (cons (vlax-curve-getPointAtParam ent (setq n (1- n))) co-ords))
  )
  (entdel ent)
  (setq ss (ssget "_f" co-ords '((0 . "POINT,INSERT"))))
  (setq oldsnap (getvar 'osmode))
  (setvar 'osmode 0)
  (setq oldzsnap (getvar 'osnapz))
  (setvar 'osnapz 0)
  (command "_.3dpoly")
  (repeat (setq x (sslength ss))
    (command (cdr (assoc 10 (entget (ssname ss (setq x (1- x)))))))
  )
  (command "")
  (setvar 'osmode oldsnap)
  (setvar 'osnapz oldzsnap)
  (prin1)
)
(vl-load-com)
(c:plverts)

It could also use some other added elements not present in your posted code, particularly a check on whether the selected Polyline is, in fact, the right kind of thing, but also *error* handling to ensure resetting of the System Variables, and Undo begin/end wrapping.

Kent Cooper, AIA
0 Likes