Jump to content

LISP to apply list of commands on a collection of 3D poly lines


Recommended Posts

Posted

Hi.

I have a collection of 3D poly lines (see Fig. 1 and 1-A), and I'm looking for a lisp that will do the follows:

1.draw a point object at the start of every  line (vertex No.1) - see figure 2

2. create an Path array from that point object and the 3d polyline. the Array parameters will be set now for the rest of 3d Polyline's collection. (Fig. 3)

3. explode the array so it can be used to the points to draw the 3d polyline from them (Fig.4)

4. draw a 3d polyline from the point collection (Fig 5 & 6) by using use a lisp command called polFPoints.lsp. i found this lisp in this thread and the lisp was made by the user JohnM - MANY THANKS AND A FULL CREDIT TO jhonM!!! 

5. then i need to apply this set of actions to all the 3D polylines in the collection (See End Result in Fig.7) using the array parameters from step 2.

 

 i'm relay lost here,

and will be thankful for any kind of help!!

thanks,

Arid. 

 

5.JPG

6.JPG

7.JPG

1.JPG

1-A.JPG

2.JPG

3.JPG

4.JPG

Posted (edited)

Can you maybe label which is Fig 1, Fig 2... Makes it easier for us to understand

 

From what I'm able to decipher, you want to draw a point at some interval from the start of the polyline. You don't really have to array it to find the points. This can be easily achieved by using vlax-curve-GetPointAtDist and incrementing the distance by a fixed amount. After which from there you can use those points to do anything... be it drawing a polyline, or even points.

 

Here's a function that you can use to get your list of points resulting from a path array given the curve entity, array distance, starting distance, and end distance:

 

;; JH:PathArrayPts --> Jonathan Handojo
;; Returns a list of points resulting from path array
;; given the starting, array, and end distance
;; crv - curve object (ename or VLA)
;; dist - array distance
;; start - starting distance
;; end - end distance (if nil or greater than curve length,
;;       this will be to the end of the curve)

(defun JH:PathArrayPts (crv dist start end / endpm len rtn startpm)
  (setq len (vlax-curve-getDistAtParam crv (vlax-curve-getEndParam crv))
	start (- start dist)
	end (if (or (null end) (> end len)) len end)
	endpm (vlax-curve-getParamAtDist crv end)
	)
  (while
    (and (setq startpm (vlax-curve-getParamAtDist crv (setq start (+ start dist))))
	 (<= startpm endpm)
	 )
    (setq rtn (cons (vlax-curve-getPointAtDist crv start) rtn))
    )
  (reverse rtn)
  )

 

Edited by Jonathan Handojo
Posted

So if you load the above, this example will draw a point on each one... This example is really no different than doing a regular path array on the curve (without rotation and any other settings).

 

