Modifying Auto Dimensioning of Polylines LISP code for dimensioning arc segment with arc length dimension instead of 3 point angular dimension & for user defined offset distance multiplication factor.

Modifying Auto Dimensioning of Polylines LISP code for dimensioning arc segment with arc length dimension instead of 3 point angular dimension & for user defined offset distance multiplication factor.

pankaj
Contributor Contributor
2,723 Views
14 Replies
Message 1 of 15

Modifying Auto Dimensioning of Polylines LISP code for dimensioning arc segment with arc length dimension instead of 3 point angular dimension & for user defined offset distance multiplication factor.

pankaj
Contributor
Contributor

Hello All,
Happy New year all. I am Pankaj.
Thanks to Mr. @Kent1Cooper  for the following source code.

Please help me in modifying this below Auto dimension LISP code for Polyline with the following needs,

  1. I have noticed that this LISP program is made for arc segment dimensioned as 3 Point Angular Dimension. But i need Arc Length Dimension instead of 3 Point Angular Dimension.
  2. The height of the dimension from the polyline is maintained as 1.5 times of the text height of the dimension style. I want this code to prompt user for defining the multiplication factor instead of 1.5 as a standard value. so user defined  value multiplied by the text height shall be the final distance from the polyline to the dimension line.

 

;; DimPoly.lsp [command names: DPI = Dimension Polyline(s) Inside, DPO = Outside]
;; To dimension the lengths of all segments of selected Polylines on the Inboard or
;; Outboard side. For self-intersecting or open Polyline without a clear "inside" and
;; "outside," will determine a side -- if not as desired, undo and run other command.
;; Dimensions along arc segments will be angular Dimensions, showing length of arc
;; as text override, not included angle native to angular Dimensions. They will not
;; update if Polyline is stretched, as those along line segments will; redo DPI/DPO.
;; Uses current Dimension and Units settings; dimension line location distance from
;; Polyline segment = 1.5 x dimension text height for stacked fractions to clear [see
;; commentary at setting of dtxt variable re: stacked fractions].
;; Accepts LW and 2D "heavy" Polylines, but not 3D Polylines or meshes. Rejects any
;; on locked Layers, because of Offset used to determine inside/outside.
;; Kent Cooper, last edited 18 May 2016

(vl-load-com)

