0

I'm trying to make my own version of an octree, and have hit a problem if you try add points of different sizes, as going down a depth level will just overwrite everything, therefore removing any information on larger blocks.

I thought the best way to fix this would be to check backwards for the last point, and rebuild the list down to the depth of the new point. However, I can't actually figure out how to build the list, despite the fact it's really easy to think of the output I'm after.

Here's the data it needs to build the list with an example start and end list, I need it in the format ["Nodes",(coordinate),"Nodes",(coordinate)...] where each coordinate covers every item in the structure list, up until it reaches the end.

structure = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]

start = ['Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1)]
end = ['Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (1, -1, -1), 'Nodes', (-1, -1, -1)]
length = len( end )-len( start )

This is an extreme example (going from depth 4 to 0), and would produce 4096 different values, though 99% of the time it wouldn't be anything like this big, so performance shouldn't matter too much.

In the case of the example start and end values, I don't need values of each length, they just all need to the maximum length, like this -

['Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1)]
['Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1)]
['Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, 1, -1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1), 'Nodes', (-1, -1, -1)]
#4002 values later
['Nodes', (1, 1, 1), 'Nodes', (-1, -1, -1), 'Nodes', (1, 1, 1), 'Nodes', (1, 1, 1), 'Nodes', (1, 1, 1), 'Nodes', (1, 1, 1)]

I had an attempt but I realised after it wasn't actually recursive, here it is anyway -

newThing = {}
for i in range( length/2 ):
    try:
        #Set it to previous level so you can append
        newThing[i] = newThing[i-1]
    except:
        #Start off the dictionary
        newThing[i] = {}
        for j in range( len( structure ) ):
            newThing[i][j] = start
    #Add structure value for each one
    for j in range( len( structure ) ):
        newThing[i][j].append( "Nodes" )
        newThing[i][j].append( structure[j] )

All I really need is each list during runtime, so if it can be got to a stage where it can print all the combinations from within the loop, that'd be great, as memory wouldn't be wasted storing all of them :)

Peter
  • 3,186
  • 3
  • 26
  • 59

1 Answers1

0

Since nobody answered, I figured the easiest way to go around it would be a recursive function, and got lucky. It will continue building the lists until it hits the maximum length, and return them all at once.

def recursiveList( currentInput, combinations, length ):
    newInputList = []
    for input in currentInput:
        if len( input ) < length:
            for combination in combinations:
                newInputList += recursiveList( [input + [input[0], combination]], combinations, length )
        else:
            newInputList.append( input )
    return newInputList

Using the values I posted in the question, recursiveList( [start], structure, len(end) ) will return 4096 correct values

It goes so much faster than I thought it would too, here are the timeit results -

64 lists: 0.0000057 seconds
512 lists: 0.00048 seconds
4096 lists: 0.004 seconds
32768 lists: 0.032 seconds

Peter
  • 3,186
  • 3
  • 26
  • 59