aridzv Posted April 18, 2020 Posted April 18, 2020 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. Quote
Jonathan Handojo Posted April 18, 2020 Posted April 18, 2020 (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 April 18, 2020 by Jonathan Handojo Quote
Jonathan Handojo Posted April 18, 2020 Posted April 18, 2020 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? Quote
aridzv Posted April 18, 2020 Author Posted April 18, 2020 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 Quote
aridzv Posted April 18, 2020 Author Posted April 18, 2020 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. Quote
BIGAL Posted April 18, 2020 Posted April 18, 2020 (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 April 18, 2020 by BIGAL Quote
Jonathan Handojo Posted April 19, 2020 Posted April 19, 2020 (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 April 19, 2020 by Jonathan Handojo Quote
aridzv Posted April 19, 2020 Author Posted April 19, 2020 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? Quote
Jonathan Handojo Posted April 19, 2020 Posted April 19, 2020 (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 April 19, 2020 by Jonathan Handojo Quote
BIGAL Posted April 21, 2020 Posted April 21, 2020 This post has some interesting solutions by Gile. https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/td-p/2745633 I managed to get the Cal function ILP(p1,p2,p3,p4,p5) to work but would need some of the gile functions to find the correct 3dface. Quote
Recommended Posts
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.