ScriptSpot

Forum topic · General Scripting

Optimizing code

By Igryl9l · 2021-04-09

Description

Hello
I am trying to optimize my code. Need to select a object class in a specific layer.
I am working with code that consists of two stages:
1: Selecting all objects in the layer.
2: Selecting splines from selected objects.


(
local allNodes = #(), theNodes = #()
for n in selection do (n.layer.nodes &theNodes ; join allNodes theNodes)
select allNodes
select(for obj in selection where classof obj.baseObject==line collect obj)
)

I am looking for a way to exclude the first part while keeping the result.
Any ideas on how to do this? Any help appreciated.

Comments (12)

.

miauu · 2021-05-03


(
	allNodes = #()
	for n in selection do 
	(
		n.layer.nodes &theNodes 		
		for obj in theNodes where classof obj.baseObject == line do
		(
			append allNodes obj
		)
	)
	select allNodes
)

.

jahman · 2021-05-03

What if selection contains several nodes that belong to the same layer?
You'll have n^2 results in allNodes array if all selected nodes are lines and belong to the same layer


LayerManager.deleteLayerByName "layer #1"
layer_1 = LayerManager.newLayerFromName "layer #1"

for i=1 to 100 do layer_1.AddNode (line())

layer_1.select true

(
	::allNodes = #()
	for n in selection do 
	(
		n.layer.nodes &theNodes 		
		for obj in theNodes do
		(
			append allNodes obj
		)
	)
	select allNodes
	
	format ">>> %\n" allNodes.count
)



>>> 10000

.

miauu · 2021-05-03

Yep, that is true. :)

obaida · 2021-07-05

just use "appendIfUnique" instead of "append"

.

jahman · 2021-07-05

it doesn't solve n^2 issue at all

obaida · 2021-07-05


LayerManager.deleteLayerByName "layer #1"
layer_1 = LayerManager.newLayerFromName "layer #1"
 
for i=1 to 100 do layer_1.AddNode (line())
 
layer_1.select true
 
(
	::allNodes = #()
	for n in selection do 
	(
		n.layer.nodes &theNodes 		
		for obj in theNodes do
		(
			appendIfUnique allNodes obj
		)
	)
	select allNodes
 
	format ">>> %\n" allNodes.count
)

;)

jahman · 2021-07-05


LayerManager.deleteLayerByName "layer #1"
layer_1 = LayerManager.newLayerFromName "layer #1"
 
for i=1 to 100 do layer_1.AddNode (line())
 
layer_1.select true
 
(
	iterations = 0
	::allNodes = #()
	for n in selection do 
	(
		n.layer.nodes &theNodes
 		
		for obj in theNodes do
		(
			iterations += 1
			appendIfUnique allNodes obj
		)
	)
	select allNodes
 
	format ">>> %\n" allNodes.count
	format "iterations: %\n" iterations
)


>>> 100
iterations: 10000 -- n^2 is still there ;)

obaida · 2021-07-06

sometimes using try()catch() is better than wasting time in solving all cases with errors
same as your case cuz it take seconds ;)
but if u care about the iterations go ahead :)

.

jahman · 2021-07-06

try catch? but how does it help you here?
Just imagine a user having 10.000 lines in a single layer. Possible? Easy. Still seconds?
10.000^2 is a pretty large amount of work. I bet max will hang for a long long time or just eat quite a lot of ram and crash after that.
I'd save a scene before any attempt to run a script with n^2 solution. ;)
That's why I posted the example to demonstrate the issue.
If it isn't a problem, ok.

obaida · 2021-07-06


LayerManager.deleteLayerByName "layer #1"
layer_1 = LayerManager.newLayerFromName "layer #1"
 
for i=1 to 100 do layer_1.AddNode (line())
 
layer_1.select true
 
(
	iterations = 0
	allNodes = #() ; layernames = #() ; theNodes
	for n in selection do appendIfUnique layernames n.layer.name
	for i in layernames do (
		layer = LayerManager.getLayerFromName i
		layer.nodes &theNodes
	)
	for obj in theNodes do (
		iterations += 1
		appendIfUnique allNodes obj
	)
	select allNodes
 
	format ">>> %\n" allNodes.count
	format "iterations: %\n" iterations
)

.

jahman · 2021-07-07


(
	all_nodes = #()
	tmp = #()
	for layer in makeuniquearray (for s in selection collect s.layer) do
	(		
		layer.nodes &tmp	
		join all_nodes tmp		
	)
	arr = makeUniqueArray all_nodes
	format "%\n" arr.count
)

Igryl9l · 2021-06-22

Many thanks. Ideally!