Jump to content

Advice on how to use a reactor to manipulate an already drawn shape


Serhan_BAKIR

Recommended Posts

Hi there,

I'm developing a custom program to draw specific shapes as shown below. I've finished the "static" part in which user basically draws a pline and program adds thickness to it and fillets corners according to the selected offset side. I'll now trying to code "dynamic" functionality: user would be able to modify the polyline (drag or add vertices). After the user modification, shape shall be recreated to match new form of the polyline. I'd like to use my algorithms in-hand for the recreation of the shape via an object reactor.

 

However "static" algorithm that I wrote is heavily dependent on native autocad commands. 

- I know that commands cannot be used inside reactor callbacks

- I know that an object reactor cannot be removed inside its own callback and there is no way for another function to follow after reactor callback execution ends.

- I know that vla-sendcommand can be used inside a reactor callback but for complex commands (even for easier ones) it seems impossible to implement it.

- All of the commands I'll be using have vla-* counterparts but "fillet" doesn't have. And I'm using it with entity and point inputs.

 

My question is for you, seasoned lispers, what is your advice for me to do?

- I'm thinking of rewriting a fillet alternative without using command but geometry. (if you know that there is a pre-written such function please point me to it)

- Also I thought of creating a .net fillet function and calling it in callback but I've no clue how to write for autocad in .net and even if it will work for this case.

 

So what do you say :)

thanks in advance for your valuable inputs.

Serhan

reactor.gif

Link to comment
Share on other sites

Your approach seems right, but looking at your gif, I would probably reconsider the structure of your code.

 

If I were to design this, I would first create a function that draws the geometry and hatch. Then, when the polyline is modified and the reactor is called, delete the old geometry and redraw it with a new one by recalling the function. Based on your gif, the geometry doesn't appear too hard to draw, but the calculations can be quite difficult to work out (and even harder if you want the result as a polyline instead of single lines and arcs since you can't use JOIN). Use some of these to help you out. But just as you said, you'll have to remove all uses of command in the reactor.

 

On a side note, if you are new to creating reactors that modifies other objects prior to the vlr-modified reactor being fired, just be prepared for crashes along the way (because I've experienced heaps).

 

Another thing that might help you is that I think there might be a function somewhere out there that can generate the outline of a hatch in the form of a polyline without invoking the HATCH or HATCHGENERATEBOUNDARY commands. I've made one somewhere, but I can't remember where I saved it, so I'm going to have a look around.

Link to comment
Share on other sites

On 8/11/2023 at 4:39 PM, Jonathan Handojo said:

If I were to design this, I would first create a function that draws the geometry and hatch. Then, when the polyline is modified and the reactor is called, delete the old geometry and redraw it with a new one by recalling the function.

Thank you Jonathan Handjo, that is exactly what I'm doing. And since the primary functions to draw the shape uses "command", I couldn't use it directly inside the reactor callback function. However I found out that writing my own "filleting" function with vla-* would be a wiser choice. As a side note, I'll use OpenDCL for the project and also found out that dcl-sendstring is way easier than using vla-sendcommand. 

 

On 8/11/2023 at 4:39 PM, Jonathan Handojo said:

On a side note, if you are new to creating reactors that modifies other objects prior to the vlr-modified reactor being fired, just be prepared for crashes along the way (because I've experienced heaps).

I've worked with reactors before and know how delicate it is to use them. But I'll be glad if you can elaborate more on the crash handling experiences of yours and also keeping reactor to run more than once.

Link to comment
Share on other sites

On 8/12/2023 at 8:21 AM, BIGAL said:

Sometimes it is much easier to select a shape say L V X ^ from a list of shapes or images in a dcl etc, then apply some values to it and draw.

Thanks but I'm afraid I can not restrict the shapes with predefined variables since they would be highly free-forms.

Link to comment
Share on other sites

On 8/16/2023 at 6:57 AM, Serhan_BAKIR said:

I've worked with reactors before and know how delicate it is to use them. But I'll be glad if you can elaborate more on the crash handling experiences of yours and also keeping reactor to run more than once.

Given your experience, I'm sure you know that reactors can be triggered consecutively. But it's more that, let's say when talking out of this reactor, you press Ctrl Z to undo something. But technically, that also fires vlr-modified reactors, in which objects cannot be modified when Undo is active. This is just from my AutoCAD, but if this is repeatedly triggered, some sort of "Access Violation" stuff can happen... so it just comes down to how you code it, I suppose?

Link to comment
Share on other sites

11 hours ago, Jonathan Handojo said:

Given your experience, I'm sure you know that reactors can be triggered consecutively. But it's more that, let's say when talking out of this reactor, you press Ctrl Z to undo something. But technically, that also fires vlr-modified reactors, in which objects cannot be modified when Undo is active. This is just from my AutoCAD, but if this is repeatedly triggered, some sort of "Access Violation" stuff can happen... so it just comes down to how you code it, I suppose?

 

Yes that's one point I always check for interference at the very beginning of the callback;

(cond
       ((and (not (= (getvar "cmdnames") "UNDO")) 
             (not (= (getvar "cmdnames") "REDO"))
             (not (= (getvar "cmdnames") "U"))
             (not (= (getvar "cmdnames") "CHPROP")) 
             ...

 

also try to prevent interference of other lisp functions by removing and adding the reactors 

  (setq lispended_reactor (vlr-lisp-reactor nil '((:vlr-lispEnded . add_reactor))))
  (setq lispstart_reactor (vlr-lisp-reactor nil '((:vlr-lispWillStart . rem_reactor))))

 

But couldn't find a bullet proof method for every case and some times even simple reactors may crash autocad completely. 

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...