/** Test that ST and MT yield the exact same result */ public void testMTEquals() { int size1 = 10; int size2 = 15; byte state1 = Grid.INSIDE; byte state2 = Grid.INSIDE; Grid grid1 = new ArrayGridByte(size1, size1, size1, 0.001, 0.001); Grid grid2 = new ArrayGridByte(size2, size2, size2, 0.002, 0.002); Grid grid3 = new ArrayGridByte(size2, size2, size2, 0.002, 0.002); // set grid1 for (int x = 3; x < 7; x++) { grid1.setState(x, 5, 5, state1); } // set grid2 for (int y = 5; y < size2; y++) { grid2.setState(1, y, 10, state2); } // set grid3 for (int y = 5; y < size2; y++) { grid3.setState(1, y, 10, state2); } // get the subtraction of grid1 from grid2 SubtractOpMT op = new SubtractOpMT(grid1, Runtime.getRuntime().availableProcessors()); Grid subtrGridMT = op.execute(grid2); SubtractOp op2 = new SubtractOp(grid1, 0, 0, 0, 1); Grid subtrGridST = op2.execute(grid2); assertEquals(size2, subtrGridST.getWidth()); assertEquals(size2, subtrGridMT.getWidth()); // check filled voxel state and material for (int x = 0; x < size2; x++) { for (int y = 0; y < size2; y++) { for (int z = 0; z < size2; z++) { assertEquals( "(" + x + ", " + y + ", " + z + ") state is not equal", subtrGridST.getState(x, y, z), subtrGridMT.getState(x, y, z)); } } } }
public void printEntriesOld() { for (int y = 0; y < grid.getHeight(); y++) { System.out.print(y + 1 + ") "); for (int x = 0; x < grid.getWidth(); x++) { String content = grid.getCell(x, y).getContent(); if (content != null) { System.out.print(" " + content + " "); } System.out.println(); } } }
public void printEntries() { for (int y = 0; y < grid.getHeight(); y++) { System.out.print(y + 1 + ") "); for (int x = 0; x < grid.getWidth(); x++) { GridCell cell = grid.getCell(x, y); String content = cell.getContent(); if (content == null) { content = "*"; } System.out.print(" " + content + " "); } System.out.println(); } }
public void adjust() { List children; try { children = this.tree.getChildren(parentNode); } catch (GraphException ex) { ex.printStackTrace(); return; } // Find the child that that is immediately to the right and to the left // of the inserted column VisualVertex immediateRightChild = null, immediateLeftChild = null; int immediateRightChildX = grid.getWidth(); int immediateLeftChildX = 0; for (int i = 0; i < children.size(); i++) { VisualVertex vVertex; vVertex = this.vGraph.getVisualVertex(children.get(i)); Point vertexPoint = grid.findVisualVertex(vVertex); if (vertexPoint.x > insertedColumnX && (immediateRightChild == null || vertexPoint.x < immediateRightChildX)) { immediateRightChild = vVertex; immediateRightChildX = vertexPoint.x; } if (vertexPoint.x < insertedColumnX && (immediateLeftChild == null || vertexPoint.x > immediateLeftChildX)) { immediateLeftChild = vVertex; immediateLeftChildX = vertexPoint.x; } } // Move the granchild nodes to the right // whose parent is immediately to the right of the inserted colunm grid // but itself is to the left of the inserted column grid if (immediateRightChild != null) { this.adjustToRight = true; this.visit(immediateRightChild.getVertex()); } // Move the granchild nodes to the left // whose parent is immediately to the left of the inserted colunm grid // but itself is to the right of the inserted column grid if (immediateLeftChild != null) { this.adjustToRight = false; this.visit(immediateLeftChild.getVertex()); } }
/** Grids sharing a voxel coordinate should have those voxels subtracted */ public void _testSharedVoxelMT() { int size1 = 10; int size2 = 15; byte state1 = Grid.INSIDE; byte state2 = Grid.INSIDE; Grid grid1 = new ArrayGridByte(size1, size1, size1, 0.001, 0.001); Grid grid2 = new ArrayGridByte(size2, size2, size2, 0.002, 0.002); // set grid1 for (int x = 3; x < 7; x++) { grid1.setState(x, 5, 5, state1); } // set grid2 for (int y = 5; y < size2; y++) { grid2.setState(3, y, 5, state2); } // get the subtration of grid1 from grid2 SubtractOpMT op = new SubtractOpMT(grid1, Runtime.getRuntime().availableProcessors()); Grid subtrGrid = (Grid) op.execute(grid2); assertEquals(size2, subtrGrid.getWidth()); // check filled voxel state and material for (int x = 0; x < size2; x++) { for (int y = 0; y < size2; y++) { for (int z = 0; z < size2; z++) { if (x == 3 && y >= 6 && y < size2 && z == 5) { assertEquals( "(" + x + ", " + y + ", " + z + ") state is not " + state2, state2, subtrGrid.getState(x, y, z)); } else { assertEquals( "(" + x + ", " + y + ", " + z + ") state is not outside", Grid.OUTSIDE, subtrGrid.getState(x, y, z)); } } } } }
/** Test basic operation */ public void testBasic() { int size1 = 10; int size2 = 15; byte state1 = Grid.INSIDE; byte state2 = Grid.INSIDE; Grid grid1 = new ArrayGridByte(size1, size1, size1, 0.001, 0.001); Grid grid2 = new ArrayGridByte(size2, size2, size2, 0.002, 0.002); // set grid1 for (int x = 3; x < 7; x++) { grid1.setState(x, 5, 5, state1); } // set grid2 for (int y = 5; y < size2; y++) { grid2.setState(1, y, 10, state2); } // get the subtraction of grid1 from grid2 SubtractOp op = new SubtractOp(grid1, 0, 0, 0, 0); Grid subtrGrid = (Grid) op.execute(grid2); assertEquals(size2, subtrGrid.getWidth()); // check filled voxel state and material for (int x = 0; x < size2; x++) { for (int y = 0; y < size2; y++) { for (int z = 0; z < size2; z++) { if (x == 1 && y >= 5 && y < size2 && z == 10) { assertEquals( "(" + x + ", " + y + ", " + z + ") state is not " + state2, state2, subtrGrid.getState(x, y, z)); } else { assertEquals( "(" + x + ", " + y + ", " + z + ") state is not outside", Grid.OUTSIDE, subtrGrid.getState(x, y, z)); } } } } }
public ConnectedComponentState( Grid grid, GridBit mask, int x, int y, int z, byte state, boolean collectData, int algorithm) { this.grid = grid; this.mask = mask; this.state = state; this.seedX = x; this.seedY = y; this.seedZ = z; nx1 = grid.getWidth() - 1; ny1 = grid.getHeight() - 1; nz1 = grid.getDepth() - 1; // printf("ConnectedComponent(%d, %d, %d)\n", x,y,z); if (collectData) m_component = new ArrayInt(30); switch (algorithm) { default: case ALG_SCANLINE_STACK: fillScanLineStack(new int[] {x, y, z}); break; case ALG_SCANLINE_QUEUE: fillScanLineQueue(new int[] {x, y, z}); break; case ALG_FLOODFILL_QUEUE: floodFillQue(new int[] {x, y, z}); break; case ALG_FLOODFILL_RECURSIVE: floodFill(x, y, z, 0); break; } // release references mask = null; grid = null; }
/** Test that MT is faster then ST. Assumes we always run on a MT box */ public void _testMTFaster() { // TODO: this test does not always works so removing for now int size1 = 800; int size2 = 800; byte state1 = Grid.INSIDE; byte state2 = Grid.INSIDE; Grid grid1 = new ArrayGridByte(size1, size1, size1, 0.001, 0.001); Grid grid2 = new ArrayGridByte(size2, size2, size2, 0.002, 0.002); Grid grid3 = new ArrayGridByte(size2, size2, size2, 0.002, 0.002); for (int y = 0; y < grid1.getHeight(); y++) { for (int x = 0; x < grid1.getWidth(); x++) { for (int z = 0; z < grid1.getDepth(); z++) { grid1.setState(x, y, z, state1); } } } for (int y = 0; y < grid2.getHeight(); y++) { for (int x = 0; x < grid2.getWidth(); x++) { for (int z = 0; z < grid2.getDepth(); z++) { grid2.setState(x, y, z, state1); } } } int WARMUP = 3; long st_time = 0; for (int i = 0; i < WARMUP; i++) { long t0 = System.currentTimeMillis(); // get the subtraction of grid1 from grid2 SubtractOpMT op = new SubtractOpMT(grid1, Runtime.getRuntime().availableProcessors()); Grid subtrGridMT = op.execute(grid2); long mt_time = System.currentTimeMillis() - t0; t0 = System.currentTimeMillis(); SubtractOp op2 = new SubtractOp(grid1, 0, 0, 0, 1); Grid subtrGridST = op2.execute(grid2); st_time = System.currentTimeMillis() - t0; // printf("MT time: %6d ST time: %6d SpeedUp: %6.2f\n",mt_time,st_time,(float)st_time / // mt_time); } int TIMES = 1; int cores = Runtime.getRuntime().availableProcessors(); cores = Math.min(cores, 16); // We expect linear scaling to stop by this time float expected_speedup = 0.5f * cores; for (int i = 0; i < TIMES; i++) { long t0 = System.currentTimeMillis(); // get the subtraction of grid1 from grid2 SubtractOpMT op = new SubtractOpMT(grid1, Runtime.getRuntime().availableProcessors()); op.setThreadCount(cores); op.setSliceSize(2); Grid subtrGridMT = op.execute(grid2); if (subtrGridMT.getWidth() > 10000) { System.out.println("no optimize away"); } ; long mt_time = System.currentTimeMillis() - t0; float speedup = (float) st_time / mt_time; printf("MT time: %6d ST time: %6d SpeedUp: %6.2f\n", mt_time, st_time, speedup); assertTrue("Speedup factor > " + expected_speedup, speedup >= expected_speedup); } }
/** Test basic operation */ public void testBasic() { int size = 10; AttributeGrid grid = new ArrayAttributeGridByte(size, size, size, 0.001, 0.001); for (int y = 2; y < 8; y++) { for (int z = 2; z < 8; z++) { setX(grid, y, z, Grid.INSIDE, 1, 2, 7); } } int erosionDistance = 1; ErosionCube ec = new ErosionCube(erosionDistance); Grid erodedGrid = ec.execute(grid); int width = erodedGrid.getWidth(); int height = erodedGrid.getHeight(); int depth = erodedGrid.getDepth(); for (int y = 0; y < height; y++) { for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { byte state = erodedGrid.getState(x, y, z); // System.out.println(x + ", " + y + ", " + z + ": " + state); if (y >= 2 && y < 6) { if (z >= 2 && z < 6) { if (x >= 2 && x < 6) { assertEquals( "State of (" + x + " " + y + " " + z + " is not interior", Grid.INSIDE, state); } else { assertEquals( "State of (" + x + " " + y + " " + z + " is not outside", Grid.OUTSIDE, state); } } else { assertEquals( "State of (" + x + " " + y + " " + z + " is not outside", Grid.OUTSIDE, state); } } else { assertEquals( "State of (" + x + " " + y + " " + z + " is not outside", Grid.OUTSIDE, state); } } } } /* erosionDistance = 2; ec = new ErosionCube(erosionDistance); erodedGrid = ec.execute(grid); width = erodedGrid.getWidth(); height = erodedGrid.getHeight(); depth = erodedGrid.getDepth(); for (int y=0; y<height; y++) { for (int z=0; z<depth; z++) { for (int x=0; x<width; x++) { System.out.println(x + ", " + y + ", " + z + ": " + erodedGrid.getState(x, y, z)); } } } */ }
@Override protected double computePrefWidth(double height) { int w = LayoutUtil.getSizeSafe(grid != null ? grid.getWidth() : null, LayoutUtil.PREF); return w; }
/** * Lays out the child nodes of the specified vertex. It is assumed that the child nodes are * "ready" for positioning. */ private void layout(Object rootVertex, List children) { Grid newGrid; int numberOfChildren = children.size(); if (numberOfChildren == 0) { // If the node has no children, create a 1x1 grid List singleElementList = new ArrayList(10); VisualVertex rootVisualVertex = this.vgraph.getVisualVertex(rootVertex); singleElementList.add(rootVisualVertex); newGrid = new Grid(singleElementList, 1, 1); // assign the visual vertex to the only point in the grid newGrid.setGridPoint(0, 0, rootVisualVertex); // then set the grid in the List this.gridsOfVertices.set(this.vgraph.getVisualVertices().indexOf(rootVisualVertex), newGrid); // Indicate that this vertex is ready for positioning for its parent this.verticesReadyForPositioning.add(rootVertex); } else { // If the node has children, it is presumed by the algorithm in visit() // that all of its children already has a grid assigned // Therefore get all the grids of the children and append them together. Grid childGrid = null; int size = children.size(); for (int i = 0; i < size; i++) { VisualVertex vObject; vObject = this.vgraph.getVisualVertex(children.get(i)); if (i == 0) { childGrid = (Grid) this.gridsOfVertices.get(this.vgraph.getVisualVertices().indexOf(vObject)); } if (i > 0) { childGrid.appendToRight( (Grid) this.gridsOfVertices.get(this.vgraph.getVisualVertices().indexOf(vObject))); } } // Find the width of the node's direct children, excluding grandchildrens. int childMinX = 0, childMaxX = 0, childWidth; for (int i = 0; i < size; i++) { VisualVertex vObject; vObject = this.vgraph.getVisualVertex(children.get(i)); Point vertexPoint = childGrid.findVisualVertex(vObject); if (i == 0) { childMinX = vertexPoint.x; childMaxX = vertexPoint.x; } else { childMinX = Math.min(childMinX, vertexPoint.x); childMaxX = Math.max(childMaxX, vertexPoint.x); } } childWidth = childMaxX - childMinX + 1; // If the width of the node's direct children is even, make it odd by adding a blank grid // in the middle position of its direct children, not the middle position // of the total grid's width. int insertedColumnX; if (childWidth % 2 == 0) { insertedColumnX = childMinX + Math.round(childWidth / 2); childGrid.insertEmptyGrid(insertedColumnX); TreeGridAdjuster adjuster = new TreeGridAdjuster(this.vgraph, rootVertex, childGrid, insertedColumnX); adjuster.adjust(); adjuster = null; } // Create a new grid for the parent of the children List singleElementList = new ArrayList(10); VisualVertex rootVisualVertex = this.vgraph.getVisualVertex(rootVertex); singleElementList.add(rootVisualVertex); newGrid = new Grid(singleElementList, childGrid.getWidth(), 1); // newGrid = new Grid( singleElementList, // childGrid.getWidth(), 1 ); newGrid.setGridPoint(childMinX + Math.round(childWidth / 2), 0, rootVisualVertex); // Now append the concatenated grid of all of its children to the bottom newGrid.appendToBottom(childGrid); // Finally, set the grid on the List this.gridsOfVertices.set(this.vgraph.getVisualVertices().indexOf(rootVisualVertex), newGrid); // Indicate that this vertex is ready for positioning for its parent this.verticesReadyForPositioning.add(rootVertex); } // Dont forget to replace the grid this.grid = newGrid; // Now recursively ( upward ) test if we need to layout the parent. Tree tree = (Tree) this.vgraph.getGraph(); Object parent; List siblings; try { parent = tree.getParent(rootVertex); siblings = tree.getChildren(parent); } catch (Exception ex) { ex.printStackTrace(); return; } if (parent != null) { // If all of its siblings ( its parent's children ) are ready for positioning, // then layout the vertices of the parent siblings.remove(rootVertex); if (this.verticesReadyForPositioning.containsAll(siblings)) { // Add the current vertex being visited back to siblings // since the layout() method requires all children. siblings.add(rootVertex); this.layout(parent, siblings); this.verticesReadyForPositioning.add(rootVertex); } } }