Lt Dan's legs Posted August 3, 2011 Posted August 3, 2011 (edited) I'm using this reactor on a dynamic block. It works fine until you use a Flip Parameter.. What am I doing wrong? see video (in zip file)problem.zip ( (lambda ( e / reactor ) (vl-load-com) (and e (setq reactor (vlr-object-reactor (list (vlax-ename->vla-object e)) nil (list (cons :vlr-modified 'stretch)) ) )(vlr-data-set reactor reactor) ) )(car (entsel)) ) (defun stretch ( owner react args ) (if (vlax-vla-object->ename owner) (vlax-invoke (vlax-get (vlax-get-acad-object) 'ActiveDocument) 'Regen acActiveViewport )(vlr-remove react) ) ) Edited August 4, 2011 by Lt Dan's legs Quote
Lt Dan's legs Posted August 4, 2011 Author Posted August 4, 2011 Is there a way to update a field without regenerating the drawing? Quote
Lee Mac Posted August 4, 2011 Posted August 4, 2011 Is there a way to update a field without regenerating the drawing? UPDATEFIELD command? Quote
Lt Dan's legs Posted August 4, 2011 Author Posted August 4, 2011 It seems both command and vl-cmdf will not work with reactors. Quote
BlackBox Posted August 4, 2011 Posted August 4, 2011 UPDATEFIELD command? Lee, does the UPDATEFIELD command operate in conjunction with, or in lieu of, the FIELDEVAL System Variable setting? The Command Reference only excluded the Date from being updated; didn't quite understand. Quote
Lee Mac Posted August 4, 2011 Posted August 4, 2011 It seems both command and vl-cmdf will not work with reactors. Indeed, command call's cannot be used with reactors. You could alternatively update a text object using a reactor perhaps? Quote
Lee Mac Posted August 4, 2011 Posted August 4, 2011 Lee, does the UPDATEFIELD command operate in conjunction with, or in lieu of, the FIELDEVAL System Variable setting? I would say in conjunction with - for times when you want to manually force a field to update. The exception being a Date field, for which the help indicates must be updated using the updatefield command. /guess Quote
Lt Dan's legs Posted August 4, 2011 Author Posted August 4, 2011 Indeed, command call's cannot be used with reactors. You could alternatively update a text object using a reactor perhaps? See beginning post for my current reactor. It looks like when flip is selected on the owner object the reactor runs twice. It seems you cannot regen the dwg twice in a row..? Quote
Lt Dan's legs Posted August 4, 2011 Author Posted August 4, 2011 __edit__ Lee, ignore previous post. I understand now. Thanks for the help. Quote
Lt Dan's legs Posted August 4, 2011 Author Posted August 4, 2011 Indeed, command call's cannot be used with reactors. You could alternatively update a text object using a reactor perhaps? (defun stretch ( owner react args / lst ) (if (vlax-vla-object->ename owner) (progn (vlax-for x (vla-item (vlax-get (vlax-get (vlax-get-acad-object) 'ActiveDocument) 'Blocks) "airspace" ) (cond ( (eq (vlax-get x 'ObjectName) "AcDbRotatedDimension") (setq lst (cons (cons "AcDbRotatedDimension" x) lst)) ) ( (and (eq (vlax-get x 'ObjectName) "AcDbText") (wcmatch (strcase (vlax-get x 'TextString)) "*AIR*") ) (setq lst (cons (cons "AcDbText" x) lst)) ) ) ) (vlax-put (cdr (assoc "AcDbText" lst)) 'TextString (strcat (rtos (vla-get-Measurement (cdr (assoc "AcDbRotatedDimension" lst)) ) 5 4 ) "\" AIR SPACE" ) )(vla-update owner) )(vlr-remove react) ) ) ; error: Automation Error. Object was notifying Quote
Lee Mac Posted August 4, 2011 Posted August 4, 2011 You can't modify the owner of the object reactor within the object reactor callback function for which that object is an owner. This would cause an infinite callback loop since the modification would fire the reactor, evaluating the callback function, triggering the reactor... However, there is a workaround if you want to modify the owner of an object reactor within its own callback function: disable the object reactor within the object reactor callback function and create a command reactor triggered by the commandended event. Then, within the callback function of the command reactor, modify the owner and re-enable the object reactor, then remove the command reactor. This is the method I use to retain the position of the centerlines in this program. 1 Quote
Lee Mac Posted August 4, 2011 Posted August 4, 2011 You might also be interested in this thread: http://www.theswamp.org/index.php?topic=37937.0 Quote
Lt Dan's legs Posted August 4, 2011 Author Posted August 4, 2011 Thanks Lee. I'll check out the link and give it a try tomorrow. Quote
Lee Mac Posted August 4, 2011 Posted August 4, 2011 My remarks in post#11 could perhaps explain your crash in the first post of this thread, since, if the field is part of the object reactor owner block and is being updated in the callback function, this would trigger the reactor, causing an infinite callback loop, regenerating the drawing repeatedly. Quote
Lt Dan's legs Posted August 5, 2011 Author Posted August 5, 2011 (edited) This works. I was making it more complicated than it had to be. ;|¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤- ;- converts a selection set into a list of enames/vla-objects ;- (ss->lst ss flag) ;--------------------------------------------------------------------------------------------------- ;- ss = selection set ;- flag = (T will return vl-objects, NIL will return enames) ;-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤- ; Example: ; (ss->lst (ssget) t) ; Returns: ; (#<VLA-OBJECT IAcadBlockReference 13293944> #<VLA-OBJECT IAcadLine 132e0864>) ;--------------------------------------------------------------------------------------------------- ; Example: ; (ss->lst (ssget) nil) ; Returns: ; (<Entity name: 7ed4f318> <Entity name: 7ed4f320>) ;-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤-¤|; (defun ss->lst ( ss flag / id lst ) (repeat (setq id (sslength ss)) ( (lambda ( name ) (setq lst (cons (if flag (vlax-ename->vla-object name) name )lst ) ) )(ssname ss (setq id (1- id))) ) ) ) (vlr-command-reactor "FieldUpdate" (list (cons :vlr-CommandEnded 'Regen)) ) (defun Regen ( react data / ss ) (cond ( (and (equal data '("GRIP_STRETCH")) (setq ss (ss->lst (ssget "_p") t)) (vl-position "airspace" (mapcar (function vla-get-effectivename) (vl-remove-if-not (function (lambda ( x ) (vlax-property-available-p x 'EffectiveName) ) )ss ) ) ) ) (vlax-invoke (vlax-get (vlax-get-acad-object) 'ActiveDocument) 'Regen acActiveViewport ) ) ) (princ) ) Edited August 5, 2011 by Lt Dan's legs Quote
Lee Mac Posted August 5, 2011 Posted August 5, 2011 Good solution Dan I might be inclined to make the ActiveDocument global, to improve performance: (if (not *field-update*) (setq *field-update* (vlr-command-reactor "Field-Update" '((:vlr-commandended . field-regen))) ) ) (defun field-regen ( reactor params ) (cond ( (equal params '("GRIP_STRETCH")) (vla-regen (setq *acdoc* (cond ( *acdoc* ) ( (vla-get-activedocument (vlax-get-acad-object)) ) ) ) acactiveviewport ) ) ) (princ) ) Quote
Lt Dan's legs Posted August 5, 2011 Author Posted August 5, 2011 I use grip stretch more than I thought.. lisp revised Thanks for all the help Lee Quote
disposedhero Posted June 5, 2017 Posted June 5, 2017 Good afternoon, I realize this is an old thread but I just stumbled across it and am hoping that someone can help me out. I have a dynamic block that has a few fields in it. The fields are tied to a lookup table and are updated with whatever option is chosen on the lookup table. What I would like to do is have the field automatically regen after each selection is made on the lookup table. Right now what I have to do is manually "regen" each time that I make a selection in the block. I realize that manually doing a regen isn't necessarily a big deal, however once there are multiple blocks in a drawing the regen is taking a great deal of time. The other option would be to have a bunch of visibility states that would cycle between the various text that I want displayed instead of using a lookup table. But making blocks with 150+ visibility states is very tedious. Is it possible to have a reactor auto regenerate a field so that the change appears seamless? Auto Regen Field Values with Reactor.dwg Quote
Lee Mac Posted June 5, 2017 Posted June 5, 2017 (edited) Try the following: ( (lambda ( ) (vl-load-com) (foreach rtr (cdar (vlr-reactors :vlr-command-reactor)) (if (= "regen-reactor" (vlr-data rtr)) (vlr-remove rtr)) ) (vlr-set-notification (vlr-command-reactor "regen-reactor" '((:vlr-commandended . regenreactor:callback))) 'active-document-only ) (defun regenreactor:callback ( rtr arg ) (if (= (strcase (car arg) t) "grip_popup") (progn (eval (list 'defun 'regenreactor:callback '( rtr arg ) (list 'if '(= (strcase (car arg) t) "grip_popup") (list 'vla-regen (vla-get-activedocument (vlax-get-acad-object)) 'acactiveviewport) ) '(princ) ) ) (regenreactor:callback rtr arg) ) ) (princ) ) (princ) ) ) Edited June 6, 2017 by Lee Mac Updated function redefinition. Quote
disposedhero Posted June 6, 2017 Posted June 6, 2017 It worked like a charm, thanks so much! This will go a long way in making my dynamic blocks more useable. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.