Creating an array of unique geometry

I'm trying to generate an array that has all geometry in my scene, minus duplicates of instanced objects. I don't want to remove all instanced geometry, I'd like to have one copy of the instance(s) in my array. The point being I want to apply changes to obj properties and vray properties of all the geometry in my scene, but I don't want to cycle back through 1000 instances to apply the same settings, as it then propagates those changes 1000 times and my script runs very slowly.

I tried to re-purpose some existing functions from the soulburn scripts library as I didn't feel like reinventing the wheel (though I renamed them incase I needed to edit them so they didn't conflict with the originals), but when my script finishes and I select the original array, it's right back to having all the geometry including all instances in it. Can someone give me a hand and tell me what I've missed? This is just the fn's and the portion of the larger script that deals with making the Array in question:

Another note, looking at it, this looks like an incredibly convoluted route to get to something as simple as the array I need, any suggestions on a simpler method would be much appreciated.

(
fn YSlibCopyArray a =
(
local b = #()
if a.count != 0 then
(
for i = 1 to a.count do
(
append b a[i]
)
)
return b
show b "returned as b"
)

fn YSlibGetInstancesOfObject Obj =
(
a = #()
if (refs.dependents Obj.baseobject).count != 0 then
(
for i = 1 to (refs.dependents Obj.baseobject).count do
(
if (refs.dependents Obj.baseobject)[i] != Obj then
(
if iskindof (refs.dependents Obj.baseobject)[i] (classof Obj) then
(
append a (refs.dependents Obj.baseobject)[i]
)
)
)
)
return a
)

fn YsLibRemoveIndexesFromArray a indexes =
(
local a = YsLibCopyArray a
local b = YsLibCopyArray indexes
if b.count != 0 then
(
sort b
for i = 1 to b.count do
(
deleteitem a b[i]
for w = 1 to b.count do
(
b[w] -= 1
)
)
)
return a
)

fn YsLibRemoveItemFromArray a item =
(
b = YsLibCopyArray a
if b.count != 0 then
(
delete_array = #()
for i = 1 to b.count do
(
if b[i] == item then append delete_array i
)
b = YsLibRemoveIndexesFromArray b delete_array
)
return b
)

fn YSlibRemoveItemsFromArray a items =
(
local a = YSlibCopyArray a
local b = YSlibCopyArray items
if b.count != 0 then
(
for i in b do
(
a = YSlibRemoveItemFromArray a i
)
)
return a
)

fn YSlibRemoveInstancesOfObjFromArray a Obj =
(
local b = YSlibCopyArray a
if Obj != undefined then
(
toRemove = YSlibGetInstancesOfObject Obj
b = YSlibRemoveItemsFromArray a toRemove
show b.count
)
return b
)
------------------------------------------

select geometry

GArray = geometry

Show GArray.count

clearselection()

show "cleared"

for obj in GArray do
(
yslibremoveinstancesofobjfromarray GArray obj
show garray.count
)
show garray.count
)

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
barigazy's picture

NOTE

If you want to isolate only geometry objects then use:

for obj in geometry as array where not isKindOf obj TargetObject do 
(
--the rest of the code
)

barigazy

barigazy's picture

Try this code

uniqueNodesArr = #()
for obj in objects do 
(
	InstanceMgr.GetInstances obj &instancesArr
	if instancesArr.count == 1 then append uniqueNodesArr obj
	else
	(
		if uniqueNodesArr.count == 0 then append uniqueNodesArr obj
		else 
		(
			findInst = (for i in uniqueNodesArr where finditem instancesArr i != 0 collect true).count
			if findInst == 0 do append uniqueNodesArr obj
		)
	)
)
uniqueNodesArr
for i in uniqueNodesArr do print i.name

barigazy

xXDambielXx's picture

THanks

Thanks for the quick reply and improved code, that's way better than what I had.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.