Author Topic: Collision Check of 3DSOLID from Type Cylinder  (Read 3601 times)

0 Members and 1 Guest are viewing this topic.

CADwiesel

  • Newt
  • Posts: 46
  • Wir machen das Mögliche unmöglich
Collision Check of 3DSOLID from Type Cylinder
« on: October 13, 2014, 07:16:45 AM »
Hi there,

i tryed to check some cylinders of collision with some others.
my first try was to get the start and endpoint of an cylinder's centerline and find similar by using the ssget "_C" or "_CP" function. But this won't work like my idea was.
The ssget funktion seems not to be the right way to check for collision, now i hop of your helps.

Maybe there is someone, who have had the same Problem and found an Soloution?
Gruß
CADwiesel
Besucht uns im CHAT

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #1 on: October 13, 2014, 08:39:00 AM »
In theory you can use the 3D editing command _UNION. Calculate the total volume of all cylinders you want to check. Create temporary copies and use the _UNION command and compare the new volume with the old volume. Probably slow.

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #2 on: October 13, 2014, 08:58:21 AM »
In theory you can use the 3D editing command _UNION. Calculate the total volume of all cylinders you want to check. Create temporary copies and use the _UNION command and compare the new volume with the old volume. Probably slow.

You're right Roy... You could use 3D editing command, but I disagree with _UNION... UNION will always add volumes, though not necessarily interfering 3D SOLIDS... I would rather used UNION on cylinders you want to check, create temporary copy of union 3D SOLID... But then I would use _SUBTRACT union 3D SOLID and other 3D SOLIDS that may interfere... Only then if volume is less than old volume there are interferences... Yes it's slow procedure...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

CADwiesel

  • Newt
  • Posts: 46
  • Wir machen das Mögliche unmöglich
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #3 on: October 14, 2014, 01:23:29 AM »
The easyest way, it seems first to me, should be the intersectWith methode, But although its availlable if you use this, it forces an error. Really the Methode isn't availlable. :-(
Than I created for each cylinder an centerline and checked the lines while using the intersectWith methode, but if there are some cylinders overlapping another in the same direction, is no more working.

I can't use the _union or _subtract command, because it will also work with Object, which are not collision to another.

some other ideas?
Gruß
CADwiesel
Besucht uns im CHAT

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #4 on: October 14, 2014, 04:01:50 AM »
I don't understand your objection to the use of _union or _subtract. If you know which objects you need to check you can use it. Note: there is also vla-boolean.

An alternative is to calculate the shortest distance between the center lines and compare this with the radii of the cylinders. I don't know how to calculate that distance.
« Last Edit: October 14, 2014, 04:05:34 AM by roy_043 »

GP

  • Newt
  • Posts: 83
  • Vercelli, Italy
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #5 on: October 14, 2014, 09:29:18 AM »
For a start... if I understand correctly.

