1

I started giving a basic voxel type script a shot, where it'll look in the 6 directions adjancent to a point n draw a plane across any side that doesn't have anything next to it. Then I can combine the planes and it'll make an object.

This works nicely when it's all one object, but if there's space between the objects, it still combines it all as one object. With the list of coordinates being like (x,y,z), how would I split it based on what is connected? The only way I can think of would be very processing heavy and would involve checking every free space around an object while building it up until there is none left, but I imagine there should probably be a better way.

For the record, this isn't actually going to be used for anything, it's just for fun to see if I could do it

import pymel.core as py

directions = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]]

grid = {}
grid[(0,0,0)] = 1
grid[(1,0,0)] = 0
grid[(-1,0,0)] = 1
grid[(0,1,0)] = 1


for originalCoordinate in grid.keys():
    adjacentCoordinates = [tuple( sum( j ) for j in zip( i, originalCoordinate ) ) for i in directions]
    blockHere = grid[originalCoordinate]
    if blockHere:
        for newCoordinate in adjacentCoordinates:
            if not grid.get( newCoordinate, 0 ):
                newDirection = tuple( i[1]-i[0] for i in zip( originalCoordinate, newCoordinate ) )
                newSide = py.polyPlane( width = 1, height = 1, sx = 1, sy = 1 )[0]
                sideLocation = list( originalCoordinate )
                sideRotation = [0, 0, 0]
                if newDirection[0]:
                    if newDirection[0] > 0:
                        print originalCoordinate, "Facing X"
                        sideLocation[0] += 0.5
                        sideRotation[2] += -90
                    else:
                        print originalCoordinate, "Facing -X"
                        sideLocation[0] += -0.5
                        sideRotation[2] += 90
                if newDirection[1]:
                    if newDirection[1] > 0:
                        print originalCoordinate, "Facing Y"
                        sideLocation[1] += 0.5
                        sideLocation[1] += 0
                    else:
                        print originalCoordinate, "Facing -Y"
                        sideLocation[1] += -0.5
                        sideLocation[1] += 180
                if newDirection[2]:
                    if newDirection[2] > 0:
                        sideLocation[2] += 0.5
                        sideRotation[0] += 90
                        print originalCoordinate, "Facing Z"
                    else:
                        sideLocation[2] += -0.5
                        sideRotation[0] += -90
                        print originalCoordinate, "Facing -Z"
                py.move( newSide, sideLocation )
                py.rotate( newSide, sideRotation )
kartikg3
  • 2,590
  • 1
  • 16
  • 23
Peter
  • 3,186
  • 3
  • 26
  • 59
  • You really should add the tags: tag pymel and Maya. I have suggested that edit for this post. But if you don't see that reflected, you should add those tags soon. – kartikg3 Mar 06 '15 at 22:50
  • Quick suggestion: try using "pm" or "pmc" for pymel, instead of "py". – kartikg3 Mar 06 '15 at 22:51
  • Thanks, to be fair with the problem not being particularly maya specific (only the code), I didn't think it would need the tags :) And is that mainly for being more google friendly with pm instead of py? – Peter Mar 06 '15 at 23:27
  • 1
    I'm pretty sure @kartikg3's suggestion of using something other than `py` was because the two letters "py" occur so frequently in Python that it would be easy to get confused when reading it, since the name is basically meaningless due to wide usage. So readability, not "Google friendliness". – jpmc26 Mar 06 '15 at 23:59
  • Thanks @jpmc26. You took the words out of my keyboard. – kartikg3 Mar 07 '15 at 00:01
  • Ahh right that makes sense haha (I started using py before I realised pymel was a module, I thought it was actually modified python when we first covered it in uni), I'll start using pm from now on :P – Peter Mar 07 '15 at 04:03

1 Answers1

1

The usual method for searching a 3-d regular grid like this is an octree. The basic idea is that you divide your space into powers-of-two cubes: each cube becomes 8 smaller cubes of half size, and reports the presence of objects in its children. By recursively subdividing this way you can quickly eliminate checks for large areas of the world that are empty. It's not too difficult to implement because it's fundamentally recursive: if you get it working for two levels of subdivision you've got the ability to go deeper as needed. There are several python implementations on github to look at, I haven't got one to recommend.

theodox
  • 12,028
  • 3
  • 23
  • 36
  • Thanks, I'm guessing this would be a way to display the grid as opposed to calculate which bits are separate? It doesn't actually sound that hard to design so I'll give it a shot and see how it goes :) – Peter Mar 10 '15 at 02:23
  • An octree is basically a way of accelerating checks for 3-d data when the data is spares: if you have 10 points in a 10 x 10 x 10 grid, thats 10 points in 1000 cells: a lot of checks. The octree can help you eliminate the empty cells quickly from any searches. This will make it faster to figure out the adjacencies and also to cut the area you need to voxelize down to the smallest volume that contains your points – theodox Mar 10 '15 at 17:55
  • Yeah cheers for the info, I've been trying to get it working but I've hit a small problem. I'm storing the coordinates like (1,1),(-1,1) etc and keeping it 2D for now, but how do you deal with even points that fall on the edge of a grid? Would adding 0.5 to each coordinate fix it? Got a quick example here - http://i.imgur.com/h6gr2HH.png – Peter Mar 10 '15 at 20:22
  • 1
    The traditional approach is to make sure that the boundaries are consistently included in the same way: either bump them up or down but do it consistentlly at all levels. its usually a "less than, larger-or-equals" test – theodox Mar 10 '15 at 21:49
  • Nearly got it to a working state, but the fact it can't use even numbers was causing problems with drawing the cubes, so I may try the same thing but with a 3x3x3 cube instead, to allow for the even numbers :) – Peter Mar 11 '15 at 02:10