Convert Selection Set's Vla Object to Ordinary Selection Set

Convert Selection Set's Vla Object to Ordinary Selection Set

serag.hassouna
Advocate Advocate
5,011 Views
11 Replies
Message 1 of 12

Convert Selection Set's Vla Object to Ordinary Selection Set

serag.hassouna
Advocate
Advocate

I have a selection set created from VBA, e.g named "MySSet" and resides in the Selection Sets collection.

To retrieve its vla object I use this

(vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet")

The results looks like this

#<VLA-OBJECT IAcadSelectionSet 00000208a6d28c28>

however, when using vlax-vla-object->ename on the vla object I got "nil" as a result, though the intended result should look like this

<Selection set: 1408>

I've searched for any lisp function through documentation & searching but with no clue.
____________
Are both of them

  1. Ordinary Selection Sets (created from ssget)
  2. Activex Selection Sets

similar in nature & separated from each other ?

0 Likes
Accepted solutions (1)
5,012 Views
11 Replies
Replies (11)
Message 2 of 12

roland.r71
Collaborator
Collaborator

Now I must admit VLA mostly still eludes me (& I can get stuff done without, so too lazy to learn)

But let me try and get this straight:

You have a VLA object, containing a selection set.

Then you use "ename" on the object & expect it to return the selection set identifier ?

 

But isn't ename just to get the entity name from a VLA entity object, which happens to be a member of the selection set, one level down?

 

i.e. should you not retrieve an entity object first, before using ename on it?

Just as one would with autolisp & ssget. retrieving the ename won't work on the result to get <selection set: 1>

It will work on any member of the selection set, like: (setq ename (ssname ss i))

0 Likes
Message 3 of 12

serag.hassouna
Advocate
Advocate

@roland.r71 wrote:
...

 

But isn't ename just to get the entity name from a VLA entity object, which happens to be a member of the selection set, one level down?

 

i.e. should you not retrieve an entity object first, before using ename on it?

...

 


 

Got it, but in my case I'm not asking about how to process every primary object one by one by their entity names, what I need is a simple conversion (If it's possible).
In other words, vlax-vla-object->ename was a failed trial.
__________
What I do ask for is a function e.g somefunc that converts vla-object (that points to a selection set) to its corespondent selection set.

