Arrow on 3d polyline to show water flow direction - LISP

Arrow on 3d polyline to show water flow direction - LISP

yu85.info
Collaborator Collaborator
596 Views
5 Replies
Message 1 of 6

Arrow on 3d polyline to show water flow direction - LISP

yu85.info
Collaborator
Collaborator

Hi, I will appreciate if someone could help modify this nice LISP written by Stefan and Jonathan that I founded here:

https://www.cadtutor.net/forum/topic/57478-arrow-on-3d-polyline-to-show-water-flow-direction/

 

This lisp adds arrows symbol to a 3D polyline to show water flow direction (based on Z values).

 

Is it possible to modify it so instead of arrows created in 2D polylines, all the arrows on a single object will turn to a block with an insertion point in the middle of it.

I have attached a DWG file with an example of the current situation and the desired one (made manually).

Thank you very much in advance

 

This is the lisp:

 

;Show flow direction
;Stefan M. - 26.07.2015
(defun c:flow ( / *error* ms ss e l key d i n c y p f a p1 p2 p3 ar) ; Variable 'i' localised (Jonathan Handojo)
 (or acDoc (setq acDoc (vla-get-activedocument (vlax-get-acad-object))))
 (setq ms (vlax-get acDoc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace)))
 (vla-startundomark acDoc)
 
 (defun *error* (msg)
   (and
     msg
     (not (wcmatch (strcase msg) "*CANCEL*,*QUIT*,*EXIT*"))
     (princ (strcat "\nError: " msg))
   )
   (vla-endundomark acDoc)
   (princ)
 )
 (if
   (eq (vla-get-lock (vla-get-activelayer acdoc)) :vlax-true)
   (progn
     (princ "\nCurrent Layer is locked.")
     (exit)
     )
   )
 
 (if
   (setq ss (ssget '((0 . "POLYLINE") (-4 . "&=") (70 . 8)))) ; Modified to multiple selection (Jonathan Handojo)
   (progn
     (or (tblsearch "layer" "arrow") (vla-add (vla-get-layers acDoc) "arrow"))
;;;     (setq e (ssname ss 0) ; Commented (Jonathan Handojo)
;;;           l (vlax-curve-getdistatpoint e (vlax-curve-getendpoint e))
;;;           )
     (initget "Distance Items" 1)
     (setq key (getkword "\nChoose a method [Distance/Items]: ")) ; Modified (Jonathan Handojo)
     (if
       (eq key "Distance")
       (setq d (getdist "\nDistance between arrows: "))
       (setq n (getint  "\nNumber of arrows: "))
       )
     (repeat (setq i (sslength ss)) ; Repeat loop (Jonathan Handojo)
(setq i (1- i) e (ssname ss i) ; Curve details moved here (Jonathan Handojo)
           l (vlax-curve-getdistatpoint e (vlax-curve-getendpoint e))
           )
     (if n (setq d (/ l n)))
     (if d
       (progn
         (setq c 0.0 y (/ d 5.0))
         (while (< (setq c (+ c d)) l)
           (setq p (vlax-curve-getpointatdist e c)
                 f (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e p))
                 a (angle '(0.0 0.0) f)
                 p1 (polar p a (if (minusp (caddr f)) (- y) y))
                 p2 (polar p1 (+ a (* pi 0.5)) (* 0.4 y))
                 p3 (polar p1 (- a (* pi 0.5)) (* 0.4 y))
                 ar (vla-Add3DPoly ms
                      (vlax-safearray-fill
                        (vlax-make-safearray vlax-vbDouble '(0 . 8))
                        (append p2 p p3)
                        )
                      )
                 )
           (vla-put-closed ar :vlax-true)
;;;            (vla-put-color ar (if (minusp (caddr f)) acred acyellow))
           (vla-put-layer ar "arrow")
           )
         )
       )
) ; Repeat loop end (Jonathan Handojo)
     ) 
   )
 (*error* nil)
 (princ)
 )

 

0 Likes
597 Views
5 Replies
Replies (5)
Message 2 of 6

Sea-Haven
Mentor
Mentor

Would it not be easier to use a linetype with an arrow. 

 

*Arrowsolid,->->->-
A,4.8,["►",Arial,S=1.0,R=0.0,X=0.0,Y=-0.375],-1.2

*INVERT_ARROW,Drain invert arrow -----<--------
A,20,[INVERT_ARROW,Custom.shx,s=0.25],20

*SUBSOIL_DRAIN_LEFT,Subsoil drain left ----<----<----<----<----<----<--
A,40,-5.08,["<",STANDARD,S=1.8,R=0.0,X=-1.8,Y=-.9],-3

 

Message 3 of 6

yu85.info
Collaborator
Collaborator
Of course, but I must use 3D polyline in the drawing for technical issues.
So line type won't do for this problem. Thank you anyway sir
0 Likes
Message 4 of 6

Sea-Haven
Mentor
Mentor

I just thought of that myself 3dpoly. Need insert a block arrow. would be in XY plane but at say Z rl with rotation.

 

Try this may need a block scale.

 

 

 

 

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/arrow-on-3d-polyline-to-show-water-flow-direction-lisp/td-p/12789833
; put arrow block on a 3d pline
; By AlanH May 2024

(defun c:arrows ( / alg-ang oldsnap obj dist spac num len )

(defun alg-ang (obj pnt)
  (angle '(0. 0. 0.)
     (vlax-curve-getfirstderiv
       obj
       (vlax-curve-getparamatpoint
         obj
         pnt
       )
     )
  )
)

(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)
(setq oldang (getvar 'Aunits))
(setvar 'aunits 3)

(setq obj (vlax-ename->vla-object (car (entsel "\nSelect a pline object "))))
(setq dist (getreal "\nEnter spacing "))

(setq spac 0.0)
(setq len (vlax-get obj 'length))
(setq num (fix (/ len dist)))

(repeat num
  (setq spac (+ spac dist))
  (princ (setq pt (vlax-curve-getpointatdist obj spac)))
  (setq ang (alg-ang obj pt))
  (command "-insert" "your arrow block" pt 1 1 ang)
)

(setvar 'osmode oldsnap)
(setvar 'Aunits oldang)
(princ)
)

 

 

 

 

Message 5 of 6

yu85.info
Collaborator
Collaborator

Thank you sir. Sorry for my rudeness but in order to create every arrow along the 3D polyline I need to click each time on the 3D polyline. And in addition I don't think my arrow block I made is very good 😞 ...

 

yu85info_0-1716448458566.png

 

0 Likes
Message 6 of 6

Sea-Haven
Mentor
Mentor

Is it a single pline or multiple it should draw all along given suitable spacing. Ok my mistake the ang is in radians amended code above. I tested 3 spacing, pline 34 long. Multiple appear.

0 Likes