TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: deanby7 on January 27, 2017, 07:56:49 PM

Title: Grread - dynamic sizing/position of circle
Post by: deanby7 on January 27, 2017, 07:56:49 PM
I wonder whether anyone can help with the code below. I'm trying to position a circle on a polyline (simulating osnap 'near') using mouse, and simultaneously being able to resize the circle to 4 four radii options by pressing 1,2, 3 or 4 on the keyboard. The circle moves as expected up and down the polyline and is fixed with a left click. However, when pressing keys 1, 2,3 or 4 the circle only temporarily resizes in the original circle position! The 'entmod' function does not appear to be modifying the entity. I'm missing something simple I think!!
Any ideas/help would be most apreciated.
Title: Re: Grread - dynamic sizing/position of circle
Post by: Lee Mac on January 27, 2017, 08:32:34 PM
Consider that when updating the circle position, you are using the original DXF data, as opposed to the DXF data which may hold a different radius value.

I would personally suggest:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:gg ( / cir ent grr lst rad sel )
  2.     (setq lst
  3.        '(
  4.             (49 . 12.78)
  5.             (50 . 15.78)
  6.             (51 . 18.78)
  7.             (52 . 21.78)
  8.         )
  9.     )
  10.     (if (setq sel (ssget "_+.:E:S" '((0 . "LWPOLYLINE"))))
  11.         (progn
  12.             (setq ent (ssname sel 0)
  13.                   cir (cons -1 (entmakex (list '(0 . "CIRCLE") '(10 1e8 1e8) (cons 40 (cdar lst)))))
  14.             )
  15.             (while (/= 3 (car (setq grr (grread t 15 0))))
  16.                 (cond
  17.                     (   (= 5 (car grr))
  18.                         (entmod (list cir (cons 10 (vlax-curve-getclosestpointto ent (cadr grr)))))
  19.                     )
  20.                     (   (= 2 (car grr))
  21.                         (if (setq rad (cdr (assoc (cadr grr) lst)))
  22.                             (entmod (list cir (cons 40 rad)))
  23.                         )
  24.                     )
  25.                 )
  26.             )
  27.         )
  28.     )
  29.     (princ)
  30. )

Note that the above is only a draft and doesn't account for UCS/Views etc.
Title: Re: Grread - dynamic sizing/position of circle
Post by: deanby7 on January 28, 2017, 02:40:37 AM
Brilliant! Thanks Lee
Title: Re: Grread - dynamic sizing/position of circle
Post by: Grrr1337 on January 28, 2017, 05:15:36 AM
Brilliant! Thanks Lee

Indeed. That assoc lst he used is brilliant!
Got me thinking that something can be written like action_tile, but it would work for grread instead of dialog.
Just leaving the idea. :idea:
Title: Re: Grread - dynamic sizing/position of circle
Post by: Lee Mac on January 28, 2017, 07:59:51 AM
Thank you both  :-)
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 02, 2017, 01:16:33 PM
Consider that when updating the circle position, you are using the original DXF data, as opposed to the DXF data which may hold a different radius value.

