Using the Trim Command

Using the Trim Command

Abby_Baratta
Enthusiast Enthusiast
2,231 Views
17 Replies
Message 1 of 18

Using the Trim Command

Abby_Baratta
Enthusiast
Enthusiast

Hello,

 

I've recently been trying to work with an AutoLISP routine that was written in 1997 and I've run into a few problems with the TRIM command. I haven't worked much with trim commands in general, so I've been doing my best to piece together what it's trying to do. 

 

So I know that when this code was originally written, you would give the TRIM command some reference lines and then a point so that it could trim the desired section of the line. When you type TRIM into the command line now, however, I see that you're able to hover over a section of a line and it will assume what the section of line that you're looking to trim is. 

 

In my case, I'm looking to trim off the top section of a circle, as shown below:

 

Abby_Baratta_0-1709062426590.png

Abby_Baratta_1-1709062551183.png

 

The image on top is what I'm currently working with and the image on the bottom is what I'm looking to get to (ignoring all the added centerlines, angles, and pass lanes of course).

 

As of right now, the code that is written into the program is:

 

   (command "trim" NOZL "" "" (polar BASEPT3 ( + LNOZANG (* 0.5 pi)) (* 0.5 TSTDIA)) "" "")
  (setq TRIMMER (ssadd (entlast)))

 

In this case, the NOZL selection set is referring to the 3/4 of a rectangle that is sitting on top of the circle. I've verified that the polar command that is spitting out a reference point is doing so correctly, with the point being at the very top of the circle, directly between the legs of the NOZL selection set. 

 

I've tried adding (initcommandversion) before the line, as well as using "_.TRIM" instead of what I've currently got, but it still won't get rid of that section of the circle. 

 

Any help or insight into how the TRIM command works would be greatly appreciated!

0 Likes
Accepted solutions (2)
2,232 Views
17 Replies
Replies (17)
Message 2 of 18

Abby_Baratta
Enthusiast
Enthusiast

This seemed to get the code to not throw an error and stop, but it didn't actually remove the portion of the circle:

 

 

(setq nozlpt (polar BASEPT3 ( + LNOZANG (* 0.5 pi)) (* 0.5 TSTDIA)))
(initcommandversion)
(command "_.trim" nozlpt "")

 

0 Likes
Message 3 of 18

Sea-Haven
Mentor
Mentor
Accepted solution

Not sure why you need a shortcut or are you drawing entire object using a lisp ? If so post all the code.

 

TRIM, pick vert line 1, pick vert line 2, Enter, pick circle, Enter, all done ??

0 Likes
Message 4 of 18

CodeDing
Advisor
Advisor

@Abby_Baratta wrote:

This seemed to get the code to not throw an error and stop


Errors are actually important! They help us potentially understand where the code went wrong and in what way. You should include them in any post where something is going wrong.

 


@Abby_Baratta wrote:

...but it didn't actually remove the portion of the circle:


Sometimes your object snaps can cause some chaos.. try updating to this code:

(i added "non" to temporarily remove snaps when you select your trim point, and also removed (initcommandversion) since there is no dialog version of trim that I am aware of)

(setq nozlpt (polar BASEPT3 ( + LNOZANG (* 0.5 pi)) (* 0.5 TSTDIA)))
(command "_.trim" "non" nozlpt "")

 

...and if that's no help, then yes we will need more information to understand your code & its purpose better.

 

Best,

0 Likes
Message 5 of 18

ВeekeeCZ
Consultant
Consultant

Wouldn't be more convenient just BREAK the circle?

 

(defun c:breakcircle ( / e p r)
  (if (and (setq e (car (entsel "\nSelect circle: ")))
	   (setq p (cdr (assoc 10 (entget e))))
	   (setq r (cdr (assoc 40 (entget e))))
	   )
    (command "_.break" e
	     "_non" (polar p (- (* 0.5 pi) (cvunit 30 "degree" "radian")) r)
	     "_non" (polar p (+ (* 0.5 pi) (cvunit 30 "degree" "radian")) r)))
  (princ)
  )

 