(somefunc (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet"))

If there's really a function that can do that, it will be a good help, otherwise, I'll continue trials about how to use Ordinary Selection Sets with VBA & hence, both selection set types will be considered seprated from each others.

0 Likes
Message 4 of 12

doaiena
Collaborator
Collaborator

If i understood you right, this is what you are after.

(defun vlaSel->Sel ( vlaSel / sel )

(setq sel (ssadd))
(vlax-for obj vlaSel
(ssadd (vlax-vla-object->ename obj) sel)
)
sel
)
_$ (vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet"))
<Selection set: 57>
_$ 
0 Likes
Message 5 of 12

serag.hassouna
Advocate
Advocate

Sadly No, though vlaSel->Sel  gives an "equivalent" result for small number of selection sets.

That's because this function creates another selection set (with ssadd) that holds the same elements of the original ActiveX selection set (referred by the vla-object).
________
However, this works great if we didn't exceed the allowed limit of selection set creation within the drawing.
In other words, the documentation says that it's allowed to create 128 selection set within any drawing, so, vlaSel->Sel will work fine for a number of times = (128 - no of existing selection sets).
_______
I've implemented this function within my VBA code, which deals with a test drawing that has only one selection set, and it works fine.
And to check the validity of it, I've applied the function twice with the same vla-object, the results were 2 different selection sets, though the ideal results should be the same with every time the function is applied.

e.g.

(vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet"))
<Selection set: 1542>
(vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet")) <Selection set: 154d>


_____
We already know that vlax-vla-object->ename works fine for a non-restricted number of times per every entity, hence,
Is there really any function that can work for a non-restricted number of times per drawing ? 
If there isn't, I shall consider vlaSel->Sel a working (but limited) solution.

0 Likes
Message 6 of 12

doaiena
Collaborator
Collaborator
Accepted solution

I think i got your idea this time. You want to reuse the same selection set multiple times instead of creating a new one each time you run the function. As you already know visual lisp selection sets are stored in a collection. As far as i am aware there is no such collection for pure autolisp. So for this to work ive created a collection (global variable) where you could store the autolisp selection sets and reuse them aswell.

 

Give this a try:

(defun vlaSel->Sel (vlaSel / selName sel)

  (setq selName (vla-get-name vlaSel))

  (if (not *SS*)
    (setq *SS* (cons (cons nil nil) *SS*))
  )

  (if (not (assoc selName *SS*))
    (progn
      (setq sel (ssadd))
      (vlax-for	obj vlaSel
	(ssadd (vlax-vla-object->ename obj) sel)
      )
      (setq *SS* (cons (cons selName (eval sel)) *SS*))
    )
  )

  (cdr (assoc selName *SS*))
) ;defun

Output:

_$ (vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet"))
<Selection set: fc>
_$ (vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet"))
<Selection set: fc>
_$ (vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) "MySSet"))
<Selection set: fc>
_$ 
Message 7 of 12

cadffm
Consultant
Consultant

@serag.hassouna

In other words, the documentation says that it's allowed to create 128 selection set within any drawing, so, vlaSel->Sel will work fine for a number of times = (128 - no of existing selection sets).


vlaSel->Sel [edit, the first version too] will works unlimited, because this function don't create 128 references to  selectionSets side by side at the same time.

The 128 limit for AutoLisp selectionSets means 128 selectionSets at the same time (bind to a symbol).

 

[new open file]


; No Problem, override 127 time one selectionSet

(progn ; Result ONE pointer to one Selectionset
  (setq n 0 sslist nil i (car(entsel)))
  (repeat 128
    (setq s1 (ssadd))
    (ssadd i ss1)
    (setq sslist (cons (setq n (1+ n)) sslist))
  )
)


; Problem, 128 selectionSets at the same time, the 129th and followings are invalid

(progn ; Result 128 pointers to 128 Selectionsets
  (setq n 0 sslist nil i (car(entsel)))
  (repeat 128
    (set (read(setq vns (strcat "s" (itoa(setq n (1+ n)))))) (ssadd))
    (ssadd i (eval(read vns)))
    (setq sslist (cons vns sslist))
  )
)


;; Resetfunction for testing: (foreach var sslist (set (read var) nil))


Do you need> 128 selection sets for your own program at the same time?
or do you have fear that in the drawing could work another strange program
with so many selectionsets at the same time, so you will get a problem with your program?

If you are looking for so many selection sets at the same time,
then you should better save the object names in lists or arrays.

Can you explain to us what causes concern, I want to understand why you are dealing/think about this limit.
(It is useful to deal with it to understand it, but an existing practice reference would be right)

thanks in advance

 

@doaiena nice

Sebastian

Message 8 of 12

serag.hassouna
Advocate
Advocate

@cadffm wrote:


or do you have fear that in the drawing could work another strange program
with so many selectionsets at the same time, so you will get a problem with your program?

 

 

This is the real reason of my concern about the limit.
The practical thing I'm working on is a VBA routine which uses an ActiveX selection set and passes an ordinary selection set (containing the same entities of the ActiveX selection set) to the "-Block" command.
And as you see, it deals with only at least 2 selection sets.
______________
However, The major fruits, represented by @doaiena's 2 functions and your test functions demonstrates that ActiveX Selection Sets and Ordinary (Pure AutoLISP) Selection Sets are different in their nature "of living".

  1. ActiveX Selection Sets are limited by it's hard-coded bondage to it's parent "SelectionSets" collection object.
    They cease to exist with the Delete method.
  2. Pure AutoLISP Selection Sets are limited by their bondage to symbols.
    They cease to exist by the assignment of nil to their bounded symbols.
    __________
    I'm really thankful for your insightful responses.
    and I hope I understood you right.
0 Likes
Message 9 of 12

dbroad
Mentor
Mentor

 

I've read through the posts so far.   As a review and addition, I will collect the ideas so far.

There is no direct conversion but the activeselection set can be used as effectively as an ordinary selection set and in some cases better.   So there is usually no need to convert if the coding is set to use the activeX selection.

 

(vlax-for n myActiveSs
  ;;do stuff or convert to enames and do stuff
)

 

You could create a new ordinary selection set from the an activeselection as below.  Your concerns are exceeding the selection set limits. That has rarely happened to me, but that shouldn't be a problem if you are either: 1)saving the ordinary selection sets in local variables or 2) saving them into a limited number of global variables. ;

 

;;given that the activeX selection is in ss
(setq ss2 (ssadd))
(vlax-for n ss
  (ssadd (vlax-vla-object-ename n) ss2)
  )
;then ss2 now holds the translated selection set.

 

 

 As @cadffm showed, as long as the same variable is used to store a selection set, you can create as many as you need.  Each selection set will have a different ename without causing an error. In the following, use the select command to select objects. Then execute.

 

(repeat 1000
  (setq ss (ssget "p")
	))

No error will be generated.

 

  In most cases, the problem with too many selection sets has to do with the propagation of too many activeX selection sets.  This generally doesn't happen because vla-get-activeselectionset seems to add only a single selection set no matter how many times it is used. The selection set it creates is always named "Current". If no selection is active, it doesn't recreate the selection set.  If objects have just been selected, then it reuses the same "CURRENT" selection set.  Only when an application uses vla-add on the selectionsets collection could activeX selections proliferate.  Even then it is required that names be unique and not empty.

 

(vlax-for n (vla-get-selectionsets(vla-get-active-document(vlax-get-acad-object)))
  (vla-delete n)
  )

I just generally save, close and reopen the drawing since it happens very rarely.  

 

 

Architect, Registered NC, VA, SC, & GA.
Message 10 of 12

serag.hassouna
Advocate
Advocate

That's really insightful @dbroad,

also, there's a simple thing I need to add.
AutoCAD commands recognize only ordinary selection sets as valid selection arguments.
This is really a cornerstone issue, and it should be well-considered when using AutoLISP's command function or the ActiveX SendCommand method.

0 Likes
Message 11 of 12

dbroad
Mentor
Mentor

Yes, I understand. It would be nice if there was a relationship between the legacy container and the activeX container for selection sets for that reason.  Yet most things can be accomplished using activeX directly without command methods.  In these cases, the operation is usually faster than using command methods.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 12 of 12

john.uhden
Mentor
Mentor

So what's wrong with that?

A selection set identifier is not unique, like a handle, even though multiple selection sets may have the same collection.

As you pointed out, Just don't try to keep more than 128 selection sets at the same time.  I can't imagine why one would need more than a few at the same time.  Localizing variables usually avoids that rare problem.

John F. Uhden

0 Likes