I would personally suggest:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:gg ( / cir ent grr lst rad sel )
  2.     (setq lst
  3.        '(
  4.             (49 . 12.78)
  5.             (50 . 15.78)
  6.             (51 . 18.78)
  7.             (52 . 21.78)
  8.         )
  9.     )
  10.     (if (setq sel (ssget "_+.:E:S" '((0 . "LWPOLYLINE"))))
  11.         (progn
  12.             (setq ent (ssname sel 0)
  13.                   cir (cons -1 (entmakex (list '(0 . "CIRCLE") '(10 1e8 1e8) (cons 40 (cdar lst)))))
  14.             )
  15.             (while (/= 3 (car (setq grr (grread t 15 0))))
  16.                 (cond
  17.                     (   (= 5 (car grr))
  18.                         (entmod (list cir (cons 10 (vlax-curve-getclosestpointto ent (cadr grr)))))
  19.                     )
  20.                     (   (= 2 (car grr))
  21.                         (if (setq rad (cdr (assoc (cadr grr) lst)))
  22.                             (entmod (list cir (cons 40 rad)))
  23.                         )
  24.                     )
  25.                 )
  26.             )
  27.         )
  28.     )
  29.     (princ)
  30. )

Note that the above is only a draft and doesn't account for UCS/Views etc.
Has anyone tried this function in Bricscad?
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 03, 2017, 03:45:47 AM
Version for Bricscad:
Code: [Select]
(defun c:ggB ( / EntDat ent grr lst rad sel )
   (setq lst
      '(
           (49 . 12.78)
           (50 . 15.78)
           (51 . 18.78)
           (52 . 21.78)
       )
   )
    (if (setq sel (ssget "_+.:E:S" '((0 . "LWPOLYLINE"))))
        (progn
            (setq ent    (ssname sel 0)
                  EntDat (entget (entmakex (list '(0 . "CIRCLE") '(10 1e8 1e8) (cons 40 (cdar lst)))))
            )
            (while (/= 3 (car (setq grr (grread t 15 0))))
                (cond
                    (   (= 5 (car grr))
                        (setq EntDat (entmod (subst (cons 10 (vlax-curve-getclosestpointto ent (cadr grr))) (assoc 10 EntDat) EntDat)))
                    )
                    (   (= 2 (car grr))
                        (if (setq rad (cdr (assoc (cadr grr) lst)))
                          (setq EntDat (entmod (subst (cons 40 rad) (assoc 40 EntDat) EntDat)))
                        )
                    )
                )
            )
        )
    )
    (princ)
)
Title: Re: Grread - dynamic sizing/position of circle
Post by: Lee Mac on February 03, 2017, 08:05:01 AM
Thank you Marc, I wasn't aware that BricsCAD could not modify entities using only the entity name group & groups to be modified.
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 03, 2017, 08:18:33 AM
 
Thank you Marc, I wasn't aware that BricsCAD could not modify entities using only the entity name group & groups to be modified.
:-) Prego.
Title: Re: Grread - dynamic sizing/position of circle
Post by: roy_043 on February 05, 2017, 02:06:17 PM
Thank you Marc, I wasn't aware that BricsCAD could not modify entities using only the entity name group & groups to be modified.
:-) Prego.
... Alternatively the vle-entmod function can be used.
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 06, 2017, 04:22:11 AM
Thank you Marc, I wasn't aware that BricsCAD could not modify entities using only the entity name group & groups to be modified.
:-) Prego.
... Alternatively the vle-entmod function can be used.
Ok, but the problem is that is not compatible with AutoCAD...  :cry:
Title: Re: Grread - dynamic sizing/position of circle
Post by: roy_043 on February 06, 2017, 08:02:58 AM
Ok, but the problem is that is not compatible with AutoCAD...  :cry:
Try sending in a Support Request.
Title: Re: Grread - dynamic sizing/position of circle
Post by: MP on February 06, 2017, 08:55:00 AM
Write a function that branches on loading, defining (for the life time of the session) a wrapper (say _entmod) that sports the same interface regardless the platform but internally invokes vle-entmod | entmod appropriately.
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 06, 2017, 09:20:29 AM
Write a function that branches on loading, defining (for the life time of the session) a wrapper (say _entmod) that sports the same interface regardless the platform but internally invokes vle-entmod | entmod appropriately.
Yes maybe it is the best solution ... but I seem to remember that AutoCAD does not support the method using entmod with only the entity name for all entities...
Title: Re: Grread - dynamic sizing/position of circle
Post by: Lee Mac on February 06, 2017, 12:45:22 PM
I seem to remember that AutoCAD does not support the method using entmod with only the entity name for all entities...

Correct - but Circles are supported.

I have this in my notes:

TYPE      MODIFIED USING ONLY ENAME?
=====================================
ARC                   YES
ATTRIB (SINGLE)       YES
ATTRIB (MULTI)        NO
CIRCLE                YES
ELLIPSE               NO
HATCH                 NO
INSERT                YES
LINE                  YES
LWPOLYLINE            NO
MTEXT                 NO
POINT                 YES
POLYLINE              YES
SPLINE                NO
TEXT                  YES
XLINE                 NO
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 06, 2017, 01:01:26 PM
I seem to remember that AutoCAD does not support the method using entmod with only the entity name for all entities...

Correct - but Circles are supported.

I have this in my notes:

TYPE      MODIFIED USING ONLY ENAME?
=====================================
ARC                   YES
ATTRIB (SINGLE)       YES
ATTRIB (MULTI)        NO
CIRCLE                YES
ELLIPSE               NO
HATCH                 NO
INSERT                YES
LINE                  YES
LWPOLYLINE            NO
MTEXT                 NO
POINT                 YES
POLYLINE              YES
SPLINE                NO
TEXT                  YES
XLINE                 NO

