Author Topic: Reactor question  (Read 33874 times)

0 Members and 1 Guest are viewing this topic.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Reactor question
« Reply #30 on: February 15, 2006, 03:55:38 PM »
Luis

I was just shooting from the hip. I think you can use his routine to embed the the areareact.lsp code within the drawing.
Then you could send the drawing to someone who does not have the code to keep the reactor persistant. It has been
a long time since I tried this. Maybe Peter can answer this.

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

LE

  • Guest
Re: Reactor question
« Reply #31 on: February 15, 2006, 04:05:46 PM »
  How can you have it set up so it doesn't error?  I'm sure there is a slick way that I haven't though of yet, so if anyone knows, please let me know.

Code: [Select]
(vl-load-com)
(vlax-ldata-put "TWILLEY" "AUTO_LOAD" nil t)

;; my functions in the right loading order start from here:


Make your routine part of a protected namespace VLX standard

I posted this solution on one of the Question #.... for the swamp.... anyways, that's the BEST way to auto load your LISP routines.

LE

  • Guest
Re: Reactor question
« Reply #32 on: February 15, 2006, 04:10:16 PM »
Code: [Select]
:vlr-unerased ...

You do not need that.

LE

  • Guest
Re: Reactor question
« Reply #33 on: February 15, 2006, 04:31:09 PM »
Code: [Select]
:vlr-unerased ...

You do not need that.

To elaborate more:

