Objectsbylayer selection

Hello!
when i select objects with Objectsbylayer with rhinoscript, it select all objects in the layer, but it select objets on other layout…
i made the script on Rhino 5, it was ok, but in rhino 6 every script that use “objectsbylayer” crash, because it select object on a layout…

Can you post a small example file with what’s crashing V6 when you use Rhino.ObjectsByLayer()?

Thanks, --Mitch

excuse me…
when i said crash … ce n’est pas vraiment ce que je voulais dire…
mais du coup mon script ne fonctionne plus.
dans l’exemple ci dessous:
"Call Main()
Sub Main()
Dim strobj,arrobj, layer

arrobj = rhino.selectedobjects

If  isnull(arrobj) Then
	strobj = rhino.GetObject("selectionne un objet")
Else
	strobj = arrobj(0)
End If
If isnull(strobj) Then Exit Sub
layer = rhino.objectlayer(strobj)
arrobj = Rhino.ObjectsByLayer(Layer, True)
rhino.SelectObjects arrobj

End Sub"

il me permet de sélectionner tout les objets d’un calque en sélectionnant une surface appartenant au calque…

et bien si je veux symétrisé la sélection… et bien il ne veut pas parce qu’il a été prendre une courbe ou autre sur un layout.

Ici ça semble fonctionner en Rhino 6… ??

Quand tu lance le script, as tu un mise en plan contenant une entité sur le calque?

Oui… Je peux essayer à nouveau demain, ou bien si tu as un petit exemple à poster ici…

Voilà - J’ai essayé de nouveau avec le fichier ci-dessous, ça marche toujours…

ScriptSelLayer.3dm (167.9 KB)

Le fichier a 4 calques avec des objets en “espace modèle” plus 2 pages layout avec des objets dans l’espace “layout” (pas dans l’espace modèle). Le script sélectionne tous les objets dans le calque choisi, y compris espaces modèle et layout…

Seule chose que je note, si des objets sont sélectionnés dans l’espace modèle, quand on bascule sur une page layout, ils sont desélectionnés… Même chose dans le sens inverse…

–Mitch

justement c’est là que ça ne va pas… dans rhino 5 l’outils objectbylayer ne sélectionnait que les objets qui était dans la fenêtre graphique active ( Modèle OU layout) mais en plus ne sélectionnait que les objets visibles…

alors que maintenant, dans la V6, l’outil sélectionne les objets du calque sur tout les espaces ( modèle ET layout), mais aussi les objets cachés… et en fait c’est cela qui me pose le plus de problème…
à suivre une vidéo, la suite des evenements est:
selection d’une surface
inverse hide
script objectbylayer
join
mergeallsurface
show
et là on se rend compte que des doublons sont apparus…

Autant que je sache, ObjectsByLayer() a toujours fonctionné de la même manière, soit en V5 soit en V6. Il trouve TOUS les objets dans un calque, égal qu’ils sont visibles, verrouillés ou cachés, ainsi qu’ils sont dans l’espace modèle ou dans l’espace layout. En fait, la même méthode en Rhino V6 a une option supplémentaire pour mieux trier (plus tard).

Exemple : Le fichier V5 ci-dessous contient 4 surfaces toutes sur le calque “Default”

  • dans l’espace modèle : 1 visible/sélectionnable, 1 verrouillée, 1 masquée
  • dans l’espace layout, une seule surface visible/sélectionnable.

ObjsByLayerTest.3dm (592.1 KB)

J’ai lancé ensuite le script suivant:

Option Explicit
Call Main()
Sub Main()
	Dim objs
	objs = Rhino.ObjectsByLayer("Default")
	Call Rhino.Print(Cstr(Ubound(objs) + 1) & " objects found on layer")
End Sub

Il rapporte CINQ objets. Pourquoi cinq? Il n’y a que 4 surfaces! Cependant, le «détail» lui-même sur la page layout compte également comme un objet…