Thanks, are the new entities after about 2000...

ATTRIB (MULTI)    NO
ELLIPSE               NO
HATCH                 NO (maybe new type of)
LWPOLYLINE        NO
MTEXT                 NO
SPLINE                NO
XLINE                 NO
Title: Re: Grread - dynamic sizing/position of circle
Post by: MP on February 06, 2017, 02:36:21 PM
... internally invokes vle-entmod | entmod appropriately.
Yes maybe it is the best solution ... but I seem to remember that AutoCAD does not support the method using entmod with only the entity name for all entities...

                                        ^
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 06, 2017, 03:58:35 PM
 
... internally invokes vle-entmod | entmod appropriately.
Yes maybe it is the best solution ... but I seem to remember that AutoCAD does not support the method using entmod with only the entity name for all entities...

                                        ^
:yes:
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 07, 2017, 10:15:56 AM
... internally invokes vle-entmod | entmod appropriately.
Yes maybe it is the best solution ... but I seem to remember that AutoCAD does not support the method using entmod with only the entity name for all entities...

                                        ^
I do not know if the game's not worth the candle but I have discovered that Bricscad return nil if vle-entmod fail on New entities:
Code: [Select]
(defun ALE_EntMod (EntNam NewLst / Entdat)
  (cond
    ( vle-entmod (vle-entmod (car NewLst) EntNam (cdr NewLst)) ); Bricscad return nil if fail
    ( (entmod (list (cons -1 EntNam) NewLst)) )                 ; Old entities
    ( (setq Entdat (entget EntNam))                             ; New entities
      (entmod (subst NewLst (assoc (car NewLst) EntDat) EntDat))
    ) ;this condition is not used because entmod do not return nil if fail
  )
)

(defun Dxf (DxfCod EntDat)  (cdr (assoc DxfCod EntDat)))

(defun C:TestEntMod  ( / EntNam EntDat New040)
  (setq
    EntNam (car (entsel))
    EntDat (entget EntNam)
    New040 (1+ (DXF 40 EntDat))
  )
  (print (DXF 0 EntDat))
  (print (DXF 40 EntDat)) (princ " Old Value")
  (print New040)          (princ " New Value")
  (ALE_EntMod EntNam (cons 40 New040))
  (print (DXF 40 (entget EntNam))) (princ " Real Value\n")
  (princ)
)
Code: [Select]
AutoCAD:
Comando: TestEntMod
Selezionare oggetto:
"CIRCLE"
18.0  Old Value
19.0  New Value
19.0  Real Value

Comando:  TestEntMod
Selezionare oggetto:
"ELLIPSE"
0.603314  Old Value
1.60331   New Value
0.603314  Real Value
Code: [Select]
Bricscad
: TESTENTMOD
Select entity:
"CIRCLE"
19.0  Old Value
20.0  New Value
20.0  Real Value
:
: TESTENTMOD
Select entity:
"ELLIPSE"
0.603313750533175  Old Value
1.60331375053317   New Value
0.603313750533175  Real Value
Title: Re: Grread - dynamic sizing/position of circle
Post by: roy_043 on February 07, 2017, 10:23:44 AM
I do not know if the game's not worth the candle but I have discovered that Bricscad return nil if vle-entmod fail on New entities:
How does your code use this fact? And does this really only apply to new entities?
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 07, 2017, 10:52:22 AM
I do not know if the game's not worth the candle but I have discovered that Bricscad return nil if vle-entmod fail on New entities:
How does your code use this fact? And does this really only apply to new entities?
My pseudo code fail on new entities as vle-entmod return nil if fail
    ( vle-entmod (vle-entmod (car NewLst) EntNam (cdr NewLst)) ); Bricscad return nil if fail

    ( (setq Entdat (entget EntNam))                             ; New entities
      (entmod (subst NewLst (assoc (car NewLst) EntDat) EntDat))
    ) ;this condition is not used because entmod do not return nil if fail