In the modified event you simple use something like the following:
Code: [Select]
  (if (and (not (wcmatch (getvar "cmdnames")
"ERASE,CUTCLIP,U,UNDO,REDO,OOPS"))

... my stuff inside of the event....


Then, if the user use those commands, the reactor is not going to do NOTHING. and also, helps to get the built-in UNDO....

Autolisp and Visual Lisp are not structured coding.... All end up doing what they want... and that's a BAD habit... glad that I quit LISP.

stickto.lsp uses a proved solution that works.... btw.

LE

  • Guest
Re: Reactor question
« Reply #34 on: February 15, 2006, 04:54:42 PM »
Tim, this one works nice - just to test what I said in my previous post, without using vlr-unerased.... you are in the right track.... !

Code: [Select]
(defun c:AreaReact (/ Sel EntData PolyObj TextObj ReactList Pos)

;|  Adds a presistant reactor to a polyline object that
    updates a selected text object to the polylines area
    in square feet.  You will have to have the subs loaded
    in everydrawing for it to work, so that it know what
    to do with the reactor, because it is saved with the
    drawing.  Saves the association between the text
    and the polyline in the extension dictionary of the
    polyline.
    Thanks to Luis Esquivel for his help and guidance.
|;

(if
(and
  (setq Sel (entsel "\n Select polyline to get area of: "))
  (setq EntData (entget (car Sel)))
  (= (cdr (assoc 0 EntData)) "LWPOLYLINE")
  (setq PolyObj (vlax-ename->vla-object (car Sel)))
  (setq Sel (entsel "\n Select text of hold area value: "))
  (setq EntData (entget (car Sel)))
  (vl-position (cdr (assoc 0 EntData)) '("TEXT" "MTEXT"))
  (setq TextObj (vlax-ename->vla-object (car Sel)))
)
(progn
  (PutArea PolyObj TextObj)
  (if
   (and
    (setq ReactList (AssociatedReactors PolyObj))
    (setq Pos (vl-position "MyAreaReactorModified" (mapcar 'vlr-data ReactList)))
   )
   (vlr-remove (nth Pos ReactList))
  )
  (vlr-pers
   (vlr-object-reactor
    (list PolyObj)
    "MyAreaReactorModified"
    '(
     (:vlr-modified . MakeCmdEndReactor)
     (:vlr-erased . ObjectEraseReactor)
;;;;;;     (:vlr-unerased . ObjectUnErasedReactor)
    )
   )
  )
)
)
(princ)
)
;---------------------------------------------------------------------------------------------------------------
(defun PutArea (PolyObj TextObj / Dict xRec SqFt)

(setq Dict (vla-GetExtensionDictionary PolyObj))
(if (vl-catch-all-error-p (setq xRec (vl-catch-all-apply 'vla-Item (list Dict "MyAreaReactor"))))
(setq xRec (vla-AddXRecord Dict "MyAreaReactor"))
)
(MySetXrec xRec '(40 1) (list (vlax-get PolyObj 'Area) (vlax-get TextObj 'Handle)))
(setq SqFt (/ (vla-get-Area PolyObj) 144.0))
(vla-put-TextString TextObj (strcat (rtos SqFt 2 2) " SQ.FT."))
xRec
)
;----------------------------------------------------------------------------------------------------------------
(defun MakeCmdEndReactor (Obj React NotSure)

  (if (not (wcmatch (getvar "cmdnames")
"U,UNDO,REDO,OOPS")) (progn

(if GlbVarAreaObject
(setq GlbVarAreaObject (append GlbVarAreaObject (list Obj)))
(setq GlbVarAreaObject (list Obj))
)
(if (not GlbReactorCommandEnd)
(setq GlbReactorCommandEnd (vlr-command-reactor nil '((:vlr-commandEnded . AdjustTextObj))))
)

))
 
(princ)
)
;------------------------------------------------------------------------------------------------------------------
(defun ObjectEraseReactor (Obj React NotSure)

(vlr-pers-release React)
(vlr-remove React)
(setq GlbReactorCommandEnd nil)
)
;-----------------------------------------------------------------------------------------------------------------
;;;;;;;;;(defun ObjectUnErasedReactor (Obj React NotSure)
;;;;;;;;;
;;;;;;;;;(vlr-pers
;;;;;;;;;(vlr-object-reactor
;;;;;;;;;  (list Obj)
;;;;;;;;;  "MyAreaReactorModified"
;;;;;;;;;  '(
;;;;;;;;;   (:vlr-modified . MakeCmdEndReactor)
;;;;;;;;;   (:vlr-erased . ObjectEraseReactor)
;;;;;;;;;   (:vlr-unerased . ObjectUnErasedReactor)
;;;;;;;;;  )
;;;;;;;;;)
;;;;;;;;;)
;;;;;;;;;(setq GlbReactorCommandEnd nil)
;;;;;;;;;)
;-----------------------------------------------------------------------------------------------------------------
(defun AdjustTextObj (React CommandList / Dict xRec xRecList TextObj)

(foreach Obj GlbVarAreaObject
(if (not (vlax-erased-p Obj))
  (progn
   (setq Dict (vla-GetExtensionDictionary Obj))
   (if (not (vl-catch-all-error-p (setq xRec (vl-catch-all-apply 'vla-Item (list Dict "MyAreaReactor")))))
    (progn
     (setq xRecList (MyGetXRec xRec))
     (if
      (and
       (setq TextObj (vlax-ename->vla-object (setq tmpEnt (handent (cdr (assoc 1 xRecList))))))
       (not (vlax-erased-p TextObj))
      )
      (PutArea Obj TextObj)
     )
    )
   )
  )
)
)
(setq GlbVarAreaObject nil)
(setq GlbReactorCommandEnd nil)
)
;---------------------------------------------------------------------------
(defun MySetXRec (Obj CodeList DataList / )
; Sets XRecordData. Dxf numbers between 1-369, except 5, 100, 105.
; See help for types and numbers to use.

(vla-SetXRecordData Obj
(vlax-make-variant
  (vlax-safearray-fill
   (vlax-make-safearray
    vlax-vbInteger
    (cons 0 (1- (length CodeList)))
   )
   CodeList
  )
)
(vlax-make-variant
  (vlax-safearray-fill
   (vlax-make-safearray
    vlax-vbVariant
    (cons 0 (1- (length Datalist)))
   )
   DataList
  )
)
)
)
;-----------------------------------------------------------------------------
(defun MyGetXRec (Obj / CodeType DataType)
; Retrive XRecordData for an object

(vla-GetXRecordData
Obj
'CodeType
'DataType
)
(if (and CodeType DataType)
(mapcar
  '(lambda (a b)
   (cons a (variant-value b))
  )
  (safearray-value CodeType)
  (safearray-value DataType)
)
)
)
;-------------------------------------------------------------------------------------
(defun AssociatedReactors (Obj / ReactList)
; Return a list of reactors (object type) associated with an object.
; Use like (AssociatedReactors (vlax-ename->vla-object (car (entsel))))

(foreach i (cdar (vlr-reactors :vlr-object-reactor))
(if (vl-position Obj (vlr-owners i))
  (setq ReactList (cons i ReactList))
)
)
ReactList
)
;---------------------------------------------------------------------------
(defun RemovePersReact ()
; Remove persistant reactors that don't have an owner.

(foreach i (vlr-pers-list)
(if (not (vlr-owners i))
  (progn
   (vlr-pers-release i)
   (vlr-remove i)
  )
)
)
)

LE

  • Guest
Re: Reactor question
« Reply #35 on: February 15, 2006, 04:57:41 PM »
and without a fancy loading system... simple place:

(LOAD "AREAREACT.LSP" NIL)

in your acad.mnl.... and rock & roll....

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Reactor question
« Reply #36 on: February 15, 2006, 05:15:47 PM »
Thanks Luis.  I will have to look into these issues later, real work has happened again.  I can't tell you how much I appreciate you taking the time to look over this stuff.

Gary here is a quick routine I wrote before lunch.  It woked on my test, but only with lwpolylines.
Code: [Select]
(defun c:AddVertex (/ Sel Pt Obj CoordList cnt ParmPt cnt2 Ang tmpPt1 tmpPt2)

(if
 (and
  (setq Sel (entsel "\n Select polyline near where new vertex will be added: "))
  (= (cdr (assoc 0 (entget (car Sel)))) "LWPOLYLINE")
  (setq Pt (vlax-curve-getClosestPointTo (car Sel) (cadr Sel)))
  (setq Obj (vlax-ename->vla-object (car Sel)))
  (setq CoordList (vlax-get Obj 'Coordinates))
 )
 (progn
  (setq cnt 0)
  (setq ParmPt 1)
  (while (< (1+ cnt) (length CoordList))
   (setq cnt2
    (if (>= (setq cnt2 (+ 2 cnt)) (length CoordList))
     (- cnt2 (length CoordList))
     cnt2
    )
   )
   (setq Ang
    (angle
     (setq tmpPt1
      (list
       (nth cnt CoordList)
       (nth (1+ cnt) CoordList)
      )
     )
     (setq tmpPt2
      (list
       (nth cnt2 CoordList)
       (nth (1+ cnt2) CoordList)
      )
     )
    )
   )
   (if
    (or
     (equal (angle Pt tmpPt1) Ang 0.000001)
     (equal (angle Pt tmpPt2) Ang 0.000001)
    )
    (setq cnt (length CoordList))
    (progn
     (setq ParmPt (1+ ParmPt))
     (setq cnt (+ 2 cnt))
    )
   )
  )
  (vlax-invoke Obj 'AddVertex ParmPt (list (car Pt) (cadr Pt)))
 )
)
(princ)
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Reactor question
« Reply #37 on: February 15, 2006, 05:29:33 PM »
Tim

Thanks, it will replace my old routine for sure now. It works with both routines (yours and mine). I will soon have
a standalone dialog based routine that will have my collection of area routines. I tend to like dialog boxes, because
they give you more control of the routine. Thanks again. Like I keep saying I'm going to learn this vlisp stuff.
I can't imagine what Luis is up against with the c++ arx stuff.

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

LE

  • Guest
Re: Reactor question
« Reply #38 on: February 15, 2006, 05:35:26 PM »
. Like I keep saying I'm going to learn this vlisp stuff.
I can't imagine what Luis is up against with the c++ arx stuff.

Amigos;

Nothing against to LISP/VLISP ... I am just saying that in there anyone can do whatever they want, there is no control, no methodology, nothing, niep, nada, nil.... That is good an bad....

That's all...  :mrgreen:

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Reactor question
« Reply #39 on: February 15, 2006, 05:38:28 PM »
I'm glad that people find it useful.  That is one of the best feelings about programming.  Will post the finished version here, after I make the corrections per Luis's instructions in the last few posts.
I can't imagine what Luis is up against with the c++ arx stuff.

Gary
Me either, but I'm sure it will be very cool, and very productive.

Amigos;

Nothing against to LISP/VLISP ... I am just saying that in there anyone can do whatever they want, there is no control, no methodology, nothing, niep, nada, nil.... That is good an bad....

That's all...  :mrgreen:
I think he was saying more that what you do is going to be awesome because that language is so powerful compared to lisp/vlisp and that will be cool to see where you can take it and cad.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Reactor question
« Reply #40 on: February 15, 2006, 05:44:59 PM »
Yes, everything I see from Luis has been awesome. I welcome his feedback and look forward to seeing what he comes up next.

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

LE

  • Guest
Re: Reactor question
« Reply #41 on: February 15, 2006, 05:54:49 PM »
Thanks for the cheers.... there are others out there more capable.... glad I'm still of use in here....

Have fun amigos.

zoltan

  • Guest
Re: Reactor question
« Reply #42 on: February 15, 2006, 06:49:57 PM »
Code: [Select]
:vlr-unerased ...

You do not need that.

The :vlr-Erased callback should not remove the reactor with (vlr-remove) because then if someone erases it and later brings it back with the OOPS or Undo command, the reactor will be gone and nothing will react to the :vlr-UnErased event.  Instead you want the :vlr-Erased callback to remove the persistance and the :vlr-UnErased callback to put it back. if somone erases the object, the reactor will just hang around waiting for the object to get unerased.  If it is never unerased, the non-persistant reactor will die when the drawing is closed.

LE

  • Guest
Re: Reactor question
« Reply #43 on: February 15, 2006, 07:15:06 PM »
The :vlr-Erased callback should not remove the reactor with (vlr-remove) because then if someone erases it and later brings it back with the OOPS or Undo command, the reactor will be gone and nothing will react to the :vlr-UnErased event.  Instead you want the :vlr-Erased callback to remove the persistance and the :vlr-UnErased callback to put it back. if somone erases the object, the reactor will just hang around waiting for the object to get unerased.  If it is never unerased, the non-persistant reactor will die when the drawing is closed.

Have you tested the latest routine yet?

I did exactly what you are mentioned in my early routines with reactors... One of the concerns to find an easier way to solve and get the UNDO mechanism without the use of the unerased event, was to use what I posted.

Mostly because, when you have a routine with reactors to run several times, basically a VLISP programmer would tend to create every time a new reactor per each call, in this case it is just a single object[owner]... what would happen if they were 4,5,6,10...

So, I end up killing the reactor in the erased event... and not worried of having any problems, if I not end up using the unerased....

The last routines I did with object reactors basically I simple implement a "reactor per object", in example if one routine was using four objects, and the user call it 100 times, the routine only was using 4 reactors, instead of 400 per say....

Have fun.
« Last Edit: February 15, 2006, 07:23:06 PM by LE »

LE

  • Guest
Re: Reactor question
« Reply #44 on: February 15, 2006, 07:19:57 PM »
To keep adding to this, routines with visual lisp reactors must be used with care, not everything can be done by implementing them... I wrote a lot on reactors since the first time they came up on vital lisp... today I do not use a single one....