La chose la plus importante à retenir ici est: si vous ne voulez que des objets sélectionnables, il faut filtrer davantage.

Par exemple:

Option Explicit
Call Main()
Sub Main()
	Dim objs, sel
	objs = Rhino.ObjectsByLayer("Default", True)
	sel = Rhino.SelectedObjects()
	Call Rhino.Print(Cstr(Ubound(sel) + 1) & " objects selected")
End Sub

Là, il rapporte encore 3 objets - la surface dans l’espace modèle, la surface dans l’espace layout, et le «détail» lui-même. Nous ne sommes donc pas encore arrivés…

Exemple 2:

Option Explicit
Call Main()
Sub Main()
	Dim objs, obj, sel
	objs = Rhino.ObjectsByLayer("Default")
	For Each obj In objs:
		If Rhino.IsObjectSelectable(obj) Then
			If Not Rhino.IsLayoutObject(obj) Then
				Call Rhino.SelectObject(obj)	
			End If			
		End If
	Next
	sel = Rhino.SelectedObjects()
	Call Rhino.Print(Cstr(Ubound(sel) + 1) & " objects selected")
End Sub

Là enfin, on a le résultat voulu - une seule surface sélectionnée

ObjectsByLayer en V6 a une troisième option:

Mais il faut toujours filtrer pour “séléctionnable” et “espace”

Bon… très bien… je comprends, mais as tu regarder la vidéo…

je pense pouvoir faire la même vidéo en rhino 5 et nous n’aurions pas le même résultat…

ton premier script me renvoi une erreur avec Ubound…

Pour tester, il faut le fichier dans le vidéo…

En générale, ça veut dire que l’array qu’on essaie d’avoir la dimension est vide ou non-initialisé…

oui c clair je crois avoir compris je n’ais pas de calque default, dans mon fichier mais un calque “défaut” excuse…

mais bon ça empêche pas que je rencontre un problème de doublon dans la video.

Pas grave… mais pour trouver le problème avec le doublon, il me faut un fichier pour tester… :wink:

le fichier c’est celui là:
test.3dm (46.5 KB)
me demande pas pourquoi je fais ça comme ça, mais cette suite de fonction je la fait super souvent dans mes montages:
j’affiche uniquement les surfaces que je veux fusionner ( selection puis inverse hide)
je selectionne par calque ( script objectsbylayer)
join
mergeallsurface
show
et là normalement les surfaces appartenant au même calque qui réapparaissent sont doublées. non?
et bien sur rhino 5 ça ne fait pas ça.

OK, maintenant je vois le problème… très, très étrange…! Je vais créer un “bug report”.
Comme on dit en anglais - “Thanks for reporting!” --Mitch

OK, the result of the above conversation in French - here is one of the odder bugs I have seen, discovered by our French friend @onlyforpeace

In the attached V6 file, you will see 4 surfaces on the Default layer. In addition, there are two more that are currently hidden. There are no other objects in the file. (use Show to check just to make sure I am telling the truth here, but then undo or the re-hide the two surfaces)

HiddenObjectsBug2.3dm (63.3 KB)

Now, run the following Rhinoscript on the file.

Option Explicit
Call Main()
Sub Main()
	Dim strObj,arrObjs, strLayer, arrSel

	Rhino.UnselectAllObjects
	strObj = Rhino.GetObject("Select a surface", 8)
	If Not IsNull(strObj) Then 
		strLayer = Rhino.ObjectLayer(strObj)
		arrObjs = Rhino.ObjectsByLayer(strLayer, True)
	End If
	If IsArray(arrObjs) Then
		Call Rhino.Print(Cstr(Ubound(arrObjs) + 1) & " surfaces on layer " & strLayer)
		arrSel = Rhino.SelectedObjects
		Call Rhino.Print(Cstr(Ubound(arrSel) + 1) & " surfaces selected")
		Call Rhino.Command("Join")
		Call Rhino.Command("Show")
	End If
End Sub

