.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Adding code generated entities to a selection set

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
Anonymous
3915 Views, 9 Replies

Adding code generated entities to a selection set

I am slowly trying to get to grips with VB.NET, after a good few years of messing around with VBA.

I’m currently writing some code to try to improve CAD’s MEASURE command, but I’ve hit a bit of a stumbling block.

I have my command working to the extent that it will place blocks at regular intervals along a polyline, but I would like to add the generated blocks to a selection set, so you can use “previous” to select them like you can with CAD’s  MEASURE command.

 

e.g. If I used the MEASURE  command in CAD to place blocks along a polyline, then wanted to explode the blocks directly after, I could just use:

EXPLODE <ENTER>

P <ENTER>

to explode the previous selection set, but my code never adds the blocks to a selection set – so you have to select them manually.

 

To add an entity to a selection set in VBA you would do something like this (excuse the pseudo-code):

 

Dim Ent as Entity

Ent = (whatever)

 

Dim SS as SelectionSet

SS.Add(Ent)

 

VB.NET doesn’t seem to have an Add method for selection sets though, as far as I can gather you can only get them by using SelectAll & a dxf code filter – which would just grab all instances of the block, unless I went down the route of adding a temporary unique layer for them, or something along those lines.

 

Am I missing something obvious here?

 

Thanks in advance,

Will

 

9 REPLIES 9
Message 2 of 10
Anonymous
in reply to: Anonymous

Ah, this is interesting for me as well.

I was in the similar situation of removing entities from a selectionset, and it was a pain converting the SS to an array and messing with that and going back to the selection....didn't find an easy way of dealing with that.

 

Is anybody more wise than we are?

Message 3 of 10
Hallex
in reply to: Anonymous

Take a look at SetImpliedSelection method of document Editor

Here is Q&D example:

 

        static public void AddItemsExm()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            Database db = HostApplicationServices.WorkingDatabase;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                    SelectionFilter sf = new SelectionFilter(

                     new TypedValue[] { new TypedValue(0, "LINE") });

                    PromptSelectionOptions pso = new PromptSelectionOptions();

                    pso.MessageForAdding = "\nSelect lines only >>";

                    pso.SingleOnly = false;

                    PromptSelectionResult res = ed.GetSelection(pso, sf);

                    if (res.Status != PromptStatus.OK)

                        return;

                    SelectionSet main = res.Value;

                    ObjectId[] oids = main.GetObjectIds();

                    ed.WriteMessage("\nSelected {0} objects", oids.Length);

                    Line ln = new Line(new Point3d(0, 0, 0), new Point3d(0, 1000, 0));//dummy line for test


                    btr.AppendEntity(ln);

                    tr.AddNewlyCreatedDBObject(ln, true);

                    int cnt = oids.Length;

                    Array.Resize(ref oids, cnt + 1);

                    oids[cnt] = ln.ObjectId;

                    SelectionSet newset = SelectionSet.FromObjectIds(oids);

                    main = null;

                    ed.SetImpliedSelection(newset);

                    ed.WriteMessage("\nAfter adding line: {0} objects", newset.GetObjectIds().Length);

                    foreach (SelectedObject obj in newset)
                    {
                        Entity en = (Entity)tr.GetObject(obj.ObjectId, OpenMode.ForRead);

                        en.UpgradeOpen();

                        en.ColorIndex = 1;

                        en.DowngradeOpen();

                    }

                    tr.Commit();

                }

                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message);
                }
            }
        }

 ~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 4 of 10
LE3
Advocate
in reply to: Anonymous

Have not used it this ARX function from C# and no idea if it is available (you can have access via PInvoke), read about:

 

acedGetCurrentSelectionSet();

 

In the SDK Arx docs.

Message 5 of 10
Anonymous
in reply to: Hallex

Thanks Hallex, I think this is what I'm looking for:

 

                    SelectionSet newset = SelectionSet.FromObjectIds(oids);

                    ed.SetImpliedSelection(newset); 

 I'll give it a try later and see if it does the job

Message 6 of 10
chiefbraincloud
in reply to: Anonymous

The SetImpliedSelection method is what you're after, but you don't have to create the selection set at all, because there is an overload that accepts an array of ObjectID's (at least in v.2010).  Also in order for the implied selection to remain selected after your command completes, you have to set the Redraw flag on your command method.

