TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: ozimad on August 23, 2010, 02:24:50 PM

Title: linked/synchronized/ entities and objects
Post by: ozimad on August 23, 2010, 02:24:50 PM
Hi everyone!
I am searching articles, tutorial and help in creation of linked/synchronized/ entities and objects.
For example how to get text linked to the polyline, when i move polyline text moves along.
Or moving one block another block follows first, by linking insertion points.
i think the idea is clear,
thanks in advance for the help.
Title: Re: linked/synchronized/ entities and objects
Post by: Lee Mac on August 23, 2010, 02:29:15 PM
Look into using an Object Reactor perhaps  :-)
Title: Re: linked/synchronized/ entities and objects
Post by: CAB on August 23, 2010, 07:56:27 PM
Some examples 8-)
Code: [Select]
http://www.theswamp.org/index.php?topic=29153.0  Align Text to Curve by Lee Mac
http://www.cadtutor.net/forum/showthread.php?37646-Align-Text-to-Curve
http://www.theswamp.org/index.php?topic=33735.0  Slinky Text by Lee Mac
Title: Re: linked/synchronized/ entities and objects
Post by: ozimad on August 24, 2010, 03:52:37 AM
Code: [Select]
(defun c:rtc2 (/ c1 c2 objlst obj_reactor p1 p2 rad vgad vgao vgms)
(vl-load-com)
(setq vgao (vlax-get-acad-object))
(setq vgad (vla-get-activedocument vgao))
(setq vgms (vla-get-modelspace vgad))
(setq p1 '(0 0 0))
(setq p2 '(5 5 0))
(setq rad 0.5)
(setq c1 (vla-addCircle vgms (vlax-3d-point p1) rad))
(vla-put-color c1 acred)
(setq c2 (vla-addline vgms (vlax-3d-point p1) (vlax-3d-point p2) ))
(vla-put-color c2 acblue)
(setq objlst (list c1 c2))
(setq obj_reactor (vlr-object-reactor
objlst
nil
'((:vlr-modified . callback2))))
)

(defun callback2 (notifier-object obj_reactor parameter-list
/ objlist newcenter)
(setq objlist (vlr-owners obj_reactor))
(print (setq newcenter (vlax-safearray->list (vlax-variant-value (vla-get-center notifier-object)))))
(if
(= notifier-object (nth 0 objlist))
(vla-put-startpoint (nth 1 objlist)  (vlax-3d-point newcenter))
(vla-put-center (nth 0 objlist)   (vlax-3d-point newcenter))
))
I found some code and trying to find out how thinks work, I want line start point to follow circle center point, and circle centre point to follow line startpoint.
Can some body please show me my mistake  :-)
Thanks a lot!
Title: Re: linked/synchronized/ entities and objects
Post by: CAB on August 24, 2010, 07:39:32 AM
You will need two reactors, one for each object.
When the line is modified the line reactor should move the circle.
When the circle is moved the circle reactor should modify the line.
If both are Moved then nothing should be done, as you can not modify a the object tied to the reactor
as that would fire the reactor again and again.

I am off to work so I can't look for the "Circle Line Reactor" example. I have it some where.
Title: Re: linked/synchronized/ entities and objects
Post by: Lee Mac on August 24, 2010, 08:03:38 AM
I remember Kerry posted something a while back - either using two reactors, or perhaps adding both objects to the owner list and identifying which called the reactor by the object argument in the callback function.

Lee
Title: Re: linked/synchronized/ entities and objects
Post by: ozimad on August 24, 2010, 08:16:29 AM
i difined 2 reactors.
How can i save them?
When i close drawing ther are not active anymore.
Title: Re: linked/synchronized/ entities and objects
Post by: Lee Mac on August 24, 2010, 02:45:23 PM
i difined 2 reactors.
How can i save them?
When i close drawing ther are not active anymore.

Transcient reactors are not active after the drawing closes. Persistent reactors will be, but I would advise against these. Most people rebuild the reactor using handles stored in perhaps xData or lData, or a dictionary.
Title: Re: linked/synchronized/ entities and objects
Post by: dgorsman on August 24, 2010, 04:44:37 PM
i difined 2 reactors.
How can i save them?
When i close drawing ther are not active anymore.

Transcient reactors are not active after the drawing closes. Persistent reactors will be, but I would advise against these. Most people rebuild the reactor using handles stored in perhaps xData or lData, or a dictionary.

Object reactors are a cool idea in theory, but are a serious PITA to manage.  Especially true when drawings go out of your control or you have to manage more than a few per drawing.
Title: Re: linked/synchronized/ entities and objects
Post by: ozimad on November 05, 2010, 04:25:35 AM
It took time to learn reactors, a nice and powerful tool...  :-)
Now its time to learn how to remove them!  :pissed: it looks like a cannot simply delete elements used by reactors. I think need to remove the reactor and then the element.
Anyone to help? How to do that? there is a lack of info on the net, about reactors, especially in examples.
Thanks in advance!
Title: Re: linked/synchronized/ entities and objects
Post by: roy_043 on November 05, 2010, 05:15:49 AM
I've just started working with reactors myself.
To remove reactors try this:
Code: [Select]
(mapcar 'vlr-pers-release (vlr-pers-list)) ; make all persistent reactors transient
(vlr-remove-all) ; deactivates all reactors
Title: Re: linked/synchronized/ entities and objects
Post by: ozimad on November 05, 2010, 05:34:09 AM
But i need to remove some of them, not all
Title: Re: linked/synchronized/ entities and objects
Post by: roy_043 on November 05, 2010, 06:30:31 AM
If you store a reference to the reactor object in a (global) variable:
Code: [Select]
<snip>
  (setq *obj_reactor*
    (vlr-object-reactor
      objlst
      nil
      '((:vlr-modified . callback2))
    )
  )
<snip>
You can do this:
Code: [Select]
<snip>
  (vlr-remove *obj_reactor*) ; deactivate the reactor
<snip>
  (vlr-add *obj_reactor*); reactivate the reactor
<snip>

If you want to disable a certain category of reactors you can do something like this:
Code: [Select]
<snip>
  (mapcar
    'vlr-remove
    (setq allCommandReactors (apply 'append (mapcar 'cdr (vlr-reactors :VLR-Command-Reactor))))
  )
<snip>
  (mapcar 'vlr-add allCommandReactors)
<snip>
Title: Re: linked/synchronized/ entities and objects
Post by: Lee Mac on November 05, 2010, 07:34:34 AM
I tend to manipulate the reactors using the reactor data (vlr-data), as IMO, this is more reliable than a global variable - hence, to retrieve a specific reactor object, I use such functions as:

Code: [Select]
;;----------------=={ Get Reactor Object }==------------------;;
;;                                                            ;;
;;  Returns the reactor object of the specified type          ;;
;;  associated with the application data supplied             ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  data - reactor application data                           ;;
;;  typ  - Type of reactor to query, eg :vlr-object-reactor   ;;
;;------------------------------------------------------------;;
;;  Returns: VLA Reactor Object, else nil                     ;;
;;------------------------------------------------------------;;

(defun _GetReactorObject ( data typ )
  (vl-some
    (function
      (lambda ( reactor )
        (if (eq data (vlr-data reactor)) reactor)
      )
    )
    (cdar (vlr-reactors typ))
  )
)

Then release the reactor returned.

This method is demonstrated in this thread:

http://www.theswamp.org/index.php?topic=35192.0 (http://www.theswamp.org/index.php?topic=35192.0)

Title: Re: linked/synchronized/ entities and objects
Post by: roy_043 on November 05, 2010, 08:09:09 AM
@ Lee Mac:
Of course several reactors of the same type can have the same (e.g. nil) data...

BTW: like Lee I should have used cdar as well...
Old:
Code: [Select]
    (setq allCommandReactors (apply 'append (mapcar 'cdr (vlr-reactors :VLR-Command-Reactor))))New:
Code: [Select]
    (setq allCommandReactors (cdar (vlr-reactors :VLR-Command-Reactor)))
Title: Re: linked/synchronized/ entities and objects
Post by: gile on November 06, 2010, 04:21:52 AM
Hi,

You can find here:
http://www.theswamp.org/index.php?topic=29339.0
an example of ObjectReactor using.
It shows how to create a new command reactor and lisp reactor within the object reactor callback function and how to remove them within their callbak functions.
It shows too how to store the objects handles in a dictionnary on saving so that the reactors can be re-built if the routine is loaded when the file is re-opened.

And another one here:
http://www.theswamp.org/index.php?topic=28604.0
which dynamically link block attributes values to one or more entities.
Title: Re: linked/synchronized/ entities and objects
Post by: ozimad on November 08, 2010, 06:04:51 AM
thats all is too difficult for me  :-(
i simply need to select manually an object and delete it with all the reactor connected to it.
Title: Re: linked/synchronized/ entities and objects
Post by: roy_043 on November 08, 2010, 07:23:10 AM
Try this:

Code: [Select]
(defun c:EraseAndDisconnect ( / allReactors obj)
  (vl-load-com)
  (setq allReactors (apply 'append (mapcar 'cdr (vlr-reactors))))
  (mapcar 'vlr-remove allReactors) ; temporarily disable all reactors
  (setq obj (vlax-ename->vla-object (car (entsel))))
  (vla-delete obj)
  (mapcar 'vlr-add allReactors)
  ; (mapcar
    ; '(lambda (a)
      ; (vlr-owner-remove a obj)
    ; )
    ; (cdar (vlr-reactors :vlr-object-reactor))
  ; )
  (princ)
)

<edit: code that doesn't work properly has been commented out...>
Title: Re: linked/synchronized/ entities and objects
Post by: cmwade77 on November 08, 2010, 11:51:20 AM
Isn't this what the Parametric tools are for?
Title: Re: linked/synchronized/ entities and objects
Post by: roy_043 on November 08, 2010, 02:37:46 PM
This version of EraseAndDisconnect is probably better:

Code: [Select]
(defun c:EraseAndDisconnect2 ( / allReactorsLst obj removeLst)
  (vl-load-com)
  (setq obj (vlax-ename->vla-object (car (entsel))))
  (mapcar
    '(lambda (a / ownLst)
      (setq ownLst (vlr-owners a))
      (cond
        ((and (member obj ownLst) (= (length ownLst) 1))
          (vlr-remove a)
        )
        ((member obj ownLst)
          (vlr-owner-remove a obj)
        )
      )
    )
    (apply 'append (mapcar 'cdr (vlr-reactors :vlr-object-reactor)))
  )
  (setq allReactors (apply 'append (mapcar 'cdr (vlr-reactors))))
  (mapcar 'vlr-remove allReactors) ; temporarily disable all reactors
  (vla-delete obj)
  (mapcar 'vlr-add allReactors)
  (princ)
)
Title: Re: linked/synchronized/ entities and objects
Post by: ozimad on November 10, 2010, 05:58:46 AM
Thanks a lot for your help!
ereaseanddisconnect2 work perfect  :wink: