Jump to content

Solids intersection and something else...


cletero

Recommended Posts

Hi, I would like to ask for some help, if there's a way of achieving the same results as the following LISP in a faster way, what I need is to obtain the Z coordinate of the tip of the cylindrical object at the moment it stops intersecting with the base object (which can have any form). It will be precise to a resolution (res) which is user selected.

I have cut down the code to post it here, but basically this needs to be repeated at several X,Y coordinates. Getting the coordinates is easy, but not sure if there's a better way of obtaining the intersection point. I do not need the cylinder to be shown either, as I said, what I need is the coordinates only. I.e: I'm also trying to generate an STL of both solids and obtain a cloud point to find intersection, but seems complicated ;)

 

Thanks for any help.

 

(defun c:test1 ( / )
 (vl-load-com)

 (setq thisdrawing (vla-get-activedocument (vlax-get-acad-object)))
; This makes the Undo command erase only what's drawn in this lisp
 (vla-StartUndoMark thisdrawing)
; This makes the Undo command erase only what's drawn in this lisp

 (setq cmdsave (getvar "cmdecho"))
 (setvar "cmdecho" 0)
 (setq objsnap (getvar "osmode"))
 (setvar "osmode" 0)

 (setq res 0.001)  ;Final resolution to test for interference, will be user selected
 (setq init_res 1.0)  ;Initial resolution to speed up movement on z-axis

 (command "cylinder" "0,0,0" 6 40)
 (setq cyl (entlast))
 (setq pt2 (list 0 0 6))
 (command "move" cyl "" "0,0,0" pt2)
 (command "sphere" "0,0,0" 6)
 (setq sph (entlast))
 (command "move" sph "" "0,0,0" pt2)
 (command "union" sph cyl "")
 (setq tool (entlast))

 (command "sphere" "0,10,0" 25) ;This could be any solid of any shape
 (setq 3dent (entlast))

 (vinter)
 (setq temp_res init_res)
 (setq pt1 (list 0 0 0))
 (setq pt2 (list 0 0 ptz))
 (command "move" tool "" pt1 pt2)
 (setq pt1 pt2)(vinter)
 (while (and (= interferes "f") (>= temp_res res))
   (setq pt2 (list 0 0 ptz))
   (command "move" tool "" pt1 pt2)
   (vinter)
   (if    (= interferes "t")
     (progn
   (command "move" tool "" pt2 pt1)
   (setq temp_res (* temp_res 0.1))
   (vinter)
       (setq ptz (- (caddr pt1) temp_res))
     ) ;_ end of progn
     (progn
   (setq pt1 pt2)
   (setq ptz (- ptz temp_res))
     ) ;_ end of progn
   ) ;_ end of if
 ) ;_ end of while

 (setvar "cmdecho" cmdsave)
 (setvar "osmode" objsnap)
 (vla-EndUndoMark thisdrawing)
 (princ)
) ;_ end of defun

;This will return "t" if the solids intersect
(defun vinter (/ rest key vlaobject2)
 (setq key t)
 (setq
   rest (vla-CheckInterference
      (vlax-ename->vla-object tool)
      (vlax-ename->vla-object 3dent)
      key
    ) ;_ end of vla-CheckInterference
 ) ;_ end of setq
; Curiously, if on last line I put 3dent before tool, intesect fails when it tests a tool against
; a flat box. The same happens if done by hand in AutoCAD, try it.
 (if rest
   (progn
     (setq interferes "t")
     (setq vlaobject2 (vlax-ename->vla-object (entlast)))
     (vla-GetBoundingBox vlaobject2 'minb 'maxb)
     (setq maxb (vlax-safearray->list maxb))
     (setq ptz (caddr maxb))
   ) ;_ end of progn
   (setq interferes "f")
 ) ;_ end of if
 (if (= interferes "t")
   (entdel (entlast))
 ) ;_ end of if
) ;_ end of defun

Link to comment
Share on other sites

Hi, thanks for your answer.

 

Being a "self-taught" LISP user/programmer, I did a quick search for "cal" functions in the AutoCAD help file, but couldn't find anything for 3dsolids. I did find a couple of usefull things in case I go with the "cloud point" method though. For the same reason, not being a programmer per se I'm not sure about what the ILP acronym stands for, could you please elaborate on it?

 

Thanks again for your help

 

Thankfully, I have enough time and desire to learn for my self, just need a push in the right direction :)

Link to comment
Share on other sites