(defun DP (side / *error* doc svnames svvals styht dpss n pl cw inc pt1 pt3 pt2 ang1 ang2 dtxt pt4)

(defun *error* (errmsg)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
(princ (strcat "\nError: " errmsg))
); if
(mapcar 'setvar svnames svvals); reset System Variables
(vla-endundomark doc)
(princ)
); defun -- *error*

(vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
(setq ; System Variable saving/resetting without separate variables for each:
svnames '(osmode cmdecho blipmode clayer)
svvals (mapcar 'getvar svnames)
); setq
(mapcar 'setvar svnames '(0 0)); turn off Osnap, command echoing
(command "_.layer" "_make" "A-ANNO-DIMS" "_color" 2 "" "");; <---EDIT Layer name/color as desired
(setq styht (cdr (assoc 40 (tblsearch "style" (getvar 'dimtxsty))))); height of text style in current dimension style
(if (= styht 0.0) (setq styht (* (getvar 'dimtxt) (getvar 'dimscale)))); if above is non-fixed-height

(prompt (strcat "\nTo Dimension Polyline(s) on the " side "side,"))
(if (setq dpss (ssget "_:L" '((0 . "*POLYLINE"))))
(progn ; then [can omit this if you never use blips; also two other lines below]
(setvar 'blipmode 0); [omit if you never use blips and omitted line above]
(repeat (setq n (sslength dpss)); step through selection set
(setq pl (ssname dpss (setq n (1- n))))
(if (= (logand (cdr (assoc 70 (entget pl))) 88) 0)
;; not 3D or mesh [88 = 8 (3D) + 16 (polygon mesh) + 64 (polyface mesh)]
(progn ; then
(setq pl (vlax-ename->vla-object pl))
(vla-offset pl styht); temporary
(setq cw (< (vla-get-area (vlax-ename->vla-object (entlast))) (vla-get-area pl)))
;; clockwise for closed or clearly inside/outside open; may not give
;; desired result for open without obvious inside/outside
(entdel (entlast))
(repeat (setq inc (fix (vlax-curve-getEndParam pl))); segments
(setq
pt1 (vlax-curve-getPointAtParam pl inc)
pt3 (vlax-curve-getPointAtParam pl (1- inc))
); setq
(if (not (equal pt1 pt3 1e-8)); not coincident vertices
(progn ; then -- proceed to dimension segment
(setq
pt2 (vlax-curve-getPointAtParam pl (- inc 0.5)); segment midpoint
ang1 (angle pt1 pt2)
ang2 (angle pt2 pt3)
); setq
(if
(or ; line segment?
(equal ang1 ang2 1e-8); any non-0 direction or both reading as 0 or 2 pi
(equal (abs (- ang2 ang1)) (* pi 2) 1e-8); 0-degree with one reading as 2 pi +/-
); or
(command "_.dimaligned" pt1 pt3); then [leaves at dimension line location prompt]
(progn ; else [arc segment]
(setq dtxt
(rtos
(abs ; length along arc segment
(- (vlax-curve-getDistAtParam pl inc) (vlax-curve-getDistAtParam pl (1- inc)))
); abs
;; [include mode/precision here if current dimension style's settings not desired]
); rtos
); setq
(if (wcmatch dtxt "*/*"); includes fraction?
;; can omit this entire (if) function if you don't use stacked fractions
(setq dtxt ; stack it
(strcat
"\\A1;"
(vl-string-subst ";}\"" "\""
; (vl-string-subst "#" "/"
;; remove ; from beginning of above line and its closing parenthesis line
;; below to make diagonal stack [makes horizontal-line stack without]
(vl-string-subst "{\\H0.875x;\\S" " " dtxt)
;; change 0.875 ratio to agree with Dimension Style's setting
; ); -subst
); -subst
); strcat & dtxt
); setq
); if
(command
"_.dimangular" ""
(inters ; arc center
(setq pt4 (mapcar '/ (mapcar '+ pt1 pt2) '(2 2 2)))
(polar pt4 (+ (angle pt1 pt2) (/ pi 2)) 1)
(setq pt4 (mapcar '/ (mapcar '+ pt2 pt3) '(2 2 2)))
(polar pt4 (+ (angle pt2 pt3) (/ pi 2)) 1)
nil
); inters
pt1 pt3
"_text" dtxt
); command [leaves at dimension line location prompt]
); progn
); if
(command ; complete Dimension: dimension line location
(polar
pt2
(apply ; angle
(if (or (and cw (= side "in")) (and (not cw) (= side "out"))) '- '+)
(list
(angle '(0 0 0) (vlax-curve-getFirstDeriv pl (- inc 0.5)))
(/ pi 2)
); list
); apply
(* styht 1.5); distance
;; [If you don't use stacked fractions, consider using styht without multiplier]
); polar
); command
); progn
); if [not coincident]
(setq inc (1- inc))
); repeat [segments]
); progn -- then [LW/2D]
); if
); repeat [Polylines]
); progn -- then [valid selection]; [omit if you never use blips and omitted 2 lines above]
(prompt "\nNo Polyline(s) on unlocked Layer(s) selected."); else
); if

(mapcar 'setvar svnames svvals); reset System Variables
(vla-endundomark doc)
(princ)
); defun -- DP

(defun C:DPI () (DP "in")); = Dimension Polyline Inside
(defun C:DPO () (DP "out")); = Dimension Polyline Outside

(prompt "\nType DPI to Dimension Polyline(s) on the Inside, DPO to do so on the Outside.")

 



Thanks and cheers for you help in advance.
Regards,
Pankaj

0 Likes
Accepted solutions (3)
2,724 Views
14 Replies
Replies (14)
Message 2 of 15

Kent1Cooper
Consultant
Consultant

@pankaj wrote:

.... this LISP program is made for arc segment dimensioned as 3 Point Angular Dimension. But i need Arc Length Dimension instead of 3 Point Angular Dimension. ....


Just so you know, when this was first developed the DIMARC command did not yet exist.  That's why it uses an Angular Dimension with text override.  I may take a look at updating it, and at asking the User for the offset distance [meanwhile, you can follow the comments to change that if you have a regular need different from what it uses], later today.

Kent Cooper, AIA
0 Likes
Message 3 of 15

komondormrex
Mentor
Mentor
Accepted solution

hey Pankaj,

check this other one with arc length dimensions incorporated.

dimize pline 

0 Likes
Message 4 of 15

komondormrex
Mentor
Mentor

dimarc was introduced in autocad 2006, that is almost 18 yrs ago. is that very program that old?

0 Likes
Message 5 of 15

Kent1Cooper
Consultant
Consultant

@komondormrex wrote:

dimarc was introduced in autocad 2006, that is almost 18 yrs ago. is that very program that old?


Originally, yes.  There have been updates, particularly several variations >here<, so last-edited dates are more recent than 2006, but I didn't adjust that part of it -- the updates were about other aspects.  But I'll put the new one there, too.

Kent Cooper, AIA
0 Likes
Message 6 of 15

Kent1Cooper
Consultant
Consultant
Accepted solution

Try the attached.  See the comments at the top [in general, and also for an explanation of the different file name].

Kent Cooper, AIA
0 Likes
Message 7 of 15

pankaj
Contributor
Contributor
Thanks Mr. Kent Cooper for your valuable time and swiftly reply.
This AutoLISP works very well and clearly added advantages to my most of the need & requirement.
0 Likes
Message 8 of 15

pankaj
Contributor
Contributor
Thanks Mr. Komondormrex for your Awesome code which is working really cool.

Initially i have searched a lot before posting my need but i didn't get your pinned post.
May be relative keywords didn't match i think so.

You are really a great coder thanks a lot for your contribution.
0 Likes
Message 9 of 15

pankaj
Contributor
Contributor

@Kent1Cooper 
@komondormrex 
Thanks a lot for your Replies which works totally great for my need and satisfies most of my needs.

Actually i have one more request to your respective codes,
I know i should have mentioned earlier, which would have been a easy one time modification process but now only i have noticed that aligned dimension objects gets executed in both of your codes which arises my new requirement so i am requesting you.

I need user to be prompted for type of dimension needed to be drafted
        1.Rotated Dimension
        2.Aligned Dimension
And as per the user requirement the Linear and Aligned Dimension gets executed for the polyline(Line segments) accordingly and arc length segments remains same as Arc Length Dimension.

Thanks & Regards,
Pankaj.

0 Likes
Message 10 of 15

Kent1Cooper
Consultant
Consultant

@pankaj wrote:

.... I need user to be prompted for type of dimension needed to be drafted
        1.Rotated Dimension
        2.Aligned Dimension
....


Can you illustrate what you want from the Rotated option?  Each Dimension Rotated at the angle of the segment it measures?  [If so, why, since the result is the same as Aligned?]  The difference is considerable if you need to change the path by Stretching:

DimAliRot.gif

The Rotated one will no longer show the actual length of what it measures.

Or all Rotated at the same angle?

Kent1Cooper_0-1704981278535.png

And if that's what you mean, the inside version could be really weird, and either inside or outside, the dimension-line positioning would be a real challenge to figure out how to automate, if it's even possible.

Or something else?

Kent Cooper, AIA
0 Likes
Message 11 of 15

komondormrex
Mentor
Mentor

i guess that the case is that moving grips of extension lines in aligned dimension will rotate align dimension and change its offset, which will not occur in rotated dimension.

0 Likes
Message 12 of 15

Kent1Cooper
Consultant
Consultant

@komondormrex wrote:

i guess that the case is that moving grips of extension lines in aligned dimension will rotate align dimension and change its offset, which will not occur in rotated dimension.


Changing the offset occurs when the first definition point is Stretched, but not the second.  Here, DPO has Dimensioned the red Polyline in the direction that those Dimensions that are being Stretched have their first definition point toward the right:

DimAliStr.gif

The rightward one has its first definition point left alone but its second Stretched, so its offset remains.  The leftward one has its first definition point Stretched, and its offset is affected, somewhat like what happens with DIMARC Dimensions.  I don't know whether that can be prevented or compensated for.

But with a Rotated Dimension, yes, the dimension-line location doesn't change with Stretching, but that is meaningless in terms off offset distance unless the Stretching is only in the direction of the angle of its segment [see my previous Reply -- what is the "offset distance" when the dimension line is not parallel to the dimensioned object?].  I would think it cannot be assumed that Stretching would always and only be in the direction of an edge, and in a Polyline, it cannot be only in the directions of two adjacent edges at the same time.

Can you post a drawing showing before and after using Rotated Dimensions?

Kent Cooper, AIA
0 Likes
Message 13 of 15

pankaj
Contributor
Contributor

Hello,
@Kent1Cooper & @komondormrex 
Thanks Again For your Valuable time and Support. It means a lot to me.

Please do Find the Attached Image and the same content drawing file of my needs and what i have asked for in this Forum for your reference.
pankaj_0-1705044171239.png


The above AutoDim Needs is for representing the Rebar Lengths for the bar bending and scheduling purpose.
Some times the angle will be locked but length will be changing with respect this Rotated Dimension and Aligned Dimensions are used as per the need.

For the UCS world Condition for the following angles "0d, 90d, 180d, 270d" Rotated Dim is used by me and rest all angles follows Aligned Dimension.
For other UCS conditions for the polyline as per the need it will be decided by me for Rotated Dimension or Angular Dimension.
I hope i have been clear with my requirements and request in this Forum.

Thanks & Cheers.
Pankaj
    

0 Likes
Message 14 of 15

pankaj
Contributor
Contributor

Thanks for your support.
@Kent1Cooper 
@komondormrex 
Got the need and met my requirements As great as possible.

0 Likes
Message 15 of 15

komondormrex
Mentor
Mentor
Accepted solution

@pankaj 

added selecting aligned/rotated linear dimension option 

;**************************************************************************************************************************************************************************************

;	komondormrex, feb 2024

;**************************************************************************************************************************************************************************************

(defun c:dimize_pline (/ command_terminated dim_offset linear_dimensions pline_object next_param param_list bulge_list segment_list segment_start segment_end segment_middle
						 segment_bulge dim_object center_point
					  )

	;**********************************************************************************************************************************************************************************

	(defun get_prompted_value (initget_value get_function prompt_string var command_terminated / default_string var_saved)
		(if (/= 3 (getvar 'dynmode)) (setvar 'dynmode 3))
		(if (null command_terminated)
			(progn
				(setq var_saved (read (strcat (vl-symbol-name var) "_saved")))
				(cond
					(
						(null (vl-symbol-value var_saved))
							(setq default_string "")
					)
					(
						(= 'str (type (vl-symbol-value var_saved)))
							(setq default_string (vl-symbol-value var_saved))
					)
					(
						t
							(setq default_string (rtos (vl-symbol-value var_saved)))
					)
				)
				(initget initget_value)
	 			(set var (vl-catch-all-apply get_function (list (strcat "\n" prompt_string " <" default_string ">: "))))
	 			(cond
	 				(
						(or
							(null (vl-symbol-value var))
							(= "" (vl-symbol-value var))
						)
	 						(set var (vl-symbol-value var_saved))
	 				)
	 				(
	 					(vl-catch-all-error-p (vl-symbol-value var))
	 						(setq command_terminated t)
	 				)
	 				(
	 					t
	 						(set var_saved (vl-symbol-value var))
	 				)
	 			)
			)
		)
	 	command_terminated
	)

	;**********************************************************************************************************************************************************************************

	(defun arc_segment_center (bulge start_point end_point)
		(polar (polar start_point
					  (angle start_point end_point)
					  (* 0.5 (distance start_point end_point))
			   )
			   (- (angle start_point end_point) (* 0.5 pi))
			   (/ (* 0.5 (distance start_point end_point))
			   	  (/ (sin (- pi (* 2 (atan bulge))))
				  	 (cos (- pi (* 2 (atan bulge))))
				  )
			   )
		)
	)

	;**********************************************************************************************************************************************************************************

	(defun find_pline_rotation (segment_list pline_object / angle_list)
		(defun diff_angle (angle_1 angle_2)
		  	(setq angle_1 (if (> angle_2 (+ pi angle_1)) (+ (* pi 2) angle_1) angle_1))
		  	(setq angle_2 (if (> angle_1 (+ pi angle_2)) (+ (* pi 2) angle_2) angle_2))
		  	(- angle_2 angle_1)
		)
		(setq angle_list (mapcar '(lambda (segment) (angle (vlax-curve-getpointatparam pline_object (car segment))
		  												   (vlax-curve-getpointatparam pline_object (cadr segment))
													)
								  )
				 	  			  segment_list
			 		   	  )
		)
		(if (> (apply '+ (mapcar '(lambda (angle_1 angle_2) (diff_angle angle_1 angle_2)) angle_list (cdr angle_list))) 0) t nil)
	)

	;**********************************************************************************************************************************************************************************

	(if (not (minusp (vlax-get (vla-get-activelayer (vla-get-activedocument (vlax-get-acad-object))) 'lock)))
			(progn
				(vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
				(if (null dim_offset_saved) (setq dim_offset_saved 10))
				(if (null linear_dimensions_saved) (setq linear_dimensions_saved "Aligned"))
				(and
				 	(null (get_prompted_value 0 'getdist "Dimension offset:" 'dim_offset command_terminated))
				 	(null (get_prompted_value "Aligned Rotated" 'getkword "Linear dimensions [Aligned/Rotated]" 'linear_dimensions command_terminated))
					(repeat (sslength (setq ename_index -1
											ignore_empty_sset (while (null (setq pline_sset (vl-catch-all-apply 'ssget (list '((0 . "lwpolyline")))))))
											pline_sset (cond
																	(
																		(vl-catch-all-error-p pline_sset)
																			(princ "\nCommand cancelled")
																			(ssadd)
																	)
																	(
																		t
																			pline_sset
																	)
													  		)
									   )
							)
							(setq pline_object (vlax-ename->vla-object (ssname pline_sset (setq ename_index (1+ ename_index))))
								  next_param -1
								  param_list nil
								  bulge_list nil
							)
							(repeat (fix (vlax-curve-getendparam pline_object))
								(setq param_list (append param_list (list (setq next_param (1+ next_param))))
									  bulge_list (append bulge_list (list (vla-getbulge pline_object next_param)))
								)
							)
							(setq segment_list (mapcar '(lambda (param next_param bulge) (list param next_param bulge))
														param_list
														(append (cdr param_list) (list (1+ (last param_list))))
														bulge_list
												)
							)
							(if (find_pline_rotation segment_list pline_object) (setq modify_angle '-) (setq modify_angle '+))
							(foreach segment segment_list
								(setq segment_start (vlax-curve-getpointatparam pline_object (car segment))
									  segment_end (vlax-curve-getpointatparam pline_object (cadr segment))
									  segment_middle (vlax-curve-getpointatparam pline_object (* 0.5 (+ (car segment)(cadr segment))))
									  segment_bulge (last segment)
								)
								(cond
									(
										(zerop segment_bulge)
											(if (= "Rotated" linear_dimensions)
													(setq dim_object (vla-adddimrotated (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
																   						(vlax-3d-point segment_start)
																   						(vlax-3d-point segment_end)
																   						(vlax-3d-point (polar segment_middle
																											  ((eval modify_angle) (angle segment_start segment_end) (* 0.5 pi))
																											  dim_offset
																									   )
																						)
																						(angle segment_start segment_end)
																 	)
													)
													(setq dim_object (vla-adddimaligned (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
																   						(vlax-3d-point segment_start)
																   						(vlax-3d-point segment_end)
																   						(vlax-3d-point (polar segment_middle
																											  ((eval modify_angle) (angle segment_start segment_end) (* 0.5 pi))
																											  dim_offset
																									   )
																						)
																 	)
													)
											)
									)
									(
										t
											(setq center_point (arc_segment_center segment_bulge segment_start segment_end))
											(setq dim_object (vla-adddimarc (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
																 			(vlax-3d-point center_point)
																 			(vlax-3d-point segment_start)
																 			(vlax-3d-point segment_end)
																			(vlax-3d-point (polar segment_middle ((eval modify_angle) (angle segment_start segment_end) (* 0.5 pi)) dim_offset))
															 )
											)
									)
								)
							)
					)
				)
			(vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
		)
		(alert "       Active layer is locked")
	)
	(princ)
)

;**************************************************************************************************************************************************************************************
0 Likes