Code: [Select]
(defun c:test ( / *error*  sol_ sol n sol1 interf sol_interf ss)

    (defun *error* ( msg )
        (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
    (if (and
            (princ "\nSelect cylinders ")
            (setq sol_ (ssget '((0 . "3DSOLID"))))
        )
        (progn
            (repeat (setq n (sslength sol_))
                (setq sol (cons (ssname sol_ (setq n (1- n))) sol))
            )
            (setq sol1 sol)
            (setq interf 0)
            (mapcar
                '(lambda (a)
                     (mapcar
                         '(lambda (b)
                              (if (vla-CheckInterference (vlax-ename->vla-object a) (vlax-ename->vla-object b) t t)
                                  (progn
                                      (setq sol_interf (cons a sol_interf))
                                      (setq sol_interf (cons b sol_interf))
                                      (entdel (entlast))
                                      (setq interf (1+ interf))
                                  )
                              )
                         )
                         (setq sol1 (cdr sol1))
                     )
                )
                (reverse (cdr (reverse sol)))
            )
            (setq ss (ssadd))
            (foreach ent sol_interf (ssadd ent ss))
            (sssetfirst nil ss)
            (princ
                (strcat
                    "\nNumber of cylindres: " (itoa (sslength ss))
                    " - Number of interferences: "(itoa interf)
                )
            )
        )
    )
    (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
    (princ)
)


CADwiesel

  • Newt
  • Posts: 46
  • Wir machen das Mögliche unmöglich
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #6 on: October 14, 2014, 10:05:46 AM »
Hi GP

yes, this rocks!
I had to change the Part (vla-CheckInterference (vlax-ename->vla-object a) (vlax-ename->vla-object b)  t t)
Removing the last 't because its an error: too much really params
These ist the Soulution of my search - many thanks

Meanwhile i greatet this function:
Code: [Select]
(defun c:check_sol (/ aws_org lastelem newss newelem)
  (if (and
        (princ "\nSelect cylinders ")
        (setq aws_org (ssget '((0 . "3DSOLID"))))
        ) ;_ end of and
    (progn
      (setq lastelem (entlast))
      (vl-cmdf "_-INTERFERE" aws_org "" aws_org "")
      (if (= (getvar "cmdactive") 1)
        (progn
          (command "_Y")
          (if (= (getvar "cmdactive") 1)
            (command "_n")
            ) ;_ end of if
          (if (= (getvar "cmdactive") 1)
            (command "_X")
            ) ;_ end of if
          ) ;_ end of progn
        ) ;_ end of if
      (setq newss (ssadd))
      (while (setq newelem (entnext lastelem))
        (setq newss (ssadd newelem newss))
        (setq lastelem newelem)
        ) ;_ end of while
      (if newss
        (princ (strcat (VL-PRIN1-TO-STRING (sslength newss))
                       " Overlapping Cylinders found!"
                       ) ;_ end of strcat
               ) ;_ end of princ
        ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
  (princ)
  )

But your's thats i looked for.
Thanks again!
Gruß
CADwiesel
Besucht uns im CHAT

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #7 on: October 14, 2014, 01:12:07 PM »
I think that this function by GP isn't totally waterproof... I've tested it on A2014 with both variants (vla-checkinterference vla-obj1 vla-obj2 t t) and (vla-checkinterference vla-obj1 vla-obj2 :vlax-true :vlax-true) and it seems that it doesn't function... After some time I discovered that :vlax-false :vlax-false variant works, but sometime it skips obvious interference, so when run twice it works... I've modified original code to suit and for older versions of ACAD, where I had no problems... So please, verify on A2014, A2015 is it working OK now - I don't have A2015 installed... And if something's wrong please reply... M.R.

Code: [Select]
(defun c:chk3DSOLint ( / *error* sol_ el sol n newrel sol1 interf sol_interf ss )

    (vl-load-com)

    (defun *error* ( msg )
        (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
        (if msg (prompt msg))
        (princ)
    )

    (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
    (if (and
            (princ "\nSelect 3D SOLIDS")
            (progn
                (while (or (null sol_) (< (sslength sol_) 2))
                    (setq sol_ (ssget "_:L" '((0 . "3DSOLID"))))
                    (cond
                        ( (null sol_) (prompt "\nEmpty sel. set... Try selecting again...") )
                        ( (< (sslength sol_) 2) (prompt "\nSelected one 3D SOLID, please select more... Try selecting again...") )
                    )
                )
                t
            )
        )
        (progn
            (setq el (entlast))
            (repeat (setq n (sslength sol_))
                (setq sol (cons (ssname sol_ (setq n (1- n))) sol))
            )
            (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-checkinterference (list (vlax-ename->vla-object (car sol)) (vlax-ename->vla-object (cadr sol)) :vlax-true)))
              (setq newrel t)
              (if (not (eq el (entlast)))
                  (entdel (entlast))
              )
            )
            (setq sol1 sol)
            (setq interf 0)
            (if newrel
                (progn
                    (mapcar
                        '(lambda (a)
                             (mapcar
                                 '(lambda (b)
                                      (if (vla-CheckInterference (vlax-ename->vla-object a) (vlax-ename->vla-object b) :vlax-true 'test)
                                          (progn
                                              (setq sol_interf (cons a sol_interf))
                                              (setq sol_interf (cons b sol_interf))
                                              (entdel (entlast))
                                              (setq interf (1+ interf))
                                          )
                                      )
                                 )
                                 (setq sol1 (cdr sol1))
                             )
                        )
                        (reverse (cdr (reverse sol)))
                    )
                )
                (progn
                    (mapcar
                        '(lambda (a)
                             (mapcar
                                 '(lambda (b)
                                      (if (vla-CheckInterference (vlax-ename->vla-object a) (vlax-ename->vla-object b) :vlax-true)
                                          (progn
                                              (setq sol_interf (cons a sol_interf))
                                              (setq sol_interf (cons b sol_interf))
                                              (entdel (entlast))
                                              (setq interf (1+ interf))
                                          )
                                      )
                                 )
                                 (setq sol1 (cdr sol1))
                             )
                        )
                        (reverse (cdr (reverse sol)))
                    )
                )
            )
            (setq ss (ssadd))
            (foreach ent sol_interf (ssadd ent ss))
            (sssetfirst nil ss)
            (princ
                (strcat
                    "\nNumber of 3D SOLIDS : " (itoa (sslength ss))
                    " - Number of interferences : "(itoa interf)
                )
            )
        )
    )
    (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
    (princ)
)

Thanks, G.P.
« Last Edit: April 25, 2015, 10:14:51 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

CADwiesel

  • Newt
  • Posts: 46
  • Wir machen das Mögliche unmöglich
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #8 on: October 15, 2014, 01:24:29 AM »
I found an description in another Forum
Quote
(vla-CheckInterference vlaobject-sol1 vlaobject-sol2 :vlax-true)
worked in 2012, in 2013 it appears that an extra argument is required.
e.g.
(vla-CheckInterference vlaobject-sol1 vlaobject-sol2 :vlax-true 'test)
The extra argument is a quoted lisp variable, which is set to :vlax-true,
if the solids interfere, and to :vlax-false if they do not..

so it depends on the Acad version how much Arguments are needet to vla-CheckInterference. Also the 4. Argument have to be an Quoted variable not an Argument like 'T or :vlax-true. Maybe than the code runs correctly at the first time, too.
Gruß
CADwiesel
Besucht uns im CHAT

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Collision Check of 3DSOLID from Type Cylinder
« Reply #9 on: October 15, 2014, 02:49:20 AM »
I found an description in another Forum
Quote
(vla-CheckInterference vlaobject-sol1 vlaobject-sol2 :vlax-true)
worked in 2012, in 2013 it appears that an extra argument is required.
e.g.
(vla-CheckInterference vlaobject-sol1 vlaobject-sol2 :vlax-true 'test)
The extra argument is a quoted lisp variable, which is set to :vlax-true,
if the solids interfere, and to :vlax-false if they do not..

so it depends on the Acad version how much Arguments are needet to vla-CheckInterference. Also the 4. Argument have to be an Quoted variable not an Argument like 'T or :vlax-true. Maybe than the code runs correctly at the first time, too.

Thanks, CADwiesel, I've tested and now it works as it should - from first attempt... I've updated my previous posted code...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube