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 {
scenes, // final QuadCLT [] scenes,
scenes_sel, // final boolean [] scenes_sel, // null or which scenes to process
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
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)
......@@ -2080,11 +2080,6 @@ public class TexturedModel {
dbg_mesh_imgs = new double[tileClusters.length][dbg_scaled_width * dbg_scaled_height];
// maybe fill with NaN?
}
// double [][] dbg
/*
tp.getTilesX(), // int tilesX,
tp.getTilesY(), // int tilesY,
*/
for (int nslice = 0; nslice < tileClusters.length; nslice++){
if (dbg_tri_disp != null) {
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]}):
(new double[][] {dbg_tri_tri[nslice]}) ): null;
if (debugLevel > -1){
if (debugLevel > -2){
System.out.println("Generating cluster images from texture slice "+nslice);
}
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
for (int sub_i = 0; sub_i < indices.length; sub_i++) {
Rectangle roi = bounds[sub_i];
int cluster_index = indices[sub_i];
ImagePlus imp_texture_cluster = combined_textures[nslice];
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];
if (combined_alphas != null) {
alpha = new boolean[roi.height * roi.width];
for (int row = 0; row < roi.height; row++) {
int alpha_width = roi.width * transform_size;
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(
combined_alphas[nslice],
(roi.y + row) * width + roi.x,
(alpha_y0 + row) * width + alpha_x0,
alpha,
row * roi.width,
roi.width);
row * alpha_width,
alpha_width);
}
}
}
......@@ -2170,6 +2171,7 @@ public class TexturedModel {
"shape_id-"+cluster_index, // id
null, // class
roi, // scan.getTextureBounds(),
texture_bounds, // Rectangle texture_bounds, // if not null - allows trimmed combo textures
scan_selected, // scan.getSelected(),
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
clt_parameters.transform_size,
......@@ -2198,6 +2200,16 @@ public class TexturedModel {
}
// if (imp_textures[nslice] != null)
} // 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) {
ShowDoubleFloatArrays.showArrays(
dbg_tri_disp,
......
......@@ -235,19 +235,21 @@ public class TriMesh {
final int [] num_indices
) {
//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 Thread[] threads = ImageDtt.newThreadArray(TexturedModel.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
final int source_tile_width = full_image? tilesX : bounds.width;
final int source_pix_width = source_tile_width * tile_size;
final int source_tile_offsx = full_image? bounds.x : 0;
final int source_tile_offsy = full_image? 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_offsy = source_tile_offsy * tile_size;
// final int source_pix_offs = source_pix_offsx + source_pix_offsy * source_pix_width;
// final int sub_size = Math.max(tile_size / subdiv, 1);
final int source_tile_width = full_selection? tilesX : bounds.width;
// final int source_pix_width = source_tile_width * tile_size;
final int source_tile_offsx = full_selection? bounds.x : 0;
final int source_tile_offsy = full_selection? bounds.y : 0;
// final int source_pix_offsx = source_tile_offsx * 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_offsy = (full_alpha? bounds.y : 0) * tile_size;
final int source_pix_width = (full_alpha? tilesX : bounds.width) * tile_size;
final int btiles = bounds.width * bounds.height;
final AtomicInteger aindx = new AtomicInteger(0);
......@@ -474,7 +476,7 @@ public class TriMesh {
switch (dir) {
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 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;
}
return edge;
......@@ -652,7 +654,7 @@ public class TriMesh {
if (tris[btiley][btilex][y][x] == null) {
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);
......@@ -664,32 +666,33 @@ public class TriMesh {
x = subdiv - 1;
y = i - subdiv;
}
int num_corn = 0;
for (int dir = 1; dir < 4; dir++) { // skipping top-left corner
int x1 = x + TRI_OFFS_XY[dir][0];
int y1 = y + TRI_OFFS_XY[dir][1];
int [] xyd = getNeibNode(x1, y1, subdiv);
boolean exists = false;
if (tneib_indices[xyd[2]] != null) {
exists = tneib_indices[xyd[2]][xyd[1]][xyd[0]] >= 0; // is populated
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
int x1 = x + TRI_OFFS_XY[dir][0];
int y1 = y + TRI_OFFS_XY[dir][1];
int [] xyd = getNeibNode(x1, y1, subdiv);
boolean exists = false;
exists = (tneib_indices[xyd[2]] != null) && (tneib_indices[xyd[2]][xyd[1]][xyd[0]] >= 0); // is populated
quad_corners[dir] = exists;
if (exists) {
num_corn ++;
}
}
if (exists) {
num_corn ++;
}
}
if ((num_corn >= 3) && quad_corners[0]) { // that triangle (TRI_DOWN_LEFT) should already exist
if (tris[btiley][btilex][y][x] == null) {
tris[btiley][btilex][y][x] = TRI_NONE.clone();
}
if (quad_corners[3]) {
if (quad_corners[1]) {
tris[btiley][btilex][y][x][1 << TRI_RIGHT_DOWNLEFT] = atri.getAndIncrement();
} else {
tris[btiley][btilex][y][x][1 << TRI_DOWNRIGHT_LEFT] = atri.getAndIncrement();
}
} else {
tris[btiley][btilex][y][x][1 << TRI_RIGHT_DOWN] = atri.getAndIncrement();
if (num_corn >= 3) {
if (tris[btiley][btilex][y][x] == null) {
tris[btiley][btilex][y][x] = TRI_NONE.clone();
}
if (quad_corners[3]) {
if (quad_corners[1]) {
tris[btiley][btilex][y][x][TRI_RIGHT_DOWNLEFT] = atri.getAndIncrement();
} else {
tris[btiley][btilex][y][x][TRI_DOWNRIGHT_LEFT] = atri.getAndIncrement();
}
} else {
tris[btiley][btilex][y][x][TRI_RIGHT_DOWN] = atri.getAndIncrement();
}
}
}
}
......@@ -794,6 +797,8 @@ public class TriMesh {
// 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
// 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
final Thread[] threads = ImageDtt.newThreadArray(TexturedModel.THREADS_MAX);
......@@ -817,14 +822,18 @@ public class TriMesh {
if ((btx >= 0) && (btx < bwidth) && (bty >= 0) && (bty < bheight) &&
(indices[bty][btx] != null)) {
tneib_types[dir] = 0;
if (indices[bty][btx] != null) {
tneib_types[dir] = (indices[bty][btx].length > 1) ? 2 : 1;
}
has_full_neib |= (tneib_types[dir] == 1);
// if (indices[bty][btx] != null) {
tneib_types[dir] = (indices[bty][btx].length > 1) ? 2 : 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) {
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:
for (int dir = 0; dir < 4; dir++) {
int tneib = tneib_types[2*dir];
......@@ -868,6 +877,15 @@ public class TriMesh {
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
if (tri_index >= 0) {
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++) {
tri_indices[tri_index + i][0] = indx_1;
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][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 class_name,
Rectangle bounds,
Rectangle texture_bounds, // if not null - allows trimmed combo textures
// Below selected and disparity are bounds.width*bounds.height
boolean [] selected, // may be either tilesX * tilesY or bounds.width*bounds.height
double [] disparity, // if null, will use min_disparity
......@@ -1900,7 +1931,7 @@ public class TriMesh {
if (bounds == null) {
return; // not used in lwir
}
boolean display_triangles = debug_level > 0;
/*
......@@ -1933,8 +1964,19 @@ public class TriMesh {
indices, // int [][][][] 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)
*/
......@@ -1954,23 +1996,13 @@ public class TriMesh {
tile_size, // final int tile_size,
correctDistortions, // requires backdrop image to be corrected also
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
* large (tile size) and small (tile subdivisions) and add connections between large and small ones
*/
int [][] triangles = triangulateAll(
indices);
System.out.println("generateClusterX3d(): got "+triangles.length+" triangles");
final boolean plot_center = true;
final double line_color = 1.0;
final double center_color = 3.0;
......@@ -1983,18 +2015,23 @@ public class TriMesh {
plot_center, // final boolean plot_center,
line_color, // final double line_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) {
x3dOutput.addCluster(
texturePath,
id,
class_name,
texCoord,
worldXYZ,
triangles);
x3dOutput.addCluster(
texturePath,
id,
class_name,
texCoord,
worldXYZ,
triangles);
}
if (wfOutput != null) {
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