Commit 36da3e22 authored by Andrey Filippov's avatar Andrey Filippov

Tested OK new textured meshes generation

parent f7d1b998
...@@ -1969,7 +1969,7 @@ public class TexturedModel { ...@@ -1969,7 +1969,7 @@ public class TexturedModel {
scenes, // final QuadCLT [] scenes, scenes, // final QuadCLT [] scenes,
scenes_sel, // final boolean [] scenes_sel, // null or which scenes to process scenes_sel, // final boolean [] scenes_sel, // null or which scenes to process
tileClusters, // final TileCluster [] tileClusters, // disparities, borders, selections for texture passes tileClusters, // final TileCluster [] tileClusters, // disparities, borders, selections for texture passes
renormalize, // final boolean renormalize, // false - use normalizations from previous scenes to keep consistent colors renormalize, // final boolean re-normalize, // false - use normalizations from previous scenes to keep consistent colors
max_disparity_lim, // final double max_disparity_lim, // 100.0; // do not allow stray disparities above this max_disparity_lim, // final double max_disparity_lim, // 100.0; // do not allow stray disparities above this
min_trim_disparity, // final double min_trim_disparity, // 2.0; // do not try to trim texture outlines with lower disparities min_trim_disparity, // final double min_trim_disparity, // 2.0; // do not try to trim texture outlines with lower disparities
debugLevel); // final int debug_level) debugLevel); // final int debug_level)
...@@ -2080,11 +2080,6 @@ public class TexturedModel { ...@@ -2080,11 +2080,6 @@ public class TexturedModel {
dbg_mesh_imgs = new double[tileClusters.length][dbg_scaled_width * dbg_scaled_height]; dbg_mesh_imgs = new double[tileClusters.length][dbg_scaled_width * dbg_scaled_height];
// maybe fill with NaN? // maybe fill with NaN?
} }
// double [][] dbg
/*
tp.getTilesX(), // int tilesX,
tp.getTilesY(), // int tilesY,
*/
for (int nslice = 0; nslice < tileClusters.length; nslice++){ for (int nslice = 0; nslice < tileClusters.length; nslice++){
if (dbg_tri_disp != null) { if (dbg_tri_disp != null) {
Arrays.fill(dbg_tri_disp[nslice], Double.NaN); Arrays.fill(dbg_tri_disp[nslice], Double.NaN);
...@@ -2094,28 +2089,34 @@ public class TexturedModel { ...@@ -2094,28 +2089,34 @@ public class TexturedModel {
((dbg_tri_disp != null)? (new double[][] {dbg_tri_disp[nslice], dbg_tri_tri[nslice]}): ((dbg_tri_disp != null)? (new double[][] {dbg_tri_disp[nslice], dbg_tri_tri[nslice]}):
(new double[][] {dbg_tri_tri[nslice]}) ): null; (new double[][] {dbg_tri_tri[nslice]}) ): null;
if (debugLevel > -1){ if (debugLevel > -2){
System.out.println("Generating cluster images from texture slice "+nslice); System.out.println("Generating cluster images from texture slice "+nslice);
} }
int [] indices = tileClusters[nslice].getSubIndices(); int [] indices = tileClusters[nslice].getSubIndices();
Rectangle [] bounds = tileClusters[nslice].getSubBounds(); Rectangle [] bounds = tileClusters[nslice].getSubBounds(); // tiles?
Rectangle texture_bounds = null; // if not null - allows trimmed combo textures tiles?
int dbg_tri_indx = 3; // showing triangles for cluster 3 int dbg_tri_indx = 3; // showing triangles for cluster 3
for (int sub_i = 0; sub_i < indices.length; sub_i++) { for (int sub_i = 0; sub_i < indices.length; sub_i++) {
Rectangle roi = bounds[sub_i]; Rectangle roi = bounds[sub_i];
int cluster_index = indices[sub_i]; int cluster_index = indices[sub_i];
ImagePlus imp_texture_cluster = combined_textures[nslice]; ImagePlus imp_texture_cluster = combined_textures[nslice];
boolean [] alpha = (combined_alphas != null) ? combined_alphas[nslice] : null; boolean [] alpha = (combined_alphas != null) ? combined_alphas[nslice] : null;
if (imp_textures != null) { if (imp_textures != null) { // wrong? roi is in tiles or pixels?
//transform_size
imp_texture_cluster = imp_textures[cluster_index]; imp_texture_cluster = imp_textures[cluster_index];
if (combined_alphas != null) { if (combined_alphas != null) {
alpha = new boolean[roi.height * roi.width]; int alpha_width = roi.width * transform_size;
for (int row = 0; row < roi.height; row++) { int alpha_height = roi.height * transform_size;
int alpha_x0 = roi.x * transform_size;
int alpha_y0 = roi.y * transform_size;
alpha = new boolean[alpha_width * alpha_height];
for (int row = 0; row < alpha_height; row++) {
System.arraycopy( System.arraycopy(
combined_alphas[nslice], combined_alphas[nslice],
(roi.y + row) * width + roi.x, (alpha_y0 + row) * width + alpha_x0,
alpha, alpha,
row * roi.width, row * alpha_width,
roi.width); alpha_width);
} }
} }
} }
...@@ -2170,6 +2171,7 @@ public class TexturedModel { ...@@ -2170,6 +2171,7 @@ public class TexturedModel {
"shape_id-"+cluster_index, // id "shape_id-"+cluster_index, // id
null, // class null, // class
roi, // scan.getTextureBounds(), roi, // scan.getTextureBounds(),
texture_bounds, // Rectangle texture_bounds, // if not null - allows trimmed combo textures
scan_selected, // scan.getSelected(), scan_selected, // scan.getSelected(),
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM], scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
clt_parameters.transform_size, clt_parameters.transform_size,
...@@ -2198,6 +2200,16 @@ public class TexturedModel { ...@@ -2198,6 +2200,16 @@ public class TexturedModel {
} }
// if (imp_textures[nslice] != null) // if (imp_textures[nslice] != null)
} // for (int nslice = 0; nslice < tileClusters.length; nslice++){ } // for (int nslice = 0; nslice < tileClusters.length; nslice++){
if (dbg_mesh_imgs != null) {
ShowDoubleFloatArrays.showArrays(
dbg_mesh_imgs,
dbg_scaled_width,
dbg_scaled_height,
true,
ref_scene.getImageName()+"-tri-meshes");
}
if (dbg_tri_disp != null) { if (dbg_tri_disp != null) {
ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays(
dbg_tri_disp, dbg_tri_disp,
......
...@@ -235,19 +235,21 @@ public class TriMesh { ...@@ -235,19 +235,21 @@ public class TriMesh {
final int [] num_indices final int [] num_indices
) { ) {
//TODO: add optimization (merging some in-tile triangles) //TODO: add optimization (merging some in-tile triangles)
final boolean full_image = selected_tiles.length > (bounds.height * bounds.width); final boolean full_selection = selected_tiles.length > (bounds.height * bounds.width); // applies to selected_tiles
final boolean full_alpha = alpha.length > (bounds.height * bounds.width * tile_size * tile_size);
final int [][][][] indices = new int [bounds.height][bounds.width][][]; final int [][][][] indices = new int [bounds.height][bounds.width][][];
final Thread[] threads = ImageDtt.newThreadArray(TexturedModel.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(TexturedModel.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
final int source_tile_width = full_image? tilesX : bounds.width; final int source_tile_width = full_selection? tilesX : bounds.width;
final int source_pix_width = source_tile_width * tile_size; // final int source_pix_width = source_tile_width * tile_size;
final int source_tile_offsx = full_image? bounds.x : 0; final int source_tile_offsx = full_selection? bounds.x : 0;
final int source_tile_offsy = full_image? bounds.y : 0; final int source_tile_offsy = full_selection? bounds.y : 0;
// final int source_tile_offs = source_tile_offsx + source_tile_offsy * source_tile_width; // final int source_pix_offsx = source_tile_offsx * tile_size;
final int source_pix_offsx = source_tile_offsx * tile_size; // final int source_pix_offsy = source_tile_offsy * tile_size;
final int source_pix_offsy = source_tile_offsy * tile_size; final int source_pix_offsx = (full_alpha? bounds.x : 0) * tile_size;
// final int source_pix_offs = source_pix_offsx + source_pix_offsy * source_pix_width; final int source_pix_offsy = (full_alpha? bounds.y : 0) * tile_size;
// final int sub_size = Math.max(tile_size / subdiv, 1); final int source_pix_width = (full_alpha? tilesX : bounds.width) * tile_size;
final int btiles = bounds.width * bounds.height; final int btiles = bounds.width * bounds.height;
final AtomicInteger aindx = new AtomicInteger(0); final AtomicInteger aindx = new AtomicInteger(0);
...@@ -474,7 +476,7 @@ public class TriMesh { ...@@ -474,7 +476,7 @@ public class TriMesh {
switch (dir) { switch (dir) {
case 0: for (int i = 0; i < subdiv; i++) {edge[i] = tile[0][subdiv - i - 1];} break; case 0: for (int i = 0; i < subdiv; i++) {edge[i] = tile[0][subdiv - i - 1];} break;
case 1: for (int i = 0; i < subdiv; i++) {edge[i] = tile[subdiv - i - 1][subdiv-1];} break; case 1: for (int i = 0; i < subdiv; i++) {edge[i] = tile[subdiv - i - 1][subdiv-1];} break;
case 4: for (int i = 0; i < subdiv; i++) {edge[i] = tile[subdiv-1][i];} break; case 2: for (int i = 0; i < subdiv; i++) {edge[i] = tile[subdiv-1][i];} break;
case 3: for (int i = 0; i < subdiv; i++) {edge[i] = tile[i][0];} break; case 3: for (int i = 0; i < subdiv; i++) {edge[i] = tile[i][0];} break;
} }
return edge; return edge;
...@@ -652,7 +654,7 @@ public class TriMesh { ...@@ -652,7 +654,7 @@ public class TriMesh {
if (tris[btiley][btilex][y][x] == null) { if (tris[btiley][btilex][y][x] == null) {
tris[btiley][btilex][y][x] = TRI_NONE.clone(); tris[btiley][btilex][y][x] = TRI_NONE.clone();
} }
tris[btiley][btilex][y][x][1 << TRI_DOWN_LEFT] = atri.getAndIncrement(); tris[btiley][btilex][y][x][TRI_DOWN_LEFT] = atri.getAndIncrement();
} }
} }
Arrays.fill(quad_corners, false); Arrays.fill(quad_corners, false);
...@@ -664,32 +666,33 @@ public class TriMesh { ...@@ -664,32 +666,33 @@ public class TriMesh {
x = subdiv - 1; x = subdiv - 1;
y = i - subdiv; y = i - subdiv;
} }
int num_corn = 0; quad_corners[0] = tneib_indices[8][y][x] >= 0; // this subtile
for (int dir = 1; dir < 4; dir++) { // skipping top-left corner if (quad_corners[0]) { // all following triangles assume that top-left corner exists
int x1 = x + TRI_OFFS_XY[dir][0]; int num_corn = 1;
int y1 = y + TRI_OFFS_XY[dir][1]; for (int dir = 1; dir < 4; dir++) { // skipping top-left corner
int [] xyd = getNeibNode(x1, y1, subdiv); int x1 = x + TRI_OFFS_XY[dir][0];
boolean exists = false; int y1 = y + TRI_OFFS_XY[dir][1];
if (tneib_indices[xyd[2]] != null) { int [] xyd = getNeibNode(x1, y1, subdiv);
exists = tneib_indices[xyd[2]][xyd[1]][xyd[0]] >= 0; // is populated boolean exists = false;
exists = (tneib_indices[xyd[2]] != null) && (tneib_indices[xyd[2]][xyd[1]][xyd[0]] >= 0); // is populated
quad_corners[dir] = exists; quad_corners[dir] = exists;
if (exists) {
num_corn ++;
}
} }
if (exists) { if (num_corn >= 3) {
num_corn ++; if (tris[btiley][btilex][y][x] == null) {
} tris[btiley][btilex][y][x] = TRI_NONE.clone();
} }
if ((num_corn >= 3) && quad_corners[0]) { // that triangle (TRI_DOWN_LEFT) should already exist if (quad_corners[3]) {
if (tris[btiley][btilex][y][x] == null) { if (quad_corners[1]) {
tris[btiley][btilex][y][x] = TRI_NONE.clone(); tris[btiley][btilex][y][x][TRI_RIGHT_DOWNLEFT] = atri.getAndIncrement();
} } else {
if (quad_corners[3]) { tris[btiley][btilex][y][x][TRI_DOWNRIGHT_LEFT] = atri.getAndIncrement();
if (quad_corners[1]) { }
tris[btiley][btilex][y][x][1 << TRI_RIGHT_DOWNLEFT] = atri.getAndIncrement(); } else {
} else { tris[btiley][btilex][y][x][TRI_RIGHT_DOWN] = atri.getAndIncrement();
tris[btiley][btilex][y][x][1 << TRI_DOWNRIGHT_LEFT] = atri.getAndIncrement(); }
}
} else {
tris[btiley][btilex][y][x][1 << TRI_RIGHT_DOWN] = atri.getAndIncrement();
} }
} }
} }
...@@ -794,6 +797,8 @@ public class TriMesh { ...@@ -794,6 +797,8 @@ public class TriMesh {
// type 4 (4 dirs, 2 triangles): // type 4 (4 dirs, 2 triangles):
// 1 in ortho, 1 CCW from it, 2 CCW from 1. Does not need mirror, as the mirror will be if looking // 1 in ortho, 1 CCW from it, 2 CCW from 1. Does not need mirror, as the mirror will be if looking
// from the last 2 (90 degrees CCW from the first 1) // from the last 2 (90 degrees CCW from the first 1)
// type 5 (4 dirs, 1 triangle):
// 1 in ortho, 2 CCW from it, 1 CCW from 1. Does not need mirror
// First pass - reserving triangles indices // First pass - reserving triangles indices
final Thread[] threads = ImageDtt.newThreadArray(TexturedModel.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(TexturedModel.THREADS_MAX);
...@@ -817,14 +822,18 @@ public class TriMesh { ...@@ -817,14 +822,18 @@ public class TriMesh {
if ((btx >= 0) && (btx < bwidth) && (bty >= 0) && (bty < bheight) && if ((btx >= 0) && (btx < bwidth) && (bty >= 0) && (bty < bheight) &&
(indices[bty][btx] != null)) { (indices[bty][btx] != null)) {
tneib_types[dir] = 0; tneib_types[dir] = 0;
if (indices[bty][btx] != null) { // if (indices[bty][btx] != null) {
tneib_types[dir] = (indices[bty][btx].length > 1) ? 2 : 1; tneib_types[dir] = (indices[bty][btx].length > 1) ? 2 : 1;
} // }
has_full_neib |= (tneib_types[dir] == 1); // all modes 0..4 require 2-1 in ortho direction
has_full_neib |= (tneib_types[dir] == 1) && ((dir & 1) == 0);
} }
} }
if (has_full_neib) { if (has_full_neib) {
tris[btiley][btilex] = new int [5][4]; // [types][directions tris[btiley][btilex] = new int [6][4]; // [types][directions
for (int i = 0; i < tris[btiley][btilex].length; i++) {
Arrays.fill(tris[btiley][btilex][i], -1);
}
// reserve indices for type0: // reserve indices for type0:
for (int dir = 0; dir < 4; dir++) { for (int dir = 0; dir < 4; dir++) {
int tneib = tneib_types[2*dir]; int tneib = tneib_types[2*dir];
...@@ -868,6 +877,15 @@ public class TriMesh { ...@@ -868,6 +877,15 @@ public class TriMesh {
tris[btiley][btilex][4][dir] = atri.getAndAdd(2); tris[btiley][btilex][4][dir] = atri.getAndAdd(2);
} }
} }
// reserve indices for type5:
for (int dir = 0; dir < 4; dir++) {
int tneib = tneib_types[2*dir]; // pointed
int tneib1= tneib_types[(2*dir+7) % 8]; // CCW 1 from pointed
int tneib2= tneib_types[(2*dir+6) % 8]; // CCW 2 from pointed
if ((tneib == 1) && (tneib1 == 2) && (tneib2 == 1)) {
tris[btiley][btilex][5][dir] = atri.getAndAdd(1);
}
}
} }
} }
} }
...@@ -905,7 +923,7 @@ public class TriMesh { ...@@ -905,7 +923,7 @@ public class TriMesh {
int tri_index = tris[btiley][btilex][0][dir4]; // type0 int tri_index = tris[btiley][btilex][0][dir4]; // type0
if (tri_index >= 0) { if (tri_index >= 0) {
int [] edge = getEdgeIndices(tneib_indices [8], dir4); int [] edge = getEdgeIndices(tneib_indices [8], dir4);
int indx_1 = tneib_indices[2 * dir4][0][0]; int indx_1 = tneib_indices[2 * dir4][0][0]; // null pointer
for (int i = 0; i < subdiv_m1; i++) { for (int i = 0; i < subdiv_m1; i++) {
tri_indices[tri_index + i][0] = indx_1; tri_indices[tri_index + i][0] = indx_1;
tri_indices[tri_index + i][1] = edge[i]; tri_indices[tri_index + i][1] = edge[i];
...@@ -964,7 +982,19 @@ public class TriMesh { ...@@ -964,7 +982,19 @@ public class TriMesh {
tri_indices[tri_index + 1][0] = indx_2; tri_indices[tri_index + 1][0] = indx_2;
tri_indices[tri_index + 1][1] = edge[subdiv_m1]; tri_indices[tri_index + 1][1] = edge[subdiv_m1];
tri_indices[tri_index + 1][2] = edge[0]; tri_indices[tri_index + 1][2] = edge1[0];
}
}
// build triangles for type5:
for (int dir4 = 0; dir4 < 4; dir4++) {
int tri_index = tris[btiley][btilex][5][dir4]; // type5
if (tri_index >= 0) {
int [] edge = getEdgeIndices(tneib_indices [8], dir4);
int [] edge1 = getEdgeIndices(tneib_indices [(2 * dir4 + 7) % 8], (dir4 + 2) % 4);
int indx_1 = tneib_indices[2 * dir4][0][0];
tri_indices[tri_index][0] = edge [subdiv_m1];
tri_indices[tri_index][1] = edge1[subdiv_m1];
tri_indices[tri_index][2] = indx_1;
} }
} }
} }
...@@ -1876,6 +1906,7 @@ public class TriMesh { ...@@ -1876,6 +1906,7 @@ public class TriMesh {
String id, String id,
String class_name, String class_name,
Rectangle bounds, Rectangle bounds,
Rectangle texture_bounds, // if not null - allows trimmed combo textures
// Below selected and disparity are bounds.width*bounds.height // Below selected and disparity are bounds.width*bounds.height
boolean [] selected, // may be either tilesX * tilesY or bounds.width*bounds.height boolean [] selected, // may be either tilesX * tilesY or bounds.width*bounds.height
double [] disparity, // if null, will use min_disparity double [] disparity, // if null, will use min_disparity
...@@ -1900,7 +1931,7 @@ public class TriMesh { ...@@ -1900,7 +1931,7 @@ public class TriMesh {
if (bounds == null) { if (bounds == null) {
return; // not used in lwir return; // not used in lwir
} }
boolean display_triangles = debug_level > 0;
/* /*
...@@ -1933,8 +1964,19 @@ public class TriMesh { ...@@ -1933,8 +1964,19 @@ public class TriMesh {
indices, // int [][][][] indices) indices, // int [][][][] indices)
subdivide_mesh); // final int [] num_indices) { subdivide_mesh); // final int [] num_indices) {
Rectangle tex_rect = full_texture ? new Rectangle(bounds.x, bounds.y, tilesX, tilesY) : null; Rectangle tex_rect = full_texture ? (
(texture_bounds != null) ?
new Rectangle( // when combo texture is trimmed (alpha should still be for the full image)
bounds.x - texture_bounds.x,
bounds.y - texture_bounds.y,
texture_bounds.width,
texture_bounds.height):
new Rectangle( // when combo texture is full tilesX * tilesY
bounds.x,
bounds.y,
tilesX,
tilesY)) :
null; // when texture is for cluster only
/* /*
* Get texture coordinates (0..1) for horizontal (positive - to the right) and vertical (positive - up) * Get texture coordinates (0..1) for horizontal (positive - to the right) and vertical (positive - up)
*/ */
...@@ -1954,23 +1996,13 @@ public class TriMesh { ...@@ -1954,23 +1996,13 @@ public class TriMesh {
tile_size, // final int tile_size, tile_size, // final int tile_size,
correctDistortions, // requires backdrop image to be corrected also correctDistortions, // requires backdrop image to be corrected also
geometryCorrection);// final GeometryCorrection geometryCorrection) geometryCorrection);// final GeometryCorrection geometryCorrection)
/*
double [] indexedDisparity = getIndexedDisparities( // get disparity for each index // updated 09.18.2022
disparity,
min_disparity,
max_disparity,
bounds,
pnum_indices[0], // final int num_indices,
indices,
tilesX);
*/
/* /*
* Triangulate all vertice indices - combine triangulation of same-size equailateral 45-degree * Triangulate all vertice indices - combine triangulation of same-size equailateral 45-degree
* large (tile size) and small (tile subdivisions) and add connections between large and small ones * large (tile size) and small (tile subdivisions) and add connections between large and small ones
*/ */
int [][] triangles = triangulateAll( int [][] triangles = triangulateAll(
indices); indices);
System.out.println("generateClusterX3d(): got "+triangles.length+" triangles");
final boolean plot_center = true; final boolean plot_center = true;
final double line_color = 1.0; final double line_color = 1.0;
final double center_color = 3.0; final double center_color = 3.0;
...@@ -1983,18 +2015,23 @@ public class TriMesh { ...@@ -1983,18 +2015,23 @@ public class TriMesh {
plot_center, // final boolean plot_center, plot_center, // final boolean plot_center,
line_color, // final double line_color, line_color, // final double line_color,
center_color); // final double center_color) center_color); // final double center_color)
if (display_triangles) {
ShowDoubleFloatArrays.showArrays(
tri_img,
tri_img_width,
tri_img.length / tri_img_width,
"this-triangles");
}
} }
if (x3dOutput != null) { if (x3dOutput != null) {
x3dOutput.addCluster( x3dOutput.addCluster(
texturePath, texturePath,
id, id,
class_name, class_name,
texCoord, texCoord,
worldXYZ, worldXYZ,
triangles); triangles);
} }
if (wfOutput != null) { if (wfOutput != null) {
wfOutput.addCluster( wfOutput.addCluster(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment