Results 1 to 9 of 9

Thread: Xref Object Identification

  1. #1
    I could stop if I wanted to
    Join Date
    2012-11
    Location
    Brisbane, Australia
    Posts
    239
    Login to Give a bone
    0

    Default Xref Object Identification

    Hey All

    I am writing a program to navigate around walls and through doors in cad.
    I am working on the clash detection module at the moment and have it working.
    the only problem is, it only works if you run it in the architectural file but we work with the architectural file Xref'd into our drawings.

    I am uncertain how to identify individual objects between 2 points inside an xref and identify their layer and black name.

    Here is the code I have so far:
    Code:
    (defun ClashDetection ( pt1 pt2 )
    	(setq	n		nil
    			s		nil
    			e		nil
    			x1		nil
    			check	nil
    	)
    	(if (setq s (ssget "_F" (list pt1 pt2)))
    		(progn
    			(setq 	i 0
    					n (sslength s)
    			)
    			(repeat n
    				(setq 	e (ssname s i)
    						x1 (cdr (assoc 8 (entget e)))
    						x2 (cdr (assoc 0 (entget e)))
    						WIP	(if (= nil (wcmatch (strcase x2) "*DOOR*"))
    									(if 	(or	(/= nil (wcmatch (strcase x1) "*GENM*,*WALL*,*GLAZ*,*STRUCT*"))
    												(/= nil (wcmatch (strcase x2) "*GENM*,*WALL*,*GLAZ*,*STRUCT*"))
    											)
    										(setq check "T")
    									)
    							)
    						i (1+ i)
    				)
    			)
    		)
    	)
    	print check
    )
    Any Ideas?
    Last edited by Wanderer; 2014-12-19 at 02:34 PM. Reason: added code tags

  2. #2
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,109
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    OK my first thought is nested blocks.

    Imagine having blocks nested inside blocks inside blocks... etc...

    Transforming the coordinate systems and recursing through the block definitions is relatively straight forward... See translate function below

    Code:
    (vl-load-com)
    ;___________________________________________________________________________________________________________
    ; 
    ; Written By Peter Jamtgaard Copr 2014
    ; Translates coordinates from inside a block to the world coordinate system 
    ; (Even under an alternate UCS, the activeX points are always under the World Coordinate Systems)
    ;___________________________________________________________________________________________________________
    
    
    ; Function for transforming a point from block object coordinate system to a world coordinate system.
    ; It handles normals other than (0.0 0.0 1.0)
    ; lstPoint is the point to transform and objBlock is the block object
    
    
    (defun code:TranslateObjectToWorld (objBlock         ; Block object 
                                        lstPointInBlock  ; Coordinates of point (RELATIVE TO BASE POINT)
                                                         ; inside the block
                                        /       
                                        lstPointInWorld  ; Coordinates of point inside the WorldCS
                                        objDocument      ; Document of objBlock
                                        varReturn        ; Variant return of translate coordinates
                                       )
     (setq objDocument (vla-get-document objBlock))
     (setq lstPointInBlock (code:transformpoint lstPointInBlock (vla-get-rotation objBlock))
           varReturn       (vla-translateCoordinates (vla-get-utility objDocument)                
                                                     (vlax-3d-point lstPointInBlock)
                                                     acOCS
                                                     acWorld
                                                     :vlax-false
                                                     (vla-get-normal objBlock)
                           )
     
           lstPointInWorld (vlax-safearray->list (variant-value varReturn))
           lstPointInWorld (mapcar '+ lstPointInWorld (vlax-get objBlock "insertionpoint"))
     )
     lstPointInWorld
    )
    
    
    
    ;___________________________________________________________________________________________________________
    ;
    ; Written By: Peter Jamtgaard copr 2014 
    ; Function for Translating coordinates around the origin using a rotation angle in radians
    ; and returns the rotated point.
    ;___________________________________________________________________________________________________________
    
    
    (defun code:TransformPoint (lstPoint sngTheta)
     (list 
      (+ (* (nth 0 lstPoint) (cos sngTheta))
         (* (nth 1 lstPoint) -1 (sin sngTheta))   
      )
      (+ (* (nth 0 lstPoint) (sin sngTheta))
         (* (nth 1 lstPoint) (cos sngTheta))   
      )
      (nth 2 lstPoint)
     )
    )
    How do you detect a clash?

    The other thought is bpoly.

    Somehow let the bpoly command find the nearest edge.

    Peter
    AutomateCAD

  3. #3
    I could stop if I wanted to
    Join Date
    2012-11
    Location
    Brisbane, Australia
    Posts
    239
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    Cheers Peter, I will give it a go and see how it works.

    I've attached what I have so far, its still in progress but it is coming along.
    it uses an A* path-finding algorithm, I have done my best to re-write it to lisp.

    To test, pick a point in a hallway or room in the building.
    As it stands the program will maneuver around walls and draw a path in all directions at a defined loop (currently refers to each grid being searched).

    As it stand the program is not very impressive but I think the idea behind it can be altered to do some impressive stuff, I just need it working first.
    Attached Files Attached Files

  4. #4
    I could stop if I wanted to
    Join Date
    2012-11
    Location
    Brisbane, Australia
    Posts
    239
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    Hey Peter.
    So I have had a look the code you posted and pondered your response and I am ashamed to say I don't fully understand.
    So can you iterate through all of a block's internal components?
    If so does that mean you have to search all objects inside the block for objects crossing the 2 points?
    If this were to be done on multiple layers of blocks, I am worried how this will slow the program due to this check being run so often.

  5. #5
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,109
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    Can you post a "simple" example of exactly what you are looking for?

    Peter
    AutomateCAD

  6. #6
    I could stop if I wanted to
    Join Date
    2012-11
    Location
    Brisbane, Australia
    Posts
    239
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    Sorry for all the confusion, basically what I need is a clash detection routine routine between 2 points.
    I need the routine to identify everything between the 2 points regardless, if it is in an xref or not.

    This is the current routine I have however it does not look inside xrefs (I believe you helped me with this on another thread).
    (defun ClashDetection ( lstPoint1 lstPoint2 )
    (ssget "_f" (list lstPoint1 lstPoint2)
    (list (cons 8 "*GENM*,*WALL*,*WALL,*GLAZ*,*GLAZ"))
    )
    )

  7. #7
    All AUGI, all the time
    Join Date
    2015-10
    Location
    Belgrade, Serbia, Europe
    Posts
    564
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    Code:
    (defun ClashDetection ( pt1 pt2 / ss_fnestelst n s e x1 x2 check WIP )
    
      (defun ss_fnestelst ( p1 p2 / unique ss ssn ptsssn ent entl )
    
        (defun unique ( l )
          (if l
            (cons (car l) (vl-remove (car l) (unique (cdr l))))
          )
        )
    
        (setq ss (ssget "_F" (list p1 p2)))
        (if ss
          (progn
            (setq ssn (ssnamex ss))
            (setq ptsssn
                   (mapcar
                     'cadr
                     (apply
                       'append
                       (mapcar '(lambda ( x ) (vl-remove-if-not 'listp x)) ssn)
                     )
                   )
            )
            (foreach pt ptsssn
              (setq ent (car (nentselp pt)))
              (setq entl (cons ent entl))
            )
            (unique entl)
          )
        )
      )
    
      (if (setq s (ss_fnestelst pt1 pt2))
        (progn (setq i 0
                     n (length s)
               )
               (repeat n
                 (setq e   (nth i s)
                       x1  (cdr (assoc 8 (entget e)))
                       x2  (cdr (assoc 0 (entget e)))
                       WIP (if (= nil (wcmatch (strcase x2) "*DOOR*"))
                             (if (or (/= nil
                                         (wcmatch (strcase x1)
                                                  "*GENM*,*WALL*,*GLAZ*,*STRUCT*"
                                         )
                                     )
                                     (/= nil
                                         (wcmatch (strcase x2)
                                                  "*GENM*,*WALL*,*GLAZ*,*STRUCT*"
                                         )
                                     )
                                 )
                               (setq check T)
                             )
                           )
                       i   (1+ i)
                 )
               )
        )
      )
      check
    )
    HTH, M.R.
    Last edited by marko_ribar; 2015-01-20 at 07:56 AM. Reason: code now passed tests

  8. #8
    All AUGI, all the time
    Join Date
    2015-10
    Location
    Belgrade, Serbia, Europe
    Posts
    564
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    However, I've found some issues that I fixed in your main routine... Whenever it's possible avoid using (command) function to setup sysvars - instead use (setvar)... I've added undomarks also, so you can quickly undo routine processing in one single "U" call... Also I've fixed my mistake in above posted function - added (if ss ... ) as when no sel. set - empty subfunction would fail, this way it's doing what it's supposed to do...

    Code:
    ;;-------------------STANDARD LISP--------------------;;
    ;;--Description                                     --;;
    ;;--Description                                     --;;
    ;;--Description                                     --;;
    ;;--Description                                     --;;
    ;;--Description                                     --;;
    ;;----------------------------------------------------;;
    ;;--Designed by:	Matthew Mortimer                --;;
    ;;--email:			Matthew.e.mortimer@hotmail.com  --;;
    ;;----------------------------------------------------;;
    (defun c:test (/            *error*      ClashDetection
                   *adoc*       dwgname      dwgprefix    osmode
                   clayer       filedia      pdmod        EndPoint
                   Increment    WIPInt       i1           i2
                   i3           Frontier     Visited      CurrentPoint
                   FrontierProposed
                  )
    ;;;;;--------------------ERROR CHECKING-------------------;;;;;
      (defun *error* (msg)
        (setvar "filedia" 1)
        (cond ((not msg))                   ; Normal exit
              ((member msg '("Function cancelled" "quit / exit abort")))
                                            ; <esc> or (quit)
              ((princ (strcat "\n** Error: " msg " ** ")))
                                            ; Fatal error, display it
        )
        (vla-endundomark *adoc*)
        (princ)
      )
    ;;;;;--------------------ERROR CHECKING-------------------;;;;;
      (defun ClashDetection
             (pt1 pt2 / ss_fnestelst n s e x1 x2 check i WIP)
        (defun ss_fnestelst (p1 p2 / unique ss ssn ptsssn ent entl)
          (defun unique (l)
            (if l
              (cons (car l) (vl-remove (car l) (unique (cdr l))))
            )
          )
          (setq ss (ssget "_F" (list p1 p2)))
          (if ss
            (progn (setq ssn (ssnamex ss))
                   (setq ptsssn
                          (mapcar
                            'cadr
                            (apply
                              'append
                              (mapcar '(lambda (x) (vl-remove-if-not 'listp x))
                                      ssn
                              )
                            )
                          )
                   )
                   (foreach pt ptsssn
                     (setq ent (car (nentselp pt)))
                     (setq entl (cons ent entl))
                   )
                   (unique entl)
            )
          )
        )
        (if (setq s (ss_fnestelst pt1 pt2))
          (progn (setq i 0
                       n (length s)
                 )
                 (repeat n
                   (setq e   (nth i s)
                         x1  (cdr (assoc 8 (entget e)))
                         x2  (cdr (assoc 0 (entget e)))
                         WIP (if (= nil (wcmatch (strcase x2) "*DOOR*"))
                               (if (or (/= nil
                                           (wcmatch (strcase x1)
                                                    "*GENM*,*WALL*,*GLAZ*,*STRUCT*"
                                           )
                                       )
                                       (/= nil
                                           (wcmatch (strcase x2)
                                                    "*GENM*,*WALL*,*GLAZ*,*STRUCT*"
                                           )
                                       )
                                   )
                                 (setq check T)
                               )
                             )
                         i   (1+ i)
                   )
                 )
          )
        )
        check
      )                                     ;----------[PRE-ROUTINE]-------------------------------
      (setq dwgname   (getvar "dwgname")
            dwgprefix (getvar "dwgprefix")
            osmode    (getvar "osmode")
            clayer    (getvar "clayer")
            filedia   (getvar "filedia")
            pdmod     (getvar "pdmode")
      )
      (vl-load-com)
      (setq *adoc* (vla-get-activedocument (vlax-get-acad-object)))
      (vla-startundomark *adoc*)            ;----------[PRE-ROUTINE]-------------------------------
      (setq EndPoint  (getpoint "\nPick Desired Room: ")
            Increment 500
            WIPInt    (getint "\nEnter Number: ")
            i1        1
            i2        0
            i3        0
            Frontier  (list EndPoint)
            Visited   (list)
      )
      (repeat WIPInt
        (setq CurrentPoint (nth (1- (length Frontier)) Frontier)
              Frontier     (vl-remove CurrentPoint Frontier)
              Visited      (cons CurrentPoint Visited)
              i1           1
        )
        (repeat 4
          (setq FrontierProposed (cond ((= i1 1)
                                        (list (+ (nth 0 CurrentPoint) Increment)
                                              (nth 1 CurrentPoint)
                                              (nth 2 CurrentPoint)
                                        )
                                       )
                                       ((= i1 2)
                                        (list (nth 0 CurrentPoint)
                                              (+ (nth 1 CurrentPoint) Increment)
                                              (nth 2 CurrentPoint)
                                        )
                                       )
                                       ((= i1 3)
                                        (list (- (nth 0 CurrentPoint) Increment)
                                              (nth 1 CurrentPoint)
                                              (nth 2 CurrentPoint)
                                        )
                                       )
                                       ((= i1 4)
                                        (list (nth 0 CurrentPoint)
                                              (- (nth 1 CurrentPoint) Increment)
                                              (nth 2 CurrentPoint)
                                        )
                                       )
                                 )
                Frontier         (if (member FrontierProposed Visited)
                                   Frontier
                                   (if (ClashDetection CurrentPoint FrontierProposed)
                                     Frontier
                                     (cons FrontierProposed Frontier)
                                   )
                                 )
                i1               (1+ i1)
          )
        )
      )
      (setvar "osmode" 0)
      (setvar "pdmode" 35)
      (repeat (length Frontier)
        (command "point" (nth i2 Frontier))
        (setq i2 (1+ i2))
      )
      (setvar "pdmode" 0)
      (setvar "clayer" "defpoints")
      (repeat (length Visited)
        (command "point" (nth i3 Visited))
        (setq i3 (1+ i3))
      )
      (setvar "clayer" "0")                 ;----------[POST-ROUTINE]-----------------------------
      (setvar "osmode" osmode)
      (setvar "clayer" clayer)
      (setvar "filedia" filedia)
      (setvar "pdmode" pdmod)               ;----------[POST-ROUTINE]-----------------------------
      (*error* nil)
    )
    Only one side note - as experienced drawer you actually don't need this function - it's obvious which rooms are dead - no entrances - this is classical mistake... Avoid such situations - put just a single door if that is adequate, but one door is minimum you should predict, unless those rooms are some kind of isolated spaces with entrances in floor or ceiling or they represent some kind of shafts for elevators, ventilation, etc...

  9. #9
    I could stop if I wanted to
    Join Date
    2012-11
    Location
    Brisbane, Australia
    Posts
    239
    Login to Give a bone
    0

    Default Re: Xref Object Identification

    Cheers for that mate, I had a play around with it and it works a treat.
    The only place where it is falling down is with dynamic blocks.
    Something about dynamic blocks is making it ignore both criteria of block name and layer.
    Any ideas?

Similar Threads

  1. 2014: Xref Object
    By mbrandt5 in forum AutoCAD General
    Replies: 8
    Last Post: 2015-04-23, 07:43 PM
  2. xref object from source dwg only
    By mbrandt5 in forum AutoLISP
    Replies: 8
    Last Post: 2015-04-22, 04:00 PM
  3. object fields in xref
    By randyspear in forum AutoCAD Fields
    Replies: 1
    Last Post: 2013-07-16, 06:41 AM
  4. Object identification with location information
    By dfi in forum Revit - Platform
    Replies: 3
    Last Post: 2009-09-12, 08:58 AM
  5. Select an object within an XREF
    By autocad.wishlist1734 in forum AutoCAD Wish List
    Replies: 3
    Last Post: 2007-09-19, 06:49 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •