HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonMinor

Convert points into an octree

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
convertpointsintooctree

Problem

I set about doing it as a challenge (and it's still far from finished) but I hit lots of problems. The main one that caused most of them was it can't deal with even numbers (it can be (1,1),(1,-1),(-1,1),(-1,-1), but nothing with a 0), so I had to multiply everything by 2 and add 1, which caused such a headache later on (which I won't bother going into as it should hopefully be fixed by now).

I don't know how they're normally coded anyway, so I just made it up as I went along until I had something that worked. Anyway, is the way I've done it alright, or is it not so good?

It calculates which path the points should take from the highest depth (eg. 9 = 16-8+4-2-1 or +1,-1,+1,-1,-1 ), and put them into the dictionary based on those values. If an entire branch (8 coordinates) gets filled, and all the blocks have the same ID, it'll go up a level, and set the branch to that ID to save space. Likewise, if there's nothing in it, it'll be set to False.

If you want to try out the code on a larger grid, scroll down a bit and there's a line to uncomment where it'll download a grid of 400k points (be warned, it took 70 seconds to process for me). Here's a picture of it in 3d, where I deleted a corner so you can see how it works.

```
#import pymel.core as pm
import math
from operator import itemgetter

minDepthLevel = 0

class EditError( Exception ):
pass
def editDictionary( dictionaryName, listOfValues, canOverwriteKeys=True ):
reducedDictionary = dictionaryName
for i in listOfValues[:-2]:
if type( reducedDictionary ) != dict and canOverwriteKeys:
reducedDictionary = {}
try:
if reducedDictionary.get( i, None ) == None:
canOverwriteKeys = True
raise EditError()
elif type( reducedDictionary[i] ) != dict:
raise EditError()
except EditError:
reducedDictionary[i] = {}
except:
print "Something went wrong"
return

Solution

General comment

Python has a style guide called PEP 8. You are free to follow it or not but if except if you have a good reason, it's probably better to try to stick to it. Among other things, the naming convention is not followed.

You'll find tools to check your code (pep8) but also to fix it ([autopep8]3). You'll also find various other tools to check your code quality : pylint, pychecker, pyflakes, etc.

In
roundToMultiple`

From Idioms and Anti-Idioms in Python


Because except: catches all exceptions, including SystemExit,
KeyboardInterrupt, and GeneratorExit (which is not an error and should
not normally be caught by user code), using a bare except: is almost
never a good idea.

I'll let you think about it and catch only the relevant exceptions.

You can rewrite :

if closestPower > maxPower:
        maxPower = closestPower

    maxPower = max(closestPower, maxPower)


Also, if I were you, I'd define a function like :

def roundToMultiple( multiple, i):
    maxPower = 0
    if i:
         try:
            return int( math.ceil( math.log( abs( i ), multiple ) ) )
        except:
            pass
    return 0

def max_power( multiple, *args ):
    return max(roundToMultiple(multiple, i) for i in args)


(The naming kind of sucks because I have no idea what these functions are supposed to be).

Code Snippets

if closestPower > maxPower:
        maxPower = closestPower

    maxPower = max(closestPower, maxPower)
def roundToMultiple( multiple, i):
    maxPower = 0
    if i:
         try:
            return int( math.ceil( math.log( abs( i ), multiple ) ) )
        except:
            pass
    return 0

def max_power( multiple, *args ):
    return max(roundToMultiple(multiple, i) for i in args)

Context

StackExchange Code Review Q#83959, answer score: 2

Revisions (0)

No revisions yet.