TheSwamp

Code Red => .NET => Topic started by: Jeff_M on January 10, 2019, 11:35:28 AM

Title: Using 1 entity to control another?
Post by: Jeff_M on January 10, 2019, 11:35:28 AM
Say I have a line and an arc. I want the line's length controlled by the arc's length. But, the arc is a hidden, not visible, object. So when the line is selected I want the grips for the arc to be displayed, and dragable, along with the line's grips. However, I do not want the implied selection set to be modified by just adding the arc to it. Is this even possible?

What I'm actually working with are an arc and a Civil3D curve label for that arc. It's the arc I want to be not visible, but it needs to be available for editing when the label is selected. I thought the line/arc would be simpler to explain... I have tried using the ImpledSelectionChanged event, checking for the Xdata I've added to the label, and adding the arc to the ImpliedSelectionSet if such a label is found. This actually works as I had hoped, except it breaks the normal C3D editing of labels which are in an ImpliedSelectionSet.

I've also tried to get the arc grip points and add those to the Label Grip points. This, so far, has resulted in lots of Fatal Errors so I changed it to the ImpliedSelectionChanged option. I would rather get this working, but am out of ideas. If I could get an example for the line/arc scenario, I'm sure I could adapt it for use with the label/arc.

 
Title: Re: Using 1 entity to control another?
Post by: Jeff_M on January 13, 2019, 07:20:00 PM
Lots of views so I guess there's some interest in this. I've worked through a lot of this and have it working much as I had hoped for in a small sample class, which attached (developed using AutoCAD 2018, should work with any version 2010+). There are still 2 things that I'm struggling with.

The first, and it isn't a show stopper, is that I cannot get the arc to update as the grip is being dragged.

The second, and may be a show stopper, is that there are MANY entries added to the Undo stack. I've tried to use normal Transactions, OpenClose Transactions, no Transactions. All seem to leave the same number of Undo entries. I do not like this at all and am not seeing what I'm doing to cause all of these to be added.

Any help with either of these would be much appreciated. Here is a short video showing the sample tool in action.

https://www.screencast.com/t/CCDrzlHjonrI

Title: Re: Using 1 entity to control another?
Post by: Atook on January 13, 2019, 08:51:08 PM
Lots of views so I guess there's some interest in this...Here is a short video showing the sample tool in action.

https://www.screencast.com/t/CCDrzlHjonrI

Hey Jeff, I'm curious to see what you're trying to accomplish. The idea does seem like it could be very useful.

Any chance you can post a gif or a non-flash link to the video?
Title: Re: Using 1 entity to control another?
Post by: Jeff_M on January 14, 2019, 11:11:30 AM
Here's a GIF created from the swf file. It starts slow, as I wasn't aware that it started recording.
Title: Re: Using 1 entity to control another?
Post by: Atook on January 14, 2019, 01:17:20 PM
That is a cool implementation.

The idea of tying a visible object to an invisible one is interesting. How does the line know which invisible arc is it's parent? I'm currently tying two visible objects together by writing the handle of one as xdata on the other. That works as long as the user doesn't copy or pasteclip them.

As far as multiple undos, have you tried creating one transaction to start, and passing it to whatever functions need to be called?

Edit: I'd suggest a dynamic block, but I assume that's out since you're hoping to apply this to Civil3d objects.

Also, I just realized you posted code to read. Apologies for any silly questions answered in the code.
Title: Re: Using 1 entity to control another?
Post by: Jeff_M on January 14, 2019, 04:38:38 PM
I save the Handle of each object in the other's Xdata so there's a link between them. Although, since the arc is invisible it is not selectable with normal selections (it can be obtained in code, but most users wouldn't have a need for that) it really doesn't need to know about the line. Selecting the line shows the grips where the arc grips would be (those are not the arc's actual grips) and then the arc is recalculated based on the movement of the grip. You will see in the code that if the line is erased I also erase the invisible arc so it's not left behind to pollute the drawing.

As for the copy issue, for the final version of this with the C3D labels, they cannot be copied anyway so I shouldn't have any problems with that.

The GripOverrule has the GetGripPoints and MoveGripPoints methods which are connected with the selection of the Line which, by default, is opened by Autocad for write. However, to work with the Arc, it must be opened for write in both of those methods in order show it and then modify it. These methods fire multiple times during a grip edit. I just made 1 edit to the arc in a test and there were 76 undo entries added for that 1 edit. That is about 75 too many. :-)
Title: Re: Using 1 entity to control another?
Post by: Jeff_M on January 17, 2019, 03:55:29 PM
I ended up posting this over on the Autodesk .NET forum. Virupaksha Aithal suggested that the culprit of the multiple Undo entries was likely the Open.ForWrite call on the arc in the GetGripPoints. Sure enough, changing that to ForRead, and moving the 2 calls to modify the display of the arc to the MoveGripPointsAt method solved the Undo issue. Here's the final result for the intended application.
 
Title: Re: Using 1 entity to control another?
Post by: kdub_nz on January 17, 2019, 05:09:55 PM

Well done Jeff.
Title: Re: Using 1 entity to control another?
Post by: MP on January 17, 2019, 08:11:32 PM
Well done Jeff.

x 2!!
Title: Re: Using 1 entity to control another?
Post by: Atook on January 17, 2019, 09:35:31 PM
Wow Jeff, that looks great! Looks like a great UI enhancement.

...likely the Open.ForWrite call on the arc in the GetGripPoints. Sure enough, changing that to ForRead, and moving the 2 calls to modify the display of the arc to the MoveGripPointsAt method solved the Undo issue...

Were these changes to  Arc.GetGripPoints.OpenForWrite done via the overrule, an extension or some other kind of override?
Title: Re: Using 1 entity to control another?
Post by: MickD on January 17, 2019, 10:43:13 PM
Well done Jeff.

x 2!!

x3!!!
Title: Re: Using 1 entity to control another?
Post by: Jeff H on January 18, 2019, 12:57:32 AM
Well done Jeff.

x 2!!

x3!!!
Thanks guy, will keep making you proud.
Title: Re: Using 1 entity to control another?
Post by: Jeff_M on January 18, 2019, 09:52:23 AM

Were these changes to  Arc.GetGripPoints.OpenForWrite done via the overrule, an extension or some other kind of override?

The overrule was changed. I've attached the modified code which also has what I tried to use as a drawable overrule to show a temp. arc instead of making the actual arc visible.
Title: Re: Using 1 entity to control another?
Post by: Jeff_M on January 18, 2019, 09:53:09 AM
Thanks guys! I definitely learned a bit while getting this to work.