Title: Re: Grread - dynamic sizing/position of circle
Post by: roy_043 on February 07, 2017, 04:21:42 PM
My pseudo code fail on new entities as vle-entmod return nil if fail
But vle-entmod works on both 'old' and 'new' entities and your code does nothing with the return value from that function.
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 07, 2017, 05:08:27 PM
My pseudo code fail on new entities as vle-entmod return nil if fail
But vle-entmod works on both 'old' and 'new' entities and your code does nothing with the return value from that function.
Ok, my apologies. I have found my error: (1+ (cdr (assoc 40 EntDat)) >>> 1+ is too big value for the ellipse!
Grazie.  :oops:
This is a better test:
Code: [Select]
(defun C:TestEntMod  ( / EntNam EntDat New062)
  (setq
    EntNam (car (entsel))
    EntDat (entget EntNam)
    New062 (1+ (DXF 62 EntDat))
  )
  (print (DXF 0 EntDat))
  (print (DXF 62 EntDat)) (princ " Old Value")
  (print New062)          (princ " New Value")
  (ALE_EntMod EntNam (cons 62 New062))
  (print (DXF 62 (entget EntNam))) (princ " Real Value\n")
  (princ)
)
Title: Re: Grread - dynamic sizing/position of circle
Post by: Marc'Antonio Alessi on February 08, 2017, 03:19:10 AM
I have founfd the original code of Bricscad:
Code: [Select]
;;================================================================================
;;|              Copyright © Menhirs NV. All rights reserved.                    |
;;================================================================================
;; VLE Library Emulation for AutoCAD 2000 and higher, and for all BricsCAD versions
;;================================================================================
;;| FUNCTION : vle-entmod                                                        |
;;|------------------------------------------------------------------------------|
;;| (vle-entmod dxf ename value)                                                 |
;;|                                                                              |
;;| modifies the entity's property value for specified DXF group code;           |
;;| in typical case, this is a high-performance replacement for usual code like  |
;;| (entmod (subst (cons dxf value) olditem lst))                                |
;;|                                                                              |
;;| Arguments : 'dxf'   the DXF group code to set the new value for              |
;;|           : 'ename' the entity's ename                                       |
;;|           : 'value' new value to be set for the entity's property            |
;;|                                                                              |
;;| Return    :  T   if the entity's value has been updated (or is identical)    |
;;|              NIL if updating the entity's DXF value failed                   |
;;|                                                                              |
;;| Example   :  (vle-entmod 62 entity 112) sets the colour index as 112         |
;;================================================================================
(if (not vle-entmod)
  (defun vle-entmod ( dxf ename value / olditem lst )
    (if (setq lst (entget ename))
      (if (setq olditem (assoc dxf lst))
        (if (not (equal value (cdr olditem)))
          (and (entmod (subst (cons dxf value) olditem lst)))
          t ;; new value is same as current value, do not update, to keep performance
        )
        (and (entmod (append lst (list (cons dxf value)))))
      )
    )
  )
)
So, it use always the old method with subst...
Title: Re: Grread - dynamic sizing/position of circle
Post by: ScottMC on September 02, 2021, 09:07:17 PM
Anyone able to show me how to reveal/extract the working choice from the "cir" entity (the lst selected)? Did a bit of diggin but must need to convert or something. Entities do have value and wish find out how to work a snatch live (assoc 40 cdr ..somehow. Thanks again.
Consider that when updating the circle position, you are using the original DXF data, as opposed to the DXF data which may hold a different radius value.

I would personally suggest:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:gg ( / cir ent grr lst rad sel )
  2.     (setq lst
  3.        '(
  4.             (49 . 12.78)
  5.             (50 . 15.78)
  6.             (51 . 18.78)
  7.             (52 . 21.78)
  8.         )
  9.     )
  10.     (if (setq sel (ssget "_+.:E:S" '((0 . "LWPOLYLINE"))))
  11.         (progn
  12.             (setq ent (ssname sel 0)
  13.                   cir (cons -1 (entmakex (list '(0 . "CIRCLE") '(10 1e8 1e8) (cons 40 (cdar lst)))))
  14.             )
  15.             (while (/= 3 (car (setq grr (grread t 15 0))))
  16.                 (cond
  17.                     (   (= 5 (car grr))
  18.                         (entmod (list cir (cons 10 (vlax-curve-getclosestpointto ent (cadr grr)))))
  19.                     )
  20.                     (   (= 2 (car grr))
  21.                         (if (setq rad (cdr (assoc (cadr grr) lst)))
  22.                             (entmod (list cir (cons 40 rad)))
  23.                         )
  24.                     )
  25.                 )
  26.             )
  27.         )
  28.     )
  29.     (princ)
  30. )

Note that the above is only a draft and doesn't account for UCS/Views etc.