Help with Reactor

Help with Reactor

ArchD
Collaborator Collaborator
1,726 Views
15 Replies
Message 1 of 16

Help with Reactor

ArchD
Collaborator
Collaborator

I am trying to create a reactor that watches xrefs being attached. When one is attached, it looks for a layer that is thawed. If so, then set some other layers to certain settings. I can get the reactor to notice the layer, but I cannot figure out how to detect the layer and execute the layer settings if the detected layer is thawed.

 

Also, I can't get the layer settings to work. When I plug that part into my reactor it says "; error: AutoCAD command rejected: "CPHCurbCallouts"". 

 

So this is the reactor I have at the moment.

 

(vl-load-com)

(or acDoc (setq acDoc (vla-get-activedocument (vlax-get-acad-object))))
;;;--------------------------------------------------------------------;
;;; Reactors:Start function
(defun Reactors:Start  ()

  ;; Command reactors
  (or *Reactors_Command*
      (setq *Reactors_Command*
             (vlr-xref-reactor
               nil
               '((:VLR-endAttach . Callback:XRefCurbLayerDetected)
                 (:VLR-endRestore . Callback:XRefCurbLayerDetected)))))
  (princ))
  
  
;;;--------------------------------------------------------------------;
;;; Callback:XRefAttached function
(defun Callback:XRefCurbLayerDetected  (rea cmd / cmdName n CurNOMUTT CurCMDEcho)
  (vlax-for l (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
    (if
		(wcmatch (setq n (strcase (vla-get-name l))) "*X_TEXT_GROUPED_CURB_LABEL")
		(command "CPHCurbCallouts")))
  (princ)
)
(princ)



;;;--------------------------------------------------------------------;
(Reactors:Start)
(princ)

 

This is the CPHCurbCallouts function that is always loaded and ready to go:

 

(defun c:CPHCurbCallouts  (/ CurNOMUTT CurCMDEcho)
	(setq CurNOMUTT (getvar "nomutt"))
	(setq CurCMDEcho (getvar "cmdecho"))
	(setvar "nomutt" 0)
	(setvar "cmdecho" 0)
	(command "-layer" "T" "*X_POINTS_TOPO_EOP,*X_POINTS_TOPO_EOP_FREEZE,*X_POINTS_TOPO_CONCRETE,*X_POINTS_TOPO_CONCRETE_FREEZE,*X_POINTS_TOPO_BOC,*X_POINTS_TOPO_BOC_FREEZE,*X_POINTS_TOPO_FLOWLINE,*X_POINTS_TOPO_FLOWLINE_FREEZE" "F" "*GROUPED_CURB_LABEL" "")
	(command "regenall")
	(setvar "nomutt" CurNOMUTT)
	(setvar "cmdecho" CurCMDEcho)
	(print "All curb callouts are now shown.")
	(princ)
)

 

Any help would be very much appreciated.

Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes
Accepted solutions (2)
1,727 Views
15 Replies
Replies (15)
Message 2 of 16

roland.r71
Collaborator
Collaborator

@ArchD wrote:

 

Instead of (print "layers detected") I would like it to do do this function:

 

(defun c:CPHCurbCallouts  (/ CurNOMUTT CurCMDEcho)
	(setq CurNOMUTT (getvar "nomutt"))
	(setq CurCMDEcho (getvar "cmdecho"))
	(setvar "nomutt" 0)
	(setvar "cmdecho" 0)
	(command "-layer" "T" "*X_POINTS_TOPO_EOP,*X_POINTS_TOPO_EOP_FREEZE,*X_POINTS_TOPO_CONCRETE,*X_POINTS_TOPO_CONCRETE_FREEZE,*X_POINTS_TOPO_BOC,*X_POINTS_TOPO_BOC_FREEZE,*X_POINTS_TOPO_FLOWLINE,*X_POINTS_TOPO_FLOWLINE_FREEZE" "F" "*GROUPED_CURB_LABEL" "")
	(command "regenall")
	(setvar "nomutt" CurNOMUTT)
	(setvar "cmdecho" CurCMDEcho)
	(print "All curb callouts are now shown.")
	(princ)
)

This function is loaded already, so the reactor could invoke that function instead of adding all of this code to it I would imagine. I tried to do this, but it would give me that CPHCurbCallouts command error similar to the layer error. I believe it has something to do with mixing ActiveX and basic AutoLisp?

 

Any help would be very much appreciated.



You can not use ( command "") inside reactors, afaik.

0 Likes
Message 3 of 16

john.uhden
Mentor
Mentor

I don't think you can use the command function within a reactor.  But that's okay, just use Visual Lisp instead...

 

(vlax-for layer (vlax-get acDoc 'Layers)

  (if (wcmatch (strcase (vlax-get layer 'Name)) "*X_POINTS_TOPO_EOP,*X_POINTS_,etc")

    ;; do your thing without using (command ...)

  )

)

John F. Uhden

Message 4 of 16

ArchD
Collaborator
Collaborator

Going to see what I can do with my limited coding ability, but I believe this has steered me in the right direction. Thanks.

Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes
Message 5 of 16

roland.r71
Collaborator
Collaborator

A word of warning! Did you notice how I used ActiveX statements and functions to "Save" and "SaveAs". You cannot use interactive functions from within a reactor as AutoCAD may still be processing a command at the time the event is triggered. Therefore, avoid the use of input-acquisition methods such as getPoint, ensel, and getkword, as well as "selection set" operations and the command function.

 

http://www.afralisp.net/visual-lisp/tutorials/reactors-part-2.php

0 Likes
Message 6 of 16

Ranjit_Singh
Advisor
Advisor
Accepted solution

See if the below change works. Good luck.

(setq adoc (vla-get-activedocument (vlax-get-acad-object)))
(defun reactors:start  ()
  (foreach i  (cdar (vlr-reactors :vlr-xref-reactor))
    (if (= (vlr-data i) "_xref_reactor_")
      (vlr-remove i)))
  (vlr-xref-reactor "_xref_reactor_"
                    '((:vlr-endattach . callback:xrefcurblayerdetected)
                      (:vlr-endrestore . callback:xrefcurblayerdetected)))
  (princ))
(defun callback:xrefcurblayerdetected  (rea cmd / cmdname n curnomutt curcmdecho)
  (vlax-for l  (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
    (if (wcmatch (setq n (strcase (vla-get-name l))) "*X_TEXT_GROUPED_CURB_LABEL")
      (c:cphcurbcallouts)))
  (vla-regen adoc acallviewports)
  (princ))
(reactors:start)
(defun c:cphcurbcallouts  (/ curcmdecho curnomutt)
  (setq curnomutt (getvar "nomutt"))
  (setq curcmdecho (getvar "cmdecho"))
  (setvar "nomutt" 0)
  (setvar "cmdecho" 0)
  (vlax-for i  (vla-get-layers adoc)
    (cond
      ((wcmatch
         (strcase (vla-get-name i))
         "*X_POINTS_TOPO_EOP,*X_POINTS_TOPO_EOP_FREEZE,*X_POINTS_TOPO_CONCRETE,*X_POINTS_TOPO_CONCRETE_FREEZE,*X_POINTS_TOPO_BOC,*X_POINTS_TOPO_BOC_FREEZE,*X_POINTS_TOPO_FLOWLINE,*X_POINTS_TOPO_FLOWLINE_FREEZE")
       (vla-put-freeze i :vlax-false))
      ((wcmatch (strcase (vla-get-name i)) "*GROUPED_CURB_LABEL") (vla-put-freeze i :vlax-true))
      (t ())))
  (setvar "nomutt" curnomutt)
  (setvar "cmdecho" curcmdecho)
  (print "\All curb callouts are now shown.")
  (princ))

 

 

Message 7 of 16

ArchD
Collaborator
Collaborator

Wow, this is pretty much exactly what I need. The only thing missing is for it to check to if "*X_TEXT_GROUPED_CURB_LABEL" is frozen. If frozen, do nothing.

 

Ranjit, you always do more than you need to. I really appreciate you being on the forums.

Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes
Message 8 of 16

Ranjit_Singh
Advisor
Advisor
Accepted solution

No worries. Most of us are here, because we enjoy being here.

Try changing

 (wcmatch (setq n (strcase (vla-get-name l))) "*X_TEXT_GROUPED_CURB_LABEL")

to

(and (wcmatch (setq n (strcase (vla-get-name l))) "*X_TEXT_GROUPED_CURB_LABEL")
             (= :vlax-false (vla-get-freeze l)))

 I also don't see any need for that n variable in there. I'd get rid of it.

Message 9 of 16

ArchD
Collaborator
Collaborator

Once again you have helped me out. This is going to come in so handy at my office. I'd like to buy you a drink.

Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes
Message 10 of 16

john.uhden
Mentor
Mentor

@ArchD wrote to @Ranjit_Singh, "I'd like to buy you a drink."

 

I think he's in the Seattle area, still painting his house.  He's probably quite thirsty by now.

John F. Uhden

0 Likes
Message 11 of 16

Ranjit_Singh
Advisor
Advisor

@john.uhden wrote:

@ArchD wrote to @Ranjit_Singh, "I'd like to buy you a drink."

 

I think he's in the Seattle area, still painting his house.  He's probably quite thirsty by now.


I am in the so. cal region.

But @john.uhden is correct. I will take paint brushes anytime over drink Smiley LOL I still have most of the upstairs left before I can finish the job.

0 Likes
Message 12 of 16

ArchD
Collaborator
Collaborator

After attaching an xref and it does it's thing as expected, it finishes up with "Press ENTER to continue:" on the command line although it's done with the command. Pressing enter restarts an attachment.

 

I'm serious though, let me know where to donate and I'll be happy to. You've helped me out so many times I feel obliged.

Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes
Message 13 of 16

Ranjit_Singh
Advisor
Advisor

@ArchD wrote:

........After attaching an xref and it does it's thing as expected, it finishes up with "Press ENTER to continue:"............


Maybe post a sample drawing and an xref dwg as well. I tested with a sample drawing and it worked. But I might be missing some thing.Reactor_Help.gif

0 Likes
Message 14 of 16

ArchD
Collaborator
Collaborator

That's odd. I checked with others to make sure it wasn't just me and they get it also. I've attached a simplified version of a survey that our survey department loves using with these hideous labels so our civil/landscape department swaps them back to three spot shots instead. This reactor basically handles that conversion when we attach their survey into our drawings.

 

I made very minor changes to the code that you posted, mainly removing the printout telling them that all curb shots are shown and moving the  (vla-regen adoc acallviewports) from the reactor to the cphcurbcallouts function because this function is one of three similar functions that we use and all three need to be regenerated.

 

Below is my modifications:

 

 

(defun reactors:start  ()
	(foreach i (cdar (vlr-reactors :vlr-xref-reactor))
		(if (= (vlr-data i) "_xref_reactor_")
		(vlr-remove i)))
	(vlr-xref-reactor "_xref_reactor_"
		'((:vlr-endattach . callback:XREFCurbLabelDetected)
	(:vlr-endrestore . callback:XREFCurbLabelDetected)))
	(princ))
	
(defun callback:XREFCurbLabelDetected  (rea cmd / cmdname curnomutt curcmdecho)
	(vlax-for l (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
		(if
			(and
				(wcmatch (strcase (vla-get-name l)) "*X_TEXT_GROUPED_CURB_LABEL")
				(= :vlax-false (vla-get-freeze l)))
				(c:cphcurbcallouts)))
	(princ))
	
(reactors:start)
(setq adoc (vla-get-activedocument (vlax-get-acad-object)))

(defun c:CPHcurbcallouts (/ curcmdecho curnomutt) (setq curnomutt (getvar "nomutt")) (setq curcmdecho (getvar "cmdecho")) (setvar "nomutt" 0) (setvar "cmdecho" 0) (vlax-for i (vla-get-layers adoc) (cond ((wcmatch (strcase (vla-get-name i)) "*X_POINTS_TOPO_EOP,*X_POINTS_TOPO_EOP_FREEZE,*X_POINTS_TOPO_CONCRETE,*X_POINTS_TOPO_CONCRETE_FREEZE,*X_POINTS_TOPO_BOC,*X_POINTS_TOPO_BOC_FREEZE,*X_POINTS_TOPO_FLOWLINE,*X_POINTS_TOPO_FLOWLINE_FREEZE") (vla-put-freeze i :vlax-false)) ((wcmatch (strcase (vla-get-name i)) "*GROUPED_CURB_LABEL") (vla-put-freeze i :vlax-true)) (t ()))) (vla-Regen adoc acAllViewports) (setvar "nomutt" curnomutt) (setvar "cmdecho" curcmdecho) (princ))
Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes
Message 15 of 16

Ranjit_Singh
Advisor
Advisor

Something is going on with that particular xref. Try some other drawings and see if you get the same issue. Below image shows how simply opening the XREF.dwg drawing (not attaching as XREF) displays that message. I only get that message when opening the XREF.dwg file and not when opening the HOST.dwg file.Press_Enter.gif

Message 16 of 16

ArchD
Collaborator
Collaborator

Ah, I didn't catch that. Weird, not sure why that is doing that but at least the reactor is working! Thanks man, much appreciated once again.

Archie Dodge
Applications Expert - Infrastructure Solutions Division
IMAGINiT Technologies
0 Likes