0 Likes
Message 6 of 18

Kent1Cooper
Consultant
Consultant

@Abby_Baratta wrote:

... it didn't actually remove the portion of the circle: ....


That would be the result if the vertical Lines [or end Polyline segments, or whatever they are] fall short of actually touching the Circle.  Could that be the cause?

Kent Cooper, AIA
0 Likes
Message 7 of 18

Abby_Baratta
Enthusiast
Enthusiast

That did not end up working. I had EXPERT set to 5, so I changed it to 0 and it still didn't show any errors, so I'm not sure why it's not stopping, but also not trimming anything. 

 

This portion of the code is designed to draw the circle, draw the nozzle on top of the circle, and trim out the arc underneath the nozzle. Some of the variables that we define earlier include:

 

BASEPT3 - point designated to be the center of the circle

TSTDIA - length designated to be the diameter of the circle

LNOZANG - angle of the nozzle

LNOZHT - height of the nozzle

NOZRAD - radius of the nozzle

 

And this is the whole portion of code that draws and trims the circle and nozzle:

 

(if (or COREONLY (= DWGTYP "CORE"))(progn
 ;
 (if (> USIZE 2.00)(progn
  (command "circle" BASEPT3 "D" TSTDIA)
  (setq TRIMMER (ssadd (entlast)))
 ))
 ; 
 (if (= USIZE 2.00)(progn
  (setq p1 (polar BASEPT3 UP (* 0.5 TSTDIA)))
  (setq p1 (polar p1 LFT (* 0.5 TSTDIA)))
  (setq p2 (polar p1 RGT TSTDIA))
  (setq p3 (polar p2 DWN TSTDIA))
  (setq p4 (polar p1 DWN TSTDIA))
  ;
  (command "pline" p1 p2 p3 p4 "C")
  (command "fillet" "p" (entlast))
  (setq TRIMMER (ssadd (entlast)))
  ;
 ))

(setq A (+ LNOZANG (* 0.5 pi)))
(setq B (+ LNOZANG pi))
;
(setq P1 (polar BASEPT3 A LNOZHT))
(setq P2 (polar P1 B LNOZRAD))
(setq P3 (polar P1 (+ B pi) LNOZRAD))
(setq P4 (polar P2 (+ A pi) 0.1))
(setq P5 (polar P3 (+ A pi) 0.1))
(setq LNZTOP P3)
(if (= LNOZANG SC_BACK)(setq LNZTOP (polar P1 UP LNOZRAD)))
(if (= LNOZANG SC_DWN)(setq LNZTOP (polar P1 RGT LNOZRAD)))
(if (= LNOZANG SC_FRNT)(setq LNZTOP (polar P1 UP LNOZRAD)))
;
(command "pline" P5 P3 P2 P4 "")
(setq NOZL (ssadd (entlast)))
(command "EXTEND" TRIMMER "" P4 P5 "")
(setq NOZL (ssadd (entlast)))
;
(if (= modl/ "SC")(progn
 (if (and (or (= DWGTYP "CORE") COREONLY)(= LNOZANG RNOZANG))(progn
;   (command "trim" NOZL "" "" (polar BASEPT3 ( + LNOZANG (* 0.5 pi)) (* 0.5 TSTDIA)) "" "")

;testing
(setq nozlpt (polar BASEPT3 ( + LNOZANG (* 0.5 pi)) (* 0.5 TSTDIA)))
(initcommandversion)
(command "_.trim"  "non" nozlpt "")

  (setq TRIMMER (ssadd (entlast)))
 ))
))

I have ensured that LNOZANG does in fact equal RNOZANG, so the code is actually going into that if statement. 

 

It still runs all the way through the rest of the drawing process that comes after this point, but it isn't throwing errors for me to look at or trimming.

0 Likes
Message 8 of 18

Kent1Cooper
Consultant
Consultant

Should your pre-code list of variables include LNOZRAD [which is called for in the code but not defined], either instead of or in addition to NOZRAD?

 

We also don't have any information about some other variables [modl/, SC_BACK, SC-DWN, SC-FRNT, DWGTYPE, COREONLY], the last two of which we may be clever enough to figure out how to ignore, nor some others we can probably guess at [LFT, RFT, DWN].

 

We don't know your current Fillet radius, for line 16 -- if it's zero, I don't see the purpose in doing that, but if it's not zero, I don't see anything in the images that could relate to it.

 

Since we can't really test your code without those various other variables, it's hard to picture what's going on, and I'm reluctant to wade in deep enough to figure it all out.  Post a drawing file, with those variable things identified.  I'm still betting on the Circle not actually being touched by what you want to Trim it between [see my previous Reply].

Kent Cooper, AIA
0 Likes
Message 9 of 18

Abby_Baratta
Enthusiast
Enthusiast
Accepted solution

This lead me to my solution - I was not specifying two separate lines to use as boundaries, but rather a selection set that was u-shaped, with the legs of the U intended to be the boundaries. This was how it was working in AutoCAD 2004 with the original code, but AutoCAD 2021 did not appreciate this.

 

The problem with the selection set is that it was formed using an EXTEND command that extended the legs of the U to the edge of the circle, so I had no actual idea of what those points of intersection were. To get around this, I decided that I would just create arbitrary lines for boundaries and then delete afterward.

 

I responded to another reply with the full code that I was working with and there were tons of variables that were defined much earlier in the code, so I went and rewrote this portion of code with arbitrary values so I could test it. The code that I ended up getting to work was:

 

(defun CIRCLE()

(setq pt (list 10 10))
(setq dia 4)
(setq UP (/ pi 2))
(setq RGT 0)
(setq LFT pi)
(setq DWN (/ (* 3 pi) 2))
(command "circle" pt "D" dia)
(setq TRIMMER (ssadd (entlast)))
(setq ang 0)
(setq A (+ ang (* 0.5 pi)))
(setq B (+ ang pi))

(setq P1 (polar pt A 2.5))
(setq P2 (polar P1 B 1))
(setq P3 (polar P1 (+ B pi) 1))
(setq P4 (polar P2 (+ A pi) 0.1))
(setq P5 (polar P3 (+ A pi) 0.1))

(command "pline" P5 P3 P2 P4 "")
(command "EXTEND" TRIMMER "" P4 P5 "")

(setq rpt (list (+ 10 1) 10))
(setq lpt (list (- 10 1) 10))
(command "pline" P5 rpt "")
(setq TEST1 (ssadd (entlast)))
(command "pline" P4 lpt "")
(setq TEST2 (ssadd (entlast)))

(setq nozlpt (polar pt ( + ang (* 0.5 pi)) (* 0.5 dia)))

(command "_.TRIM" TEST2 TEST1 "" nozlpt "")

(command "erase" TEST1 "")
(command "erase" TEST2 "")

)

 

I'm not sure if this is the absolute fastest way to do this, but it works in the desired way.

 

Thank you for the reply - I didn't even think to check and see if the NOZL selection set was what it didn't like!

0 Likes
Message 10 of 18

Abby_Baratta
Enthusiast
Enthusiast

I ended up finding what my issue was - in the original code they were defining NOZL as a U-shaped selection set that was formed using the EXTEND command for the legs of the U. It was using those legs as the boundaries for the trim, but it was being input as one variable, NOZL. AutoCAD did not like this, but I didn't know those intersection points since the EXTEND command didn't need them, so I decided to use arbitrary lines that intersect the circle in the desired place as boundaries and then deleted them after.

 

I posted the code that I found to fix it in another reply - I rewrote it without all the variable names because I knew what each one was, what it did, and why it was there, so I just put in random numbers for testing.

0 Likes
Message 11 of 18

CodeDing
Advisor
Advisor

@Abby_Baratta ,

 

My brain hurts reading your answer 🤕

Isn't the purpose of your TRIM command to remove part of the circle to where the U shape intersects the circle? So it will be (or appear to be) one shape?

 

If you have to create 2 additional lines to trim your circle to (instead of using your U shape lines) then it would sound like the U shape is not adhering to its intended purpose.

 

While I can agree with the concept of "getting something to just work", it seems a bit far-fetched for this routine since we should already have all of the linework necessary to perform our trim command.

0 Likes
Message 12 of 18

Abby_Baratta
Enthusiast
Enthusiast

I agree that the u-shaped selection set should work because it was how it was originally written to work and it's much more seamless. Yes, the intent is to trim out the arc underneath the 'u-shape' nozzle. It is intended to look like one shape, as shown below:

 

Abby_Baratta_0-1709138194131.png

 

When I use the NOZL, it will cut out this shape, but it will give an error that says command: nil and the rest of my code will not run after it. I will attach a version of the code that makes this shape and cuts out the arc using the NOZL selection set that doesn't depend on all those predefined variables, so it should be easier to work with.

 

(defun oldcircle()

(setq pt (list 10 10))
(setq dia 4)
(setq UP (/ pi 2))
(setq RGT 0)
(setq LFT pi)
(setq DWN (/ (* 3 pi) 2))
(command "circle" pt "D" dia)
(setq TRIMMER (ssadd (entlast)))
(setq ang 0)
(setq A (+ ang (* 0.5 pi)))
(setq B (+ ang pi))

(setq P1 (polar pt A 2.5))
(setq P2 (polar P1 B 1))
(setq P3 (polar P1 (+ B pi) 1))
(setq P4 (polar P2 (+ A pi) 0.1))
(setq P5 (polar P3 (+ A pi) 0.1))

(command "pline" P5 P3 P2 P4 "")
(setq NOZL (ssadd (entlast)))
(command "EXTEND" TRIMMER "" P4 P5 "")
(setq NOZL (ssadd (entlast)))

(setq nozlpt (polar pt ( + ang (* 0.5 pi)) (* 0.5 dia)))

(command "_.TRIM" NOZL "" nozlpt "")

)

 I would appreciate any help in getting this to now throw the command: nil because this is much simpler than adding in arbitrary lines, just to delete them.

0 Likes
Message 13 of 18

CodeDing
Advisor
Advisor

@Abby_Baratta ,

 

I re-wrote your circle code which duplicates the shape and you should be able to easily see where variables could be replaced. Hope this helps:

(defun c:MYSHAPE ( / Circle asin LWPoly pt rad slotWidth slotHeight upDir angDeltaLower angDeltaUpper distUpper cir ptLowerLeft ptUpperLeft ptUpperRight ptLowerRight poly ptTrim)
  ;; ----- Helper Function(s) -----
  ;; Creates a circle on current layer
  ;; cen - point, center of circle
  ;; rad - real/int, radius of circle
  ;; returns - ename, of created circle
  (defun Circle (cen rad)
    (entmakex (list (cons 0 "CIRCLE") (cons 10 cen) (cons 40 rad)))
  )
  ;; Computes asin
  ;; y  = real, -1<=y<=1
  ;; returns - real, inverse sin in radians
  (defun asin (y)
    (atan y (sqrt (- 1 (* y y))))
  )
  ;; Creates polyline on current layer
  ;; lst - list, of points for polyline
  ;; returns - ename, of polyline
  (defun LWPoly (lst)
    (entmakex
      (append
         (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline")
               (cons 90 (length lst)) (cons 70 0))
         (mapcar (function (lambda (p) (cons 10 p))) lst)
      );append
    );entmakex
  )
  ;; ----- Begin Work -----
  ;; Set default variables & perform geometry for slot info
  (setq pt '(10 10))
  (setq rad 2.0)
  (setq slotWidth 2.0)
  (setq slotHeight 0.5)
  (setq upDir (* 0.5 pi))
  (setq angDeltaLower (asin (/ (* slotWidth 0.5) rad)))
  (setq angDeltaUpper (atan (/ (* slotWidth 0.5) (+ rad slotHeight))))
  (setq distUpper (sqrt (+ (expt (* 0.5 slotWidth) 2) (expt (+ rad slotHeight) 2))))
  ;; Create initial circle
  (setq cir (Circle pt rad))
  ;; Prepare slot locations
  (setq ptLowerLeft (polar pt (+ upDir angDeltaLower) rad))
  (setq ptUpperLeft (polar pt (+ upDir angDeltaUpper) distUpper))
  (setq ptUpperRight (polar pt (- upDir angDeltaUpper) distUpper))
  (setq ptLowerRight (polar pt (- upDir angDeltaLower) rad))
  ;; Create slot
  (setq poly (LWPoly (list ptLowerLeft ptUpperLeft ptUpperRight ptLowerRight)))
  ;; Prep for Trim
  (setq ptTrim (polar pt upDir rad))
  ;; Perform Trim
  (command "_.TRIM" poly "" "non" ptTrim "")
  ;;Finish up
  (prompt "\nMYSHAPE Complete.")
  (princ)
);defun

 

Best,

0 Likes
Message 14 of 18

Kent1Cooper
Consultant
Consultant

YOU SIMPLY NEED TO TURN OFF RUNNING OBJECT SNAP.  Your code in Message 12 fails for me with running Osnap on, but works with it off.  It would probably fail in slightly different ways depending on which mode(s) you have on, and even possibly the Zoom level.  You should always build turning that off into AutoLisp routines that work with locations in commands in which Osnap can affect things.

Kent Cooper, AIA
0 Likes
Message 15 of 18

Abby_Baratta
Enthusiast
Enthusiast

I tried changing it, but it didn't seem to work and I'm trying to pinpoint why. At the beginning of the code, there is a line that reads

(setvar "OSMODE" 0)

Since the code is very lengthy and goes through many LISP routines to get to this point, I went ahead and copied that line and put it right before the section of code that I posed in Message 12. 

 

When I type OSNAP into the command line and it brings up the dialog box, the 'Object Snap On' box is checked. I even went into the tools>options>AM:Preferences and changed my OSNAP preference to be off, but this box still checks itself. 

 

I am also seeing an invalid window specification when I try and run this code like this:

(setq nozlpt (polar pt ( + ang (* 0.5 pi)) (* 0.5 dia)))

(command "_.TRIM" NOZL "" "non" nozlpt "")

 

But not when I run it like this:

(setq nozlpt (polar pt ( + ang (* 0.5 pi)) (* 0.5 dia)))

(command "_.TRIM" NOZL "" "non" TRIMMER "")

(with the TRIMMER selection set being defined in the code in Message 12)

 

The only problem with the code that doesn't throw the window specification error is that it trims the whole circle except for the arc underneath the nozzle.

0 Likes
Message 16 of 18

Kent1Cooper
Consultant
Consultant

@Abby_Baratta wrote:

....

When I type OSNAP into the command line and it brings up the dialog box, the 'Object Snap On' box is checked. ....


As for that, it doesn't matter whether it's "on" if no modes are in effect -- that's what an OSMODE setting of zero represents.  I don't think it will make any difference, but if you prefer to have no modes selected and to have Osnap "off," set OSMODE to 16384.

Kent Cooper, AIA
0 Likes
Message 17 of 18

Kent1Cooper
Consultant
Consultant

Varioius thoughts....

 

For me, the code in Message 12 does this [with Osmode = 0]:

Kent1Cooper_0-1709146781345.png

I work with Blips turned on, so you can see the points it calculates and uses, including the one where it picked the Circle to Trim it between the sides of the top part.

 

You can also see the locations of P4 & P5 where it picked to Extend.  I wonder whether those might be so close to the corners that the Zoom level could affect what it "sees" in the Extend command.  It may not matter if it's seeing the horizontal segment rather than the vertical end segments, but just in case, does it have the same issues if you Zoom in closer?  Or if you set P4 & P5 to be farther from the top?  [I'm doubtful, since it works for me.]

 

Code lines 22 & 24 in Message 12 are redundant -- you don't need to re-establish that variable after Extending.  And [again, I'm not sure it will make any difference] the NOZL variable doesn't need it put into a selection set, but can simply use the entity name if it's the only entity involved.  Same with TRIMMER in line 10.  You could do just:

(setq NOZL (entlast))

Kent Cooper, AIA
0 Likes
Message 18 of 18

Sea-Haven
Mentor
Mentor

I liked the way the points were worked out so added a front end dcl, added make single pline, added do a rotation on result.

SeaHaven_0-1709169838526.png

; original code by CODEDING FEB 2024
; Multi getvals added make pline and rotation added by AlanH Feb 2024

(defun c:MYSHAPE ( / Circle asin LWPoly pt rad slotWidth slotHeight upDir angDeltaLower angDeltaUpper 
distUpper cir ptLowerLeft ptUpperLeft ptUpperRight ptLowerRight poly ptTrim oldsnap)
  ;; ----- Helper Function(s) -----
  ;; Creates a circle on current layer
  ;; cen - point, center of circle
  ;; rad - real/int, radius of circle
  ;; returns - ename, of created circle
  (defun Circle (cen rad)
    (entmakex (list (cons 0 "CIRCLE") (cons 10 cen) (cons 40 rad)))
  )
  ;; Computes asin
  ;; y  = real, -1<=y<=1
  ;; returns - real, inverse sin in radians
  (defun asin (y)
    (atan y (sqrt (- 1 (* y y))))
  )
  ;; Creates polyline on current layer
  ;; lst - list, of points for polyline
  ;; returns - ename, of polyline
  (defun LWPoly (lst)
    (entmakex
      (append
         (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline")
               (cons 90 (length lst)) (cons 70 0))
         (mapcar (function (lambda (p) (cons 10 p))) lst)
      );append
    );entmakex
  )
  ;; ----- Begin Work -----
  ;; Set default variables & perform geometry for slot info
  (setq oldsnap (getvar 'osmode))
  (setvar 'osmode 0)
  
  (setq pt (getpoint "\n Please pick centre point "))
  
  (if (not AH:getvalsm)(load "Multi Getvals.lsp"))
  (setq ans (AH:getvalsm (list "Enter values " "Radius " 5 4 "2" "Slot Width " 5 4 "2" "Slot Height" 5 4 "0.5" "Angle " 5 4 "0")))
  
  (setq rad (atof (nth 0 ans ))
  slotWidth (atof (nth 1 ans))
  slotHeight (atof (nth 2 ans))
  ang (atof (nth 3 ans))
  )
    
  (setq upDir (* 0.5 pi))
  (setq angDeltaLower (asin (/ (* slotWidth 0.5) rad)))
  (setq angDeltaUpper (atan (/ (* slotWidth 0.5) (+ rad slotHeight))))
  (setq distUpper (sqrt (+ (expt (* 0.5 slotWidth) 2) (expt (+ rad slotHeight) 2))))
  ;; Create initial circle
  (setq cir (Circle pt rad))
  
  ;; Prepare slot locations
  (setq ptLowerLeft (polar pt (+ upDir angDeltaLower) rad))
  (setq ptUpperLeft (polar pt (+ upDir angDeltaUpper) distUpper))
  (setq ptUpperRight (polar pt (- upDir angDeltaUpper) distUpper))
  (setq ptLowerRight (polar pt (- upDir angDeltaLower) rad))
  (command "break" ptLowerRight ptLowerLeft ) ; must do right 1st 
  (setq cir (entlast))
  ;; Create slot
  (setq poly (LWPoly (list ptLowerLeft ptUpperLeft ptUpperRight ptLowerRight)))
  (command "pedit" poly "JOIN" cir "" "")
  (if (= ang 0.0)
    (princ)
    (command "rotate" (entlast) "" pt ang)
  )
  ;;Finish up
  (setvar 'osmode oldsnap)
  (prompt "\nMYSHAPE Complete.")
  (princ)
);defun

SeaHaven_1-1709169974496.png