ILP acronym stand for (Intersect of Line and Plane)... You can use (cal "ilp (p1,p2,t1,t2,t3)") and before that, you must load "geomcal.arx" or "geomcal.crx" for newer CAD releases, but you also have lisp version of this function... It can be found on this link at the bottom of the page...

 

Though I am not exactly sure how it can help you in your problem...

http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/m-p/5243795#M325627

 

M.R.

Edited by marko_ribar
Link to comment
Share on other sites

Thanks hanhphuc and Marko!

 

For some reason I though ILP was some kind of programming technique :?

 

I believe the "ilp" option in geomcal could help me if I go with the generate point cloud option, however it would involve a long process of exporting to STL format, reading the created file to generate a huge vertex list, finding intersections between lines and STL planes, etc etc, etc... which I believe would take longer to process than the method I posted above, so I will continue to search for other options before diving into that :)

Link to comment
Share on other sites

So far, this is the fastest I have been able to make it run, in this case moving along the x-axis, if you are familiar with cnc you'll get the grasp of what I'm trying to achieve:

 

*Edit, I added a very basic timer to track performance, it prints seconds to the command line at program exit

 

(defun c:test2 (/)
 (vl-load-com)

 (setq stopwatch (float (getvar "millisecs")))

 (setq thisdrawing (vla-get-activedocument (vlax-get-acad-object)))
; This makes the Undo command erase only what's drawn in this lisp
 (vla-StartUndoMark thisdrawing)
; This makes the Undo command erase only what's drawn in this lisp

 (setq cmdsave (getvar "cmdecho"))
 (setvar "cmdecho" 0)
 (setq objsnap (getvar "osmode"))
 (setvar "osmode" 0)

 (setq res 0.005) ; 0.005 lasts about 6 secs, 0.001 7 secs and 0.0001 8 secs, at least in my machine
;Resolution for each move along roughing path or each height test in finishing

 (setq init_res 1.0) ;starting with 5 instead of 1 makes almost no difference
;Initial resolution to speed up movement along path or height

 (command "_.cylinder" "0,0,0" 6 40)
 (setq cyl (entlast))
 (setq pt2 (list 0 0 6))
 (command "_.move" cyl "" "0,0,0" pt2)
 (command "_.sphere" "0,0,0" 6)
 (setq sph (entlast))
 (command "_.move" sph "" "0,0,0" pt2)
 (command "_.union" sph cyl "")
 (setq tool (entlast))
;;;  (setq mylist (append mylist (list tool)))

 (setq move_dist 0)

 (command "_.sphere" "24,24,0" 24)
;This could be any solid of any shape, will be user selected
 (setq 3dent (entlast))

 (repeat 48
   (setq pt2 (list 0 0 0))
   (vinter)
   (if (= interferes "t")
     (progn
       (setq temp_res init_res)
       (setq pt1 (list 0 0 0))
       (setq pt2 (list 0 0 ptz))
       (command "_.move" tool "" pt1 pt2)
       (setq pt1 pt2)
       (vinter)
       (while (and (= interferes "f") (>= temp_res res))
         (setq pt2 (list 0 0 ptz))
         (command "_.move" tool "" pt1 pt2)
         (vinter)
         (if (= interferes "t")
           (progn
             (command "_.move" tool "" pt2 pt1)
             (setq temp_res (* temp_res 0.1)) ;using 0.1 is faster than 0.5 by about 20%
             (vinter)
             (setq ptz (- (caddr pt1) temp_res))
           ) ;_ end of progn
           (progn
             (setq pt1 pt2)
             (setq ptz (- ptz temp_res))
           ) ;_ end of progn
         ) ;_ end of if
       ) ;_ end of while
     ) ;_ end of progn
   ) ;_ end of if
   (command "_.move" tool "" "0,0,0" "1,0,0")
   (command "_.move" tool "" pt2 (list (car pt2) (cadr pt2) 0.0))
 ) ;_ end of repeat
 (setvar "cmdecho" cmdsave)
 (setvar "osmode" objsnap)
 (vla-EndUndoMark thisdrawing)
 (princ)

 (setq stopwatch (/ (- (float (getvar "millisecs")) stopwatch) 1000))

) ;_ end of defun
;This will return "t" if the solids intersect
(defun vinter (/ rest key vlaobject2)
 (setq key t)
 (setq
   rest (vla-CheckInterference (vlax-ename->vla-object tool) (vlax-ename->vla-object 3dent) key)
 ) ;_ end of setq
; Curiously, if on last line I put 3dent before tool, intesect fails when it tests a tool
; against a flat box. The same happens if done by hand in AutoCAD, try it.
 (if rest
   (progn
     (setq interferes "t")
     (setq vlaobject2 (vlax-ename->vla-object (entlast)))
     (vla-GetBoundingBox vlaobject2 'minb 'maxb)
     (setq maxb (vlax-safearray->list maxb))
     (setq ptz (caddr maxb))
   ) ;_ end of progn
   (setq interferes "f")
 ) ;_ end of if
 (if (= interferes "t")
   (entdel (entlast))
 ) ;_ end of if
) ;_ end of defun

