Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dimensions Between Objects over Intervals

17 REPLIES 17
Reply
Message 1 of 18
bemmer7MZ3G
444 Views, 17 Replies

Dimensions Between Objects over Intervals

I get 3d scans and have to square them off, sometimes this means showing how far the scan is from a straight line every 8", 16", 24", and so forth. I am trying to write a lisp program that I can select my straight line, set the distance interval, and select the polyline I am measuring to, and have that set a node at every interval and draw a perpendicular line across the polyline, find the intersection of those and put a new node, then delete that temporary line and dimension between the two points. What I have so far will do the nodes and the lines, but it cannot find the intersections or do the dimensions from there. I have attached my code and my test file, is there something wrong with my syntax or the way I am going about it?

Tags (2)
17 REPLIES 17
Message 2 of 18
Moshe-A
in reply to: bemmer7MZ3G

@bemmer7MZ3G  hi,

 

in your code i see you are using variable name 'length' but that is a function in lisp. i change it to leng and i seems to work but seeing the result i thought why don't you use measure command to do that?

with measure (or divide) command you could scatter points (or block) on an object.

 

Moshe

 

 

Message 3 of 18
bemmer7MZ3G
in reply to: Moshe-A

Could you link the one that you edited? I went through and changed them as you said and it did not work. For me it is only putting one point and is not finding any intersections.
Message 4 of 18
Sea-Haven
in reply to: bemmer7MZ3G

I had a go at task changed a few things to my style, found a problem with entmake line so changed to command for moment.

 

 

