Problem with node in layer selection


#1

Hello everyone,

I want to ask you for help. I’m using a script from Miauu from the scriptspot forum. The script works great for my needs, but…

  fn RS =   -- random select one node all layer
    				(		
    					if selection.count != 0 then
    					(
    					hide $	
    					selObjsArr = selection as array												
    					if selObjsArr.count != 0 then												
    					(               												
    							layersArr = #()												
    							for o in selObjsArr do												
    							(												
    									selObjLayer = o.layer												
    									appendIfUnique layersArr selObjLayer												
    							)												
    							objToSelArr = #()						
    							for layer in layersArr do											
    							(												
    									layer.nodes &theNodes 										
    									append objToSelArr (theNodes[random 1 theNodes.count])												
    							)												
    							select objToSelArr												
    					)												
    					else												
    							messagebox "Select at least one object" title:"Empty Selection"n	
    				local hiddenObjs = for obj in objects where obj.isNodeHidden collect obj
    				unhide selection hiddenObjs	;
    				)
    				)

My scene: Layer1:
group name “a” (box01, box02, box03)
group name “b” (sphere01, sphere02, …)
group name “c” (…)

group name “r” (box91, box92, box93…)

the script was run 59 times and these are the results
a, f, h, o, r, r, b, j, r, m, a, a, r, r, r, h, h, h, m, j, r, i, h, r, r, h, r, r, h, m, r, h, p, h, h, h, r, r, r, a, r, r, n, h, r, r, a, r, r ,r, l, k, h, e, r, m, r, h, r,

“a” = 5x
“b” = 1x
“c” = 0
“d” = 0

“h” = 14x

“r” = 25x

The main problem is that some objects were not marked at all and “h” “r” were marked many times.
I would need a random selection but with some regularity so that some objects = 0x and other objects = 100x do not happen.

Thanks for your time.


#2

maybe I found a problem.

group "a" = 4 objects
group "b" = 3 objects
--
group "r" = 100 objects

If group “r” contains many objects, it has more combinations in “random”
Hmmm, Is it possible to set the random selection only to “GROUP” so that the script sees it as “one group = one object”?


#3

I think that the most correct method would be to collect all the nodes in one list from different (specified) layers and select them one by one in random order.
we can do it:

fn collectLayerNodes layernames = 
(
	nodes = #()
	for layername in layernames where (layer = LayerManager.getLayerFromName layername) != undefined do
	(
		layer.nodes &n
		join nodes n 
	)
	nodes
)
fn shuffleArr list seedvalue: = 
(
	if seedvalue != unsupplied do seed seedvalue
		
	for k = 1 to list.count do 
	(
		i = random 1 k
		swap list[k] list[i]
	)
	list
)


/************************** MAKE a scene ********************************/

delete objects
while (LayerManager.count > 1) do LayerManager.deleteLayerHierarchy (LayerManager.getLayer 1).name forcedelete:on
gc()

my_layernames = #(#AAA, #BBB, #CCC)
for name in my_layernames do LayerManager.newLayerFromName name

--seed 0
nodes = #()
with redraw off
(
	for z = 0 to 9 do for x = 0 to 9 do
	(
		p = point pos:[x * 10 , 0, z * 10] size:10 box:on cross:off wirecolor:gray 
		layer = LayerManager.getLayer (random 1 my_layernames.count)
		layer.addnode p
		append nodes p
	)


	(
		select nodes
		max tool zoomextents all
		--nodes.cross = off
		--nodes.wirecolor = gray
	)
	deselect objects
)
/************************** Collect layer nodes **************************/

layernodes = collectLayerNodes my_layernames

/************************** Randomize order ******************************/

shuffleArr layernodes

/************************** Select one by one **************************/
slidertime = 0
for node in layernodes while not keyboard.escPressed do 
(
	node.cross = on
	node.wirecolor = green	
	select node
	sleep 0.1
	slidertime += 1
)

#4

Hi Denis,

before i start studying your script i was trying something and maybe this would be the way.

I used this:

--
append objToSelArr (helpers[random 1 helpers.count])
--

now it only indicates “group”, everything that is not in the group will remain invisible. This is exactly what I need, but there is another problem.

in the original script was:

--
layer.nodes &theNodes
append objToSelArr (theNodes[random 1 theNodes.count])
--

this selected one object/group from each layer - excellent

in the script with “helpers” only one group from all layers is selected.
Ideally something like “layer.helpers $thehelpers” this doesn’t work.

I also tried various combinations with “isGroupHead” but without success. Basically, I need a select only group…


#5

