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

Tested OK new textured meshes generation

parent f7d1b998
Loading
Loading
Loading
Loading
+26 −14
Original line number Original line Diff line number Diff line
@@ -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 {
			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 {
					((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 {
								"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 {
			}
			}
			// 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,
+103 −66
Original line number Original line Diff line number Diff line
@@ -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 {
		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 {
        							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 {
        							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
        						if (quad_corners[0]) { // all following triangles assume that top-left corner exists 
        							int num_corn = 1;
        							for (int dir = 1; dir < 4; dir++) { //  skipping top-left corner
        							for (int dir = 1; dir < 4; dir++) { //  skipping top-left corner
        								int x1 = x + TRI_OFFS_XY[dir][0];
        								int x1 = x + TRI_OFFS_XY[dir][0];
        								int y1 = y + TRI_OFFS_XY[dir][1];
        								int y1 = y + TRI_OFFS_XY[dir][1];
        								int [] xyd = getNeibNode(x1, y1, subdiv);
        								int [] xyd = getNeibNode(x1, y1, subdiv);
        								boolean exists = false;
        								boolean exists = false;
        							if (tneib_indices[xyd[2]] != null) {
        								exists = (tneib_indices[xyd[2]] != null) && (tneib_indices[xyd[2]][xyd[1]][xyd[0]] >= 0); // is populated
        								exists = tneib_indices[xyd[2]][xyd[1]][xyd[0]] >= 0; // is populated
        								quad_corners[dir] = exists;
        								quad_corners[dir] = exists;
        							}
        								if (exists) {
        								if (exists) {
        									num_corn ++;
        									num_corn ++;
        								}
        								}
        							}
        							}
        						if ((num_corn >= 3) && quad_corners[0]) { // that triangle (TRI_DOWN_LEFT) should already exist
        							if (num_corn >= 3) {
        								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();
        								}
        								}
        								if (quad_corners[3]) {
        								if (quad_corners[3]) {
        									if (quad_corners[1]) {
        									if (quad_corners[1]) {
                							tris[btiley][btilex][y][x][1 << TRI_RIGHT_DOWNLEFT] = atri.getAndIncrement();
        										tris[btiley][btilex][y][x][TRI_RIGHT_DOWNLEFT] = atri.getAndIncrement();
        									} else {
        									} else {
                							tris[btiley][btilex][y][x][1 << TRI_DOWNRIGHT_LEFT] = atri.getAndIncrement();
        										tris[btiley][btilex][y][x][TRI_DOWNRIGHT_LEFT] = atri.getAndIncrement();
        									}
        									}
        								} else {
        								} else {
            							tris[btiley][btilex][y][x][1 << TRI_RIGHT_DOWN] = atri.getAndIncrement();
        									tris[btiley][btilex][y][x][TRI_RIGHT_DOWN] = atri.getAndIncrement();
        								}
        							}
        							}
        						}
        						}
        					}        					
        					}        					
@@ -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 {
        						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 {
        								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 {
        						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 {
        							
        							
        							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 {
			  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 {
		  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 {
				  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 {
				  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,9 +2015,14 @@ 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(