(defun c:NodeDim (/ bline poly interval pt1 pt2 len dist node-pt perp-line int-pt intersect-obj intersection-node )
  
  (vl-load-com)

(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)

  ;; Select the base line
  (setq bline (car (entsel "\nSelect the base line: ")))
  (if (not bline)
    (progn
      (prompt "\nNo line selected. Exiting...")
      (exit)
    )
  )
  (if (/= (cdr (assoc 0 (entget bline))) "LINE")
    (progn
      (prompt "\nSelected object is not a line. Exiting...")
      (exit)
    )
  )
 (setq bobj (vlax-ename->vla-object bline))
  ;; Select the polyline to dimension to

  (setq poly (car (entsel "\nSelect the polyline to dimension to: ")))
  (if (not poly)
    (progn
      (prompt "\nNo polyline selected. Exiting...")
      (exit)
    )
  )
  (if (/= (cdr (assoc 0 (entget poly))) "LWPOLYLINE")
    (progn
      (prompt "\nSelected object is not a polyline. Exiting...")
      (exit)
    )
  )
  
  ;; Get the distance interval
  (setq interval (getdist "\nEnter the distance interval: "))

  (if (not interval)
    (progn
      (prompt "\nInvalid distance interval. Exiting...")
      (exit)
    )
  )
  
  ;; Extract the start and end points of the base line
(setq pt1 (cdr (assoc 10 (entget bline))))
(setq pt2 (cdr (assoc 11 (entget bline))))
(setq ang (angle '(0. 0. 0.)
   (vlax-curve-getfirstderiv
     (vlax-ename->vla-object bline)
     (vlax-curve-getparamatpoint
       (vlax-ename->vla-object bline)
       (mapcar '* (mapcar '+ pt1 pt2) '(0.5 0.5))
     )
   )
   )
)

  ;; Calculate the length of the baseline
  (setq len (distance pt1 pt2))
  
  ;; Initialize distance
  (setq dist 0)
  
  (setvar 'clayer "TEMP")
  ;; Loop through the line and place nodes
  (while (<= dist len)
    ;; Calculate the node position along the baseline
    (setq node-pt (vlax-curve-getpointatdist bobj dist))
	(setq dist (+ dist interval))
   
    ;; Place a point (node) at the calculated position
    (entmake (list (cons 0 "POINT") (cons 10 node-pt)))
    
    ;; Draw a 12" perpendicular line centered on the node

  (command "line" (polar node-pt (+ (/ pi 2.) ang) 6.)(polar node-pt (- ang (/ pi 2.)) 6.) "")
  (setq perp-line (vlax-ename->vla-object (entlast)))
    
    ;; Get the polyline object from the user selection (use polyline selected initially)
    (setq intersect-obj (vlax-ename->vla-object poly))
    
    ;; Use the "IntersectWith" method to find intersection between the perpendicular line and the polyline
    (setq int-pt (vlax-invoke  perp-line 'IntersectWith intersect-obj acExtendNone))

    ; remove dummy line
    (vla-delete perp-line)

    ;; If an intersection is found, create a node at the intersection
    (if (/= int-pt nil)
      (progn
        ;; Create a node at the intersection point
        (setq intersection-node (entmake (list (cons 0 "POINT") (cons 10 int-pt))))
        
        ;; Create a dimension between the baseline node and the intersection node
        (command "DIM" "align" node-pt int-pt int-pt "" "exit")
      )
      (prompt "\nNo intersection found for this node.")
    )
    
    ;; Increment the distance for the next node
    (setq dist (+ dist interval))
  )
  
  (prompt "\nOperation completed successfully.")
  (setvar 'osmode oldsnap)
  (princ)
)
(c:nodedim)

 

Message 5 of 18
bemmer7MZ3G
in reply to: Sea-Haven

This worked great, thank you! One question I did have is how would I edit this to delete the int-pt and node-pt after the dimension is made? I have just tried a couple ways, but I think my syntax is incorrect.

Message 6 of 18
Sea-Haven
in reply to: bemmer7MZ3G

Just remove the 

 

;; Place a point (node) at the calculated position
    (entmake (list (cons 0 "POINT") (cons 10 node-pt)))

;; Create a node at the intersection point
        (setq intersection-node (entmake (list (cons 0 "POINT") (cons 10 int-pt))))

 

Message 7 of 18
bemmer7MZ3G
in reply to: bemmer7MZ3G

This has been working for me, I was trying to edit it to restore the osnap mode, clayer, and dimstyle if the function is cancelled out but have not quite been able to figure that out yet. I have linked what I have attempted.

Message 8 of 18
ВeekeeCZ
in reply to: bemmer7MZ3G

Didn't run it. See yourself.

 

7:  (if (and msg (wcmatch msg "*cancel*,*break*")) ;; missing "

13:  (command-s "DIMSTYLE" "r" "AGI Fab Dims") ;; in the error must be '-s  command

26:  (unwind-protect ; not sure about this?

86:      );; missing )

Message 9 of 18
bemmer7MZ3G
in reply to: ВeekeeCZ

This worked great! I am now trying to edit it to select a block instead of a polyline, because that is actually how we receive our information. When I run the program now, it says it cannot find an intersection and I suspect I am treating the blockObj incorrectly in VL

Message 10 of 18
ВeekeeCZ
in reply to: bemmer7MZ3G

That won't be so easy. The intersect method treats the inserts just as a rectangular outline.

Message 11 of 18
bemmer7MZ3G
in reply to: ВeekeeCZ

Okay, what would be the best method of going about this?

Message 12 of 18
ВeekeeCZ
in reply to: bemmer7MZ3G

I am not sure whether it is the best, but it is simple... Make a copy the block and explode it, select the previous and check the inters against the selection set.

Message 13 of 18
bemmer7MZ3G
in reply to: ВeekeeCZ

I have another idea. I have a second code that I was writing and might be able to modify to do this, I am just not well versed enough to accomplish what I am thinking. If it reads a block as a rectangle, is there someway to save that area as a bounding box and then explode the block, then use the bounding box to select everything to use in pedit and then I can use it again to group at the end of the program? I have attached the other code, but most of it can be ignored.

Message 14 of 18
ВeekeeCZ
in reply to: bemmer7MZ3G

Well, that's basically what I said. If you make a copy of the block first and explode the copy, you don't need to restore it, right? The only difference is that you want to join them... good, but rather use the built-in JOIN. 

 

Make a block with 4 lines making a rectangle and try this piece of code... it makes a polyline on top of the block.

(progn (command "copy" pause "" "" "" "_explode" "_l") (initcommandversion) (command "_join" "_p" ""))

 

btw what acad version you have?

 

Message 15 of 18
bemmer7MZ3G
in reply to: ВeekeeCZ

I have autocad 2025. Some of our 3d scans are quite complicated as they are building faces. Will this always work to draw lines over it or does it need to be simple?

Message 16 of 18
ВeekeeCZ
in reply to: bemmer7MZ3G

Yes. Try a more complex block of yours, explode it, use JOIN, and select P as the previous selection. If this somehow joins most of it and significantly reduces the number of entities, that's good.

 

As you have 2025, you need to have this bug in mind...

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/autocad-2025-entnext-entlast-bug/m-p...

Message 17 of 18
Sea-Haven
in reply to: bemmer7MZ3G

One of the things you can do with lisp is to explode an object do something with it like work out all the points and save in a list then you UNDO back to a certain point this will un-explode the object selected, but all the points are saved, look at the "Undo" "M" function, explode do something, then "UNDO" "B".

 

 

Message 18 of 18
ВeekeeCZ
in reply to: bemmer7MZ3G

Possible implementation of the idea described above.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report