package org.artisanlogiciel.games.stl; import java.util.Scanner; import org.artisanlogiciel.games.Brick; import org.artisanlogiciel.games.LabyModel; import org.artisanlogiciel.games.WallsProvider; import java.io.OutputStream; import java.io.IOException; /** * Wall3d to create walls in 3d for stl conversion South, West North East... * * wall3D will create a rectangular cuboid with 2 triangle vertex for each face **/ public class Wall3d { // 4 triangles in 2 dim space reused 3 times // in facts order matters... final static int BASE[][][] = { // lower left {{0, 0}, {1, 0}, {0, 1}}, // higher right {{1, 0}, {1, 1}, {0, 1}}, // lower right {{0, 0}, {1, 0}, {1, 1}}, // higher left {{0, 0}, {1, 1}, {0, 1}}}; final static short X = 1; final static short Y = 2; final static short Z = 4; // final static short AXIS[][]= {{X,Y},{-Z,Y},{X,Y},{Z,Y},{X,-Z},{X,-Z}}; // [face][axis] final static short AXIS[][] = { // face 0 (x,y) back {X, Y, 0}, // face 1 (z,y) left {Z, Y, 0}, // face 2 (x,y,1) {X, Y, 1}, // face 3 {Z, Y, 1}, // face 4 {X, Z, 0}, // face 5 {X, Z, 1}}; final static String normalx = "1.0 0.0 0.0"; final static String normaly = "0.0 1.0 0.0"; final static String normalz = "0.0 0.0 1.0"; final static String normalmx = "-1.0 0.0 0.0"; final static String normalmy = "0.0 -1.0 0.0"; final static String normalmz = "0.0 0.0 -1.0"; // final static short NORMAL[] = {Z,X,Z,X,Y,Y}; final static String normalstr[] = { normalmz, normalx, normalz, normalmx, normaly, normalmy }; boolean reverse_vertex[] = { true,false,false,true,false,true }; int triangle[][][] = null; public Wall3d(int t[][][]) { triangle = t; } public Wall3d(Wall3d origin, int dx, int dy, int dz) { triangle = origin.translate(dx, dy, dz); } Wall3d(int xl, int yl, int zl, int dx, int dy, int dz) { int f = 0; triangle = new int[12][3][3]; int[] factor = {xl, yl, zl}; int[] translate = {dx, dy, dz}; for (int facet = 0; facet < 12; facet++) { // point in a triangle / facet for (int p = 0; p < 3; p++) { short uaxis = 0; // a square face is two facets. int face = facet / 2; // first two axis ( projected on x,y,z depending on AXIS[face][] ) for (int axis = 0; axis < 2; axis++) { short caxis = AXIS[face][axis]; if (caxis > 0) { f = 1; } else if (caxis < 0) { // wait wait in AXIS there is no negative value ... // so we never enter here, what was the purpose ? might be history. f = -1; caxis = (short) -caxis; } // what if caxis == 0 ? f is kept as its previous value ? // which is 1 in facts due to AXIS[..][0] > 0 // uaxis keep track of used axes for this face to find last missing axis uaxis |= caxis; if (caxis == X) { caxis = 0; } else if (caxis == Y) { caxis = 1; } else { caxis = 2; } triangle[facet][p][caxis] = translate[caxis] + BASE[facet % 4][p][axis] * f * factor[caxis]; } // last remaining axis if ((uaxis & X) == 0) { // no X was used => X uaxis = 0; } else if ((uaxis & Y) == 0) { // X was used byt not Y => Y uaxis = 1; } else { // default X, and Y were used => Z uaxis = 2; } triangle[facet][p][uaxis] = translate[uaxis] + AXIS[facet / 2][2] * factor[uaxis]; } } } public int[][][] translate(int dx, int dy, int dz) { int[] translate = {dx, dy, dz}; int t[][][] = new int[12][3][3]; for (int facet = 0; facet < 12; facet ++) { // point in a triangle for (int p = 0; p < 3; p++) { for (int axis = 0; axis < 3; axis++) { t[facet][p][axis] = translate[axis] + triangle[facet][p][axis]; } } } return t; } /** * write triangles as stl text **/ public String toString() { String s = ""; for (int facet = 0; facet < 12; facet++) { int face = facet / 2; // most software don't care normal but just rely on vertex order ( right hand ). String normal = normalstr[face]; s += "facet normal " + normal + "\nouter loop\n"; boolean reverse = reverse_vertex[face]; for (int p = 0; p < 3; p++) { s += "vertex"; // p that accept right hand int rhp = p; if ( reverse ) { // reverse 2 and 1 ; 0 => 0, 1 => 2 , 2 => 1 rhp = ( p * 5 ) % 3; } for (int a = 0; a < 3; a++) { s += " " + triangle[facet][rhp][a]; } s += "\n"; } s = s + "endloop\nendfacet\n"; } return s; } }