package com.vitco.importer;
import com.vitco.util.file.FileIn;
import com.vitco.util.file.RandomAccessFileIn;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Importer contract for (all?) voxel formats
*/
public abstract class AbstractImporter {
// true if loading was successful
private final boolean hasLoaded;
public final boolean hasLoaded() {
return hasLoaded;
}
// -------------
// contains a layer object
public final static class Layer {
public final String name;
// contains the voxel that were read
private ArrayList<int[]> voxel = new ArrayList<int[]>();
// constructor
private Layer(String name) {
this.name = name;
}
// for sanity testing
private final HashSet<String> known = new HashSet<String>();
private void addVoxel(int x, int y, int z, int color) {
voxel.add(new int[]{x,y,z,color});
// for sanity testing
assert known.add(x+"_"+y+"_"+z);
}
// ----
public final boolean isEmpty() {
return voxel.isEmpty();
}
int i = 0;
public final int[] next() {
return voxel.get(i++);
}
public final boolean hasNext() {
return i < voxel.size();
}
public final void reset() {
i = 0;
}
private boolean visible = true;
public void setVisible(boolean flag) {
this.visible = flag;
}
public boolean isVisible() {
return visible;
}
}
// the currently active layer
private Layer activeLayer;
// list of layers
public final ArrayList<Layer> getVoxel() {
return layerList;
}
// add voxel to known-voxel list
protected final void addVoxel(int x, int y, int z, int color) {
voxelCount++;
lx = Math.min(lx, x);
ly = Math.min(ly, y);
lz = Math.min(lz, z);
hx = Math.max(hx, x);
hy = Math.max(hy, y);
hz = Math.max(hz, z);
cx += x;
cy += y;
cz += z;
activeLayer.addVoxel(x, y, z, color);
}
// contains the layer list
private final ArrayList<Layer> layerList = new ArrayList<Layer>();
// add a new layer that the voxels are now added to
protected final void addLayer(String name) {
if (activeLayer.isEmpty()) {
layerList.remove(activeLayer);
}
activeLayer = new Layer(name);
layerList.add(activeLayer);
}
// prepend a new layer that the voxels are now added to
protected final void prependLayer(String name) {
if (activeLayer.isEmpty()) {
layerList.remove(activeLayer);
}
activeLayer = new Layer(name);
layerList.add(0, activeLayer);
}
// set visibility of current layer
protected final void setLayerVisibility(boolean flag) {
activeLayer.setVisible(flag);
}
// --------------
// lowest voxel value in that dimension (all layers)
private int lx = Integer.MAX_VALUE;
private int ly = Integer.MAX_VALUE;
private int lz = Integer.MAX_VALUE;
public final int[] getLowest() {
return new int[] {lx, ly, lz};
}
// highest voxel value in that dimension (all layers)
private int hx = Integer.MIN_VALUE;
private int hy = Integer.MIN_VALUE;
private int hz = Integer.MIN_VALUE;
public final int[] getHighest() {
return new int[] {hx, hy, hz};
}
// the amount of voxel that were added (all layers)
private int voxelCount = 0;
public final int getVoxelCount() {
return voxelCount;
}
// weighted center (all layers)
private long cx = 0;
private long cy = 0;
private long cz = 0;
public final int[] getWeightedCenter() {
return new int[] {(int) (cx/voxelCount), (int) (cy/voxelCount), (int) (cz/voxelCount)};
}
// the the center (determined by the boundaries)
public final int[] getCenter() {
return new int[] {Math.round(lx + (hx-lx)/2.0f), Math.round(ly + (hy-ly)/2.0f), Math.round(lz + (hz-lz)/2.0f)};
}
// --------------
// constructor
public AbstractImporter(File file, String layerName) throws IOException {
activeLayer = new Layer(layerName);
layerList.add(activeLayer);
FileIn fileIn = new FileIn(file);
RandomAccessFileIn raf = new RandomAccessFileIn(file, "r");
try {
hasLoaded = read(fileIn, raf);
} finally {
raf.close();
fileIn.finish();
}
}
// read file - returns true if file has loaded correctly
protected abstract boolean read(FileIn fileIn, RandomAccessFileIn raf) throws IOException;
}