Basically it gets all the objects on the layer and selects them. The two hidden objects that are pulled in by ObjectsByLayer are not “selected”… or are they? Then Join is called on the selected objects and finally Show (all). Those last two you could also do manually instead of in the script, doesn’t matter. The ODD part is you will see that the two hidden surfaces have been DUPLICATED - there are now 4… :dizzy_face:

Note in passing that after Join, the command line says:
6 surfaces or polysurfaces joined into 4 open polysurfaces.
Which is very odd, because only 4 surfaces were showing.

OK, back up to the beginning and run the following very similar script:

Option Explicit
Call Main()
Sub Main()
	Dim strObj,arrObjs, strLayer, arrSel

	Rhino.UnselectAllObjects
	strObj = Rhino.GetObject("Select a surface", 8)
	If Not IsNull(strObj) Then 
		strLayer = Rhino.ObjectLayer(strObj)
		arrObjs = Rhino.ObjectsByLayer(strLayer, True)
	End If
	If IsArray(arrObjs) Then
		Call Rhino.Print(Cstr(Ubound(arrObjs) + 1) & " surfaces on layer " & strLayer)
		arrSel = Rhino.SelectedObjects
		Call Rhino.Print(Cstr(Ubound(arrSel) + 1) & " surfaces selected")
		'Unselect all then reselect arrSel'
		Call Rhino.UnselectAllObjects
		Call Rhino.SelectObjects(arrSel)
		Call Rhino.Command("Join")
		Call Rhino.Command("Show")
	End If
End Sub

The two hidden surfaces are no longer duplicated…
And, of course, the main reason for the original complaint - this does not happen in V5, it works as expected, no surfaces are duplicated…

So, there is something very odd going on in V6 with this, related to some hidden selection that is pulled in by Rhinoscript as well as some oddity with Join perhaps… For reference, the equivalent of the first script in Python does not exhibit the same weird behavior…

import rhinoscriptsyntax as rs

rs.UnselectAllObjects()
strObj = rs.GetObject("Select a surface", 8)
if strObj:
    strLayer = rs.ObjectLayer(strObj)
    arrObjs = rs.ObjectsByLayer(strLayer, True)
    if arrObjs:
        print "{} surfaces on layer {}".format(len(arrObjs),strLayer)
        arrSel = rs.SelectedObjects()
        print "{} surfaces selected".format(len(arrSel))
        rs.Command("Join")
        rs.Command("Show")

@pascal, I’ll let you test and forward this to the correct person… maybe @dale?

Thanks, checking…

I see this, I’ll buggify, thanks.

https://mcneel.myjetbrains.com/youtrack/issue/RH-49054

@Helvetosaur - this works - remove hidden objects from the ‘ObjectsByLayer’ tally.

Option Explicit
Call Main()
Sub Main()
	Dim strObj,arrObjs, strLayer, arrSel

	Rhino.UnselectAllObjects
	strObj = Rhino.GetObject("Select a surface", 8)
	If Not IsNull(strObj) Then 
		strLayer = Rhino.ObjectLayer(strObj)
		arrObjs = Rhino.ObjectsByLayer(strLayer)
		Dim id
			For Each id In arrObjs
				If Not Rhino.IsObjectHidden(id) Then
					Rhino.SelectObject(id)
				End If
				
			Next

	End If
	If IsArray(arrObjs) Then
		Call Rhino.Print(Cstr(Ubound(arrObjs) + 1) & " surfaces on layer " & strLayer)
		arrSel = Rhino.SelectedObjects
		Call Rhino.Print(Cstr(Ubound(arrSel) + 1) & " surfaces selected")
		Call Rhino.Command("Join")
		Call Rhino.Command("Show")
	End If
End Sub

-Pascal

Hi Pascal,
I threw a comment up on the youtrack item - which I still feel should not be closed… Of course you can filter in the script, but the point is, you shouldn’t have to… If you run Rhino.SelectObject(id), it should only select “selectable” objects - not ones that are hidden (IMO). It always used to work that way as well…