Dave O.                                                                  Sig-Logos32.png
Message 7 of 10
Anonymous
in reply to: Anonymous

Ok, having tried out the above, I'm much closer to where I want to be - but not quite there.

Here's my (abridged) code:

 

<CommandMethod("MB", CommandFlags.Redraw)> _
Public Sub NewMeasure()
Dim myDWG As ApplicationServices.Document = ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim myEd As EditorInput.Editor = myDWG.Editor


Dim MeasureObjects As DBObjectcollection = CreateObjects


Dim SelSet As SelectionSet = AddToSelectionSet(MeasureObjects)
myEd.SetImpliedSelection(SelSet)
End Sub

Function AddToSelectionSet(ByVal Objects As DBObjectCollection) As SelectionSet
Dim ObjectIDs(0 To (Objects.Count - 1)) As ObjectId
Dim ThisObjectID As ObjectId
Dim Obj As DBObject
For i As Integer = 0 To (Objects.Count - 1)
Obj = Objects(i)
ThisObjectID = Obj.ObjectId
ObjectIDs(i) = ThisObjectID
Next
Dim SelSet As SelectionSet = SelectionSet.FromObjectIds(ObjectIDs)
Return SelSet
End Function

 

Once the code has been run, the blocks remain selected (with or without the CommandFlags.Redraw flag) - but "no previous selection set exists" once they have been de-selected.

Ideally I want nothing selected after running the command, but having the objects available as the previous selection set.

Any suggestions?

 

 

 

Message 8 of 10
chiefbraincloud
in reply to: Anonymous


@Anonymous wrote:

Once the code has been run, the blocks remain selected (with or without the CommandFlags.Redraw flag) - but "no previous selection set exists" once they have been de-selected.

 

Ideally I want nothing selected after running the command, but having the objects available as the previous selection set.

 


 

First, "the blocks remain selected (with or without the CommandFlags.Redraw flag)"

   I don't know what version you are running, and I am on 2010 now but when I wrote the code I have (that uses or sets the Pickfirst set) I was on ACAD 2009, but in 09, the implied selection set was cleared by default if you did not declare the UsePickFirst or the Redraw command flag, and if you wanted to have selections set after your command you had to use the Redraw flag.  That might be a change in default behavior I don't know about yet in ACAD 2010, or a change in '2011 which I haven't installed yet.

 

That said, the description of behavior you describe is by (Autodesk) design, and (one) solution is simple enough.

 

Since it is the last thing you want to do, there is really no penalty to leaving your code as is (leaving the selection gripped when you are done), and calling SendStringToExecute (in the Document Object) and running the AutoCAD "Select" command. This will clear the grips (I think, I can't test right now), and create a previous Set from the implied set.

 

You should test that Count > 0 on the implied set before calling Select, because if there is no implied set, running SELECT will prompt the user for selection.

 

 

 

 

Dave O.                                                                  Sig-Logos32.png
Message 9 of 10
Anonymous
in reply to: Anonymous

The 'Previous' and 'Pickfirst' selection sets are not one and the same.

The former is the objects most recently selected by the user, and the

latter is the currently-selected objects.

 

The only way to set the previous selection set is to issue a command

that prompts for a selection (like the SELECT command), and supply

the selection set to the command.

 

 

Message 10 of 10
Anonymous
in reply to: Anonymous

Thanks all, adding the SELECT command on the end did the trick perfectly!

Here's the code I used:

 

 

<CommandMethod("MB", CommandFlags.Redraw)> _
Public Sub NewMeasure()
     Dim myDWG As ApplicationServices.Document =  ApplicationServices.Application.DocumentManager.MdiActiveDocument
     Dim myEd As EditorInput.Editor = myDWG.Editor

		
     Dim MeasureObjects As DBObjectcollection = CreateObjects 

     If MeasureObjects.Count > 0 Then
         Dim SelSet As SelectionSet = AddToSelectionSet(MeasureObjects)
         myEd.SetImpliedSelection(SelSet)
         myDWG.SendStringToExecute("SELECT ", False, False, False)
     End If
End Sub

 Many thanks,

Will

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost