Author Topic: enames for offset lines  (Read 4262 times)

0 Members and 1 Guest are viewing this topic.

hmspe

  • Bull Frog
  • Posts: 364
enames for offset lines
« on: November 24, 2005, 11:58:35 PM »
I'm working on a routine to trim intersections of lines or other objects.  The steps are (1) select a line, arc, ellipse, etc., (2) offest the selection on both sides, (3) retrieve the offset entities, and (4) pass these entities to the TRIM command as the "trim to" entities.  I can then select any intersecting entities that I want to trim out.  I have it working for all but a special case for ellipses.  If the ellipse is long and narrow there can be a situation where it offset on the inside is actually two splines rather than one, and I can't figure out a way to access both interior splines. I know a bit about "old fashioned" autolisp, but very little about vla/vlax.

Here's work in progress.  Bits and pices borrowed from many places...

Code: [Select]
(defun C:eb ( / )

  (defun initerr ()
    (setq temperr *error*)
    (setq *error* trap)
    (princ)
  )

  (defun trap (errmsg)
    (command)
    (if (not (member errmsg '("Cannot offset that object")))
      (princ (strcat "\nError: " errmsg))
    )
    (setq *error* temperr)
    (princ)
  )

  (defun dxf (1code 1ent) (cdr (assoc 1code 1ent)))

  (defun OffsetDouble (ename dist / vobj enew)
    (setq enew nil)
    (setq vobj (vlax-ename->vla-object ename))
    (if (vlax-method-applicable-p vobj 'Offset)
      (progn
        (setq tmplst nil)
        (vl-catch-all-error-p
          (setq TmpLst (vl-catch-all-apply 'vlax-invoke (list vobj 'Offset dist)))
        )
        (if (= (type tmplst) 'LIST)
          (progn
            (setq enew (entlast))
          ) 
        )
        (setq tmplst nil)
        (vl-catch-all-error-p
          (setq TmpLst (vl-catch-all-apply 'vlax-invoke (list vobj 'Offset (- dist))))
        )
        (if (= (type tmplst) 'LIST)
          (progn
            (if (= enew nil)
              (setq enew (entlast))
              (setq enew (list (entlast) enew))
            )
          ) 
        ) 
      )
    )
    enew
  )

;;  function starts here
 
  (initerr)
  (setvar "cmdecho" 0)
  (command "._undo" "end")
  (command "._undo" "begin")
  (setq offset_dist (* (getvar "dimscale") 0.09375))
  (setq cutline_select (entsel "\nSelect entity to trim around: "))
  (setq cutline_pt (osnap (cadr cutline_select) "near"))
  (setq cutline (entget (car cutline_select)))
  (setq offset_ok (offsetdouble (dxf -1 cutline) offset_dist))
  (print offset_ok)
  (princ)
)


I've also tried using variations of: 

            (setq enew (vlax-vla-object->ename (car tmplst)))

but everything I've tried has returned only one of the two interior splines.

Any help on how to get enames for both splines would be appreciated, as would any other suggestions.


Martin




a

<edit> code tags added by CAB
« Last Edit: November 25, 2005, 08:11:07 AM by CAB »
"Science is the belief in the ignorance of experts." - Richard Feynman

Crank

  • Water Moccasin
  • Posts: 1503
Re: enames for offset lines
« Reply #1 on: November 25, 2005, 12:48:02 PM »
1- You can turn the elipse into a polyline before the offset

2- Before the offset get the last object with (entlast) . The new objects can be found with (entnext)
Vault Professional 2023     +     AEC Collection

Crank

  • Water Moccasin
  • Posts: 1503
Re: enames for offset lines
« Reply #2 on: November 25, 2005, 12:56:58 PM »
Example:
Code: [Select]
(defun collect (e-last / ex ss1)
(setq ex (entnext e-last))
(setq ss1 (ssadd ex (ssadd)))
(setq ex (entnext ex))
(while (/= ex nil)
(setq ss1 (ssadd ex ss1) ex (entnext ex))
)
         ss1
)
« Last Edit: November 25, 2005, 01:06:47 PM by Crank »
Vault Professional 2023     +     AEC Collection

hmspe

  • Bull Frog
  • Posts: 364
Re: enames for offset lines
« Reply #3 on: November 26, 2005, 05:15:52 PM »
In case anyone's interested, here's what I came up with"

Code: [Select]
(defun c:n ( / temperr *error* a1 a2 a3 offset_ok
               offset_dist cutline_select cutline_pt cutline)

 offset_dist cutline_select cutline_pt cutline



  (defun initerr ()
    (setq temperr *error*)
    (setq *error* trap)
    (princ)
  )

  (defun trap (errmsg)
    (command)
    (if (not (member errmsg '("Cannot offset that object")))
      (princ (strcat "\nError: " errmsg))
    )
    (setq *error* temperr)
    (princ)
  )

  (defun dxf (1code 1ent) (cdr (assoc 1code 1ent)))

  (defun MyErrorCheck (eFunction Listof / ErrChk)
                                        ; Use just like (vl-catch-all-apply....
                                        ; Returns nil if an error

    (setq ErrChk (vl-catch-all-apply eFunction Listof))
    (if (vl-catch-all-error-p ErrChk)
      (setq ErrChk nil)
      ErrChk
    )
  ) 

  (defun OffsetDouble (ename dist / enew t0 t1 t2 t3 vobj tmplst)
    (setq enew nil)
    (setq t1 nil)
    (setq t2 nil)
    (setq t3 nil)
    (setq vobj (vlax-ename->vla-object ename))
    (if (vlax-method-applicable-p vobj 'Offset)
      (progn
        (setq t0 (entlast))
        (setq tmplst nil)
        (vl-catch-all-error-p
          (setq tmplst (vl-catch-all-apply 'vlax-invoke (list vobj 'Offset dist)))
        )
        (setq tmplst nil)
        (vl-catch-all-error-p
          (setq tmplst (vl-catch-all-apply 'vlax-invoke (list vobj 'Offset (- dist))))
        )
        (setq t1 (entnext t0))
        (if t1
          (progn
            (setq t2 (entnext t1))
            (if t2
              (setq t3 (entnext t2))
            )
          ) 
        )
        (if (and t1 t2 t3)
          (setq enew (list t1 t2 t3))
          (if (and t1 t2)
            (setq enew (list t1 t2))
            (setq enew t1)
          )
        )
      )
    )
    enew
  )
 
;;  function starts here
  (initerr)
  (setvar "cmdecho" 0)
  (command "._undo" "end")
  (command "._undo" "begin")
  (setq a1 nil)
  (setq a2 nil)
  (setq a3 nil)
  (setq offset_ok nil)
  (setq offset_dist (* (getvar "dimscale") 0.09375))
  (setq cutline_select (entsel "\nSelect entity to trim around: "))
  (setq cutline_pt (osnap (cadr cutline_select) "near"))
  (setq cutline (entget (car cutline_select)))
  (setq offset_ok (offsetdouble (dxf -1 cutline) offset_dist))
  (if offset_ok
    (progn
      (if (= (type offset_ok) 'list)
        (progn
          (setq a1 (car offset_ok))
          (setq a2 (cadr offset_ok))
          (setq a3 (caddr offset_ok))
        )
        (setq a1 offset_ok)
      ) 
      (if (= a2 nil)
        (command "_.trim" a1 "")
        (if (= a3 nil)
          (command "_.trim" a1 a2 "" pause)
          (command "_.trim" a1 a2 a3 "" pause)
        )
      ) 
      (while (> (getvar"cmdactive") 0)
        (command pause)
      )
      (entdel a1)
      (if (/= a2 nil)
        (entdel a2)
      ) 
      (if (/= a3 nil)
        (entdel a3)
      )
    )
  )
  (command "._undo" "end")
  (princ)
)
"Science is the belief in the ignorance of experts." - Richard Feynman

DEVITG

  • Bull Frog
  • Posts: 481
Re: enames for offset lines
« Reply #4 on: November 27, 2005, 04:29:47 PM »
You can use the ENTLAST after doing each offset
Location @ Córdoba Argentina Using ACAD 2019  at Window 10

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: enames for offset lines
« Reply #5 on: November 27, 2005, 05:46:29 PM »
I hope you don't mind, I made some adjustment to your routine.
See how this works for you.

Code: [Select]
;;  Routine to offset an object to both sides and alloe the user to
;;  trim using the new objects as the fence
(defun c:offsettrim (/ dist elast ename ent i newbies obj trim_ent)

  ;;============================================================
  ;; Rune Wold and Michael Puckett - modified
  ;; e.g. usage (setq marker (ALE_LASTENT))
  ;;  Function to get the absolute last entity in the database
  ;;  Returns nil is drawing is completely empty
  (defun ale_lastent (/ entnam outval)
    (and
      (setq outval (entlast)) ; if there is an entity in drawing
      (while (setq entnam (entnext outval))
        (setq outval entnam)
      )
    )
    outval
  )
  ;;============================================================
  ;;  Function to get new items after EntNam in the database
  (defun ale_ss-after (entnam / entnxt selset)
    (cond
      ((not entnam) (ssget "_X")) ; dwg was empty
      ((setq entnxt (entnext entnam)) ; get new items
       (setq selset (ssadd entnxt))
       (while (setq entnxt (entnext entnxt))
         (if (entget entnxt)
           (ssadd entnxt selset)
         )
       )
       selset
      )
    )
  )
  ;;=========================================================


;; o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
;;                   S T A R T   H E R E                       
;; o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o

  (setq dist (* (getvar "dimscale") 0.09375))


  (if (setq ent (entsel "\nSelect entity to trim around: "))
    (if (and (setq obj (vlax-ename->vla-object (car ent)))
             (vlax-method-applicable-p obj 'offset)
        )
      (progn ; start offset
        (command "._undo" "begin")
        (setq elast (ale_lastent)) ; get last entity in database
        (setq newbies (ssadd)) ; create an empty selection set
        (vl-catch-all-apply 'vlax-invoke (list obj 'offset dist))
        (vl-catch-all-apply 'vlax-invoke (list obj 'offset (- dist)))
        (setq newbies (ale_ss-after elast))
        ;;  user trim
        (while (and newbies
                    (setq trim_ent (entsel "\nSelect item to trim.")))
          (command "_.trim" newbies "" trim_ent "")
        ) ; while
        (and newbies ; must test for nil
             (setq i -1)
             (while (setq ename (ssname newbies (setq i (1+ i))))
               (entdel ename)
             )
        )
        (command "._undo" "end")
      )
      (prompt "\nCan not trim with that object.")
    )
    (prompt "\nNothing selected.")
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

hmspe

  • Bull Frog
  • Posts: 364
Re: enames for offset lines
« Reply #6 on: November 28, 2005, 10:40:59 PM »
Let me try this again -- my last reply seems to have gotten lost....

CAB,

Thanks.  Your version is a lot cleaner than mine.  There is one difference in operation:  mine highlights the "trim to" lines but doesn't prompt to select the entities to trim.  Yours does not highlight but does prompt.  Something for me to investigate.

One other anomoly I ran across is with (vlax-method-applicable-p vobj 'Offset).  When I was testing the code under LT2004 with LT-Extender this line errors.  Changing to (vlax-method-applicable-p vobj "offset") works with full Autocad 2004 and LT2004 with LT-Extender. 

Martin
"Science is the belief in the ignorance of experts." - Richard Feynman

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: enames for offset lines
« Reply #7 on: January 02, 2006, 11:28:29 PM »
This is the original version:
Code: [Select]
;
; Marc'Antonio Alessi - http://xoomer.virgilio.it/alessi
; Function: ALE_LastEnt
;
; Version 1.01 - 20/12/2004
;
; Description:
;   get the absolute last entity in the database,
;   for problems in >=r15 in blocks with attrib, and polylines
;
; Arguments: none
;
; Return Values:
;   An entity name;
;   otherwise nil, if there are no entities in the current drawing
;
; Example: (setq marker (ALE_LASTENT))
;
(defun ALE_LastEnt ( / EntNam OutVal)
  (and
    (setq OutVal (entlast))
    (while (setq EntNam (entnext OutVal))
      (setq OutVal EntNam)
    )
  )
  OutVal
)
;
; Marc'Antonio Alessi - http://xoomer.virgilio.it/alessi
; Function: ALE_Ss-After
;
; Version 1.01 - 20/12/2004
; Version 1.02 - 30/09/2005
;
; Description:
;   get a selection set of items after EntNam in the database
;
; Arguments: An entity name
;
; Return Values:
;   A selection set;
;   otherwise nil, if there are no entities after EntNam
;
; Examples:
;   (setq marker (ALE_LASTENT)) ...create new entities...
;   to include reference entity:
;   (command "_.MOVE" (ALE_SS-AFTER marker) marker "" ...)
;   not include reference entity:
;   (command "_.MOVE" (ALE_SS-AFTER marker) "" ...)
;
(defun ALE_Ss-After (EntNam / SelSet)
  (cond
    ( (not EntNam) (ssget "_X") )
    ( (setq EntNam (entnext EntNam))
      (setq SelSet (ssadd EntNam))
      (while (setq EntNam (entnext EntNam))
        (if (entget EntNam) (ssadd EntNam SelSet))
      )
      SelSet
    )
  )
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: enames for offset lines
« Reply #8 on: January 03, 2006, 12:34:38 AM »
Marc'Antonio Alessi
Welcome to the Swamp.
And thanks for sharing the latest version.

I think this is where i got the code posted
http://tinyurl.com/8tbpq

I hope you will stick around and share some of your talent with us.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.