Edited by cletero
Link to comment
Share on other sites

So obvious I didn't see it:

 

replaced use of command calls with vla and time went down to 20%!!:o

example:

(vla-move (vlax-ename->vla-object tool) (vlax-3d-point pt1)(vlax-3d-point pt2))

instead of:

(command "move" tool "" pt1 pt2)

and

(vla-addline mspace (vlax-3d-point pt1)(vlax-3d-point pt2))

instead of:

(command "_line" pt1 pt2 "")

 

Thank you all for your help, hope this helps anyone else hopping to improve their routines ;)

 

Any other suggestions are welcome

Link to comment
Share on other sites

ILP acronym stand for (Intersect of Line and Plane)... You can use (cal "ilp (p1,p2,t1,t2,t3)") and before that, you must load "geomcal.arx" or "geomcal.crx" for newer CAD releases, but you also have lisp version of this function... It can be found on this link at the bottom of the page...

 

Though I am not exactly sure how it can help you in your problem...

http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/m-p/5243795#M325627

 

M.R.

Thank you Marko for sharing, the arx's ILP has been tested before which got the slowest benchmark.

kudos to custom your LISP's _ILP :thumbsup:

Link to comment
Share on other sites

Thank you Marko for sharing, the arx's ILP has been tested before which got the slowest benchmark.

kudos to custom your LISP's _ILP :thumbsup:

 

Thanks, hanhphuc... For simple ILP like CAL function, no need for checking if intersection point is inside triangle t1,t2,t3... This is how ILP really should operate... BTW. I don't know is LISP version faster, but it may be of some use, as it's unnecessary to check coplanarity and other relations...

 

(defun _ilpp ( p1 p2 t1 t2 t3 / v^v unit _ilp nor o )

 (defun v^v ( u v )
   (list
     (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
     (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
     (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
   )
 )

 (defun unit ( v )
   (mapcar '(lambda ( x ) (/ x (distance '(0.0 0.0 0.0) v))) v)
 )

 (defun _ilp ( p1 p2 o nor / p1p p2p op tp pp p )
   (if (not (equal (v^v nor (unit (mapcar '- p2 p1))) '(0.0 0.0 0.0) 1e-7))
     (progn
       (setq p1p (trans p1 0 (v^v nor (unit (mapcar '- p2 p1))))
             p2p (trans p2 0 (v^v nor (unit (mapcar '- p2 p1))))
             op  (trans o 0 (v^v nor (unit (mapcar '- p2 p1))))
             op  (list (car op) (cadr op) (caddr p1p))
             tp  (polar op (+ (* 0.5 pi) (angle '(0.0 0.0 0.0) (trans nor 0 (v^v nor (unit (mapcar '- p2 p1)))))) 1.0)
       )
       (if (inters p1p p2p op tp nil)
         (progn
           (setq p (trans (inters p1p p2p op tp nil) (v^v nor (unit (mapcar '- p2 p1))) 0))
           p
         )
         nil
       )
     )
     (progn
       (setq pp (list (car (trans p1 0 nor)) (cadr (trans p1 0 nor)) (caddr (trans o 0 nor))))
       (setq p (trans pp nor 0))
       p
     )
   )
 )

 (setq nor (unit (v^v (mapcar '- t3 t1) (mapcar '- t2 t1))))
 (setq o t1)
 
 (if (_ilp p1 p2 o nor)
   (_ilp p1 p2 o nor)
   nil
 )
)

 

P.S. If you want to get code for purpose of "obtaining point of intersection of line and triangle" exactly what was quoted - if line passes through triangle, you can find that code here...

http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/m-p/5338005/highlight/true#M326785

 

M.R.

Edited by marko_ribar
Added P.S. note
Link to comment
Share on other sites

Thanks again guys!

 

Using visual lisp methods vs autocad commands, the routine now runs in 2 minutes instead of 12!! I can't believe how much difference it makes :o:o

 

I will try to test a method with the line-plane intesection routine and see if it works for my purposes :)

Link to comment
Share on other sites

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...