I tried to set it to “group” only, but it still marks objects that are not in the group. Selecting a layer based on the prefix works well, but I can’t set the label only on groups. I tried to set it to the same prefix as for layers, but it didn’t work, I don’t know why.

		-- fn RS =   -- random select one node all layer
    				clearListener()
						showtextg1 = "m*" --rollStruct.rollout1.suffix_group_show_g1.text 
					for a=0 to layerManager.count-1 do 
						(
						layer = layerManager.getLayer a
						if matchPattern layer.name pattern:showtextg1 do layer.isHidden = false
						)	

					nodesInsideLayerWithPrefix = for nodeOn in objects where isGroupHead nodeOn and matchPattern nodeOn.layer.name pattern:showtextg1 collect nodeOn
					if nodesInsideLayerWithPrefix.count > 0 then 
					select nodesInsideLayerWithPrefix
					
				--------------------------------------------------------------------------
    					selObjsArr = selection as array												
    					if selObjsArr.count != 0 then												
    					(       hide $ 
    							layersArr = #()												
    							for o in selObjsArr do												
    							(												
								selObjLayer = o.layer												
								appendIfUnique layersArr selObjLayer												
    							)
						
    							objToSelArr = #()						
								for l in layersArr do						
    							(					
										groupArr = #()
										for i in objects do
										(
											if (isGroupHead i ) == true then
											(
												append groupArr i
											)
										)
									l.nodes &groupArr	
									append objToSelArr (groupArr[random 1 groupArr.count])																								
								)
								select objToSelArr 
    					)												
    					else												
					messagebox "Select at least one object" title:"Empty Selection"n	
    				 hiddenObjs = for obj in objects where obj.isNodeHidden collect obj
    				unhide selection hiddenObjs	;

if i do this:

--l.nodes &groupArr

script indicates only group “it’s good” but in all layers and that’s bad. It should always indicate one group in each layer with the given prefix.


#6

Groups, layers, nodes, hidden, selected, random, exact, name, pattern… you’ve got me completely confused.
Can you tell exactly what you need? This is called the technical task, where everything is explained once, fully and clearly.


#7

my scene is complicated:
1.layer “ball_m” = Group_1(box_01,box_02), Group_02(box_03, box_04), sphere_01, sphere_02

2.layer “ball_x” = Group_3(box_05,box_06), Group_04(box_07, box_08), sphere_03, sphere_04


the first part of the script does this: [solved]
if the layer has the suffix “m” = select layer
(another part of the script changes the suffix) - everything works

the second part of the script should do:
all objects are hidden
randomly select one “group” and unhide (only layer “ball_m”)
everything that is not in “group” will always be hidden

the resulting record will be:
select layer “ball_m” and unhide Group_1(box_01,box_02) and hide Group_02(box_03, box_04), sphere_01, sphere_02
or
select layer “ball_m” and unhide Group_2(box_03,box_04) and hide Group_01(box_01, box_02), sphere_01, sphere_02

(sphere_01, sphere_02 will always be hidden
and layer “ball_x” will be hidden)


#8

if I run this part, I get the following result:

				----- Select layer with suffix and group ------ work
					showtextg1 = "*m*"
					nodesInsideLayerWithPrefix = for nodeOn in objects where isGroupHead nodeOn and matchPattern nodeOn.layer.name pattern:showtextg1 collect nodeOn
					if nodesInsideLayerWithPrefix.count > 0 then 
					select nodesInsideLayerWithPrefix

				if selection.count != 0 then
					(
					hide $	

						selObjsArr = selection as array						
					if selObjsArr.count != 0 then												
					(               												
							layersArr = #()												
							for o in selObjsArr do					
							(												
									selObjLayer = o.layer												
									appendIfUnique layersArr selObjLayer												
							)												

							objToSelArr = #()						
							for la in layersArr do--where isGroupHead la do-- collect la									
							(		
				--la.nodes &theNodes 
									append objToSelArr (theNodes[random 1 theNodes.count])												
							)												
							select objToSelArr												
					)
				)					

					----- UnHide all what is selected ------ work
					hiddenObjs = for obj in objects where obj.isNodeHidden collect obj
    				unhide selection hiddenObjs	;

but, iwant this result:

–Random one group select per layer with suffix m


#9

951polo…
what you’re asking is very simple, but… I’ll be honest with you, I don’t feel like helping you at all because you’re not doing what I’m asking.
And I ask for a simple - that your question be subject and clear.

What does the layers with the suffix “m” have to do with it? Are you going to use layers for the rest of your life, with or without the “m” suffix? What you need to ask is how to find all layer names matching a given pattern.

Why is the random group in the list of layer nodes? The layer nodes as well as groups are a special case… The real question is how to make all and only selected objects visible and all the others hidden.

And so on down the list of your questions.

If you don’t like this way, then go your own but without me…


#10

I understand you. I read a lot of discussions where you also wrote, and yes, you don’t exactly like people here, that’s me. Apologies, I’m not that deep into coding. I would like to solve this myself and not have to waste your time. I know what you mean, you want me to understand it all and proceed step by step. I’m not going to cry here, what’s not going well, not enough time, etc. I can’t ask the questions you want to hear because I don’t know how to ask, don’t be mad at me, I know I’m doing it wrong. Sry.