TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started 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.
-
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:(defun c:gg
( / cir ent grr lst rad sel
) '(
(49 . 12.78)
(50 . 15.78)
(51 . 18.78)
(52 . 21.78)
)
)
)
)
)
)
)
)
)
)
)
Note that the above is only a draft and doesn't account for UCS/Views etc.
-
Brilliant! Thanks Lee
-
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:
-
Thank you both :-)
-
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:(defun c:gg
( / cir ent grr lst rad sel
) '(
(49 . 12.78)
(50 . 15.78)
(51 . 18.78)
(52 . 21.78)
)
)
)
)
)
)
)
)
)
)
)
Note that the above is only a draft and doesn't account for UCS/Views etc.
Has anyone tried this function in Bricscad?
-
Version for Bricscad:
(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)
)
-
Thank you Marc, I wasn't aware that BricsCAD could not modify entities using only the entity name group & groups to be modified.
-
Thank you Marc, I wasn't aware that BricsCAD could not modify entities using only the entity name group & groups to be modified.
:-) Prego.
-
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.
-
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:
-
Ok, but the problem is that is not compatible with AutoCAD... :cry:
Try sending in a Support Request.
-
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.
-
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...
-
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
-
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
-
... 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...
^
-
... 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:
-
... 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:
(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)
)
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
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
-
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?
-
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
-
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.
-
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:
(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)
)
-
I have founfd the original code of Bricscad:
;;================================================================================
;;| 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...
-
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:(defun c:gg
( / cir ent grr lst rad sel
) '(
(49 . 12.78)
(50 . 15.78)
(51 . 18.78)
(52 . 21.78)
)
)
)
)
)
)
)
)
)
)
)
Note that the above is only a draft and doesn't account for UCS/Views etc.