(defun c:whatever ( / *error* adoc dist ent i ss)
  (defun *error* (msg) (vla-EndUndoMark adoc) (princ (strcat "\nError: " msg)))
  (setq adoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (vla-StartUndoMark adoc)

  ;; Start Routine

  (if (setq ss (ssget '((0 . "LINE,*POLYLINE,ARC,ELLIPSE,SPLINE"))))	; Get selection set
    (progn
      (setq dist (progn (initget 7) (getdist "\nSpecify array distance: ")))	; Get array distance
      (repeat (setq i (sslength ss))	; Loop through each curve in the selection
	(foreach x (JH:PathArrayPts (setq ent (ssname ss (setq i (1- i)))) dist 0 nil)	; Get path array points and loop through each point
	  (entmake (list '(0 . "POINT") (cons 10 x) '(50 . 0)))	; In this case, I've drawn a point.
	  							; (Really no different than just doing path array on a point for this case)
	  )
	)
      )
    )

  ;; End Routine
  
  (vla-EndUndoMark adoc)
  (princ)
  )

 

From what I understand from OP, you want to get list of points from array, and then draw polyline from it? Why would you need to draw another polyline if you already have one?

 

Posted

Jonathan Handojo - thanks for the reply and effort!

1. i'm sorry about the images. i'm uploading them again with labels.

2. the first polyline is a result of feature line of a TIN mesh of topography. i need to get a polyline with a fixed intervals,but one that will still use the elevation of the original polyline. that is why i create a path array of points with fixed distance along the first polyline and then convert it to the result ployline. the result polyline vertex's represent the location and elevation of irrigation emitters.

3. i didnt yet tested your lisp. i will get to it A.S.A.P and get back here to let you know about it

4.JPG

5.JPG

6.JPG

7.JPG

1.JPG

1-A.JPG

1-B.JPG

2.JPG

3.JPG

Posted

Jonathan Handojo - thanks,those 2 routine are working perfectly.

is it possible to add to it  a routine that do the last part - create from each set of points a 3D polyline like it is shown in fig. 5-6-7 with the polFPoints.lsp

thanks,

aridzv.

Posted (edited)

If you have a TIN mesh there is a formula to calculate the z value of a point. Civ3D has a built in feature to do this so can do a grid of points and they are moved to the TIN.

 

Google for formula point formula and "is point within pline" to workout which 3dface.

 

What software was used to make the original tin and 3dpline ?

Edited by BIGAL
Posted (edited)
3 hours ago, aridzv said:

Jonathan Handojo - thanks,those 2 routine are working perfectly.

is it possible to add to it  a routine that do the last part - create from each set of points a 3D polyline like it is shown in fig. 5-6-7 with the polFPoints.lsp

thanks,

aridzv.

 

Come on... almost anything is possible when it comes to LISP. And I only need to add a few lines to the previous code instead of the routine you found:

 

(defun c:whatever ( / *error* adoc arpts dist ent i msp pts ss)
  (defun *error* (msg) (vla-EndUndoMark adoc) (princ (strcat "\nError: " msg)))
  (setq adoc (vla-get-ActiveDocument (vlax-get-acad-object))
	msp (vla-get-ModelSpace adoc)
	)
  (vla-StartUndoMark adoc)

  ;; Start Routine

  (if (setq ss (ssget '((0 . "LINE,*POLYLINE,ARC,ELLIPSE,SPLINE"))))	; Get selection set
    (progn
      (setq dist (progn (initget 7) (getdist "\nSpecify array distance: ")))	; Get array distance
      (repeat (setq i (sslength ss))	; Loop through each curve in the selection
	(setq pts (JH:PathArrayPts (setq ent (ssname ss (setq i (1- i)))) dist 0 nil)	; Get path array points
	      arpts (apply 'append pts)	; Get array points for polyline
	      )
	(vla-Add3DPoly msp (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length arpts)))) arpts))	; Make polyline
	(foreach x pts	; Loop through each point
	  (entmake (list '(0 . "POINT") (cons 10 x) '(50 . 0)))	; Draw a point
	  )
	)
      )
    )

  ;; End Routine
  
  (vla-EndUndoMark adoc)
  (princ)
  )

 

If you must use the routine you found, just set the variable "plst" with "pts" from the above code.

 

Edited by Jonathan Handojo
Posted

Jonathan Handojo - THANKS!!

the last lisp is working perfectly!

6 hours ago, Jonathan Handojo said:

If you must use the routine you found, just set the variable "plst" with "pts" from the above code.

i don't need to use the routine i have found,but just for the exercise - i didn't found variable "plst" in the last routine you posted.

 where it is found and how and where do i make the call to that lsp?

 

Posted (edited)
6 minutes ago, aridzv said:

Jonathan Handojo - THANKS!!

the last lisp is working perfectly!

i don't need to use the routine i have found,but just for the exercise - i didn't found variable "plst" in the last routine you posted.

 where it is found and how and where do i make the call to that lsp?

 

 

You're welcome aridzv.

 

Sorry, I was mistaken. The routine you found draws from selecting a list of points, while this one draws from selecting a list of curves. My function calculates points from a given curve entity, so using the routine you found would've failed anyway, unless it was modified to something exactly like this routine.

Edited by Jonathan Handojo

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...