Commit 67228555 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

more tweaking

parent d059a2ac
Loading
Loading
Loading
Loading
+175 −20
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ public class LinkPlanes {
	public double     plMinStrength; //        =   0.1;  // Minimal total strength of a plane 
	public double     plMinStrength; //        =   0.1;  // Minimal total strength of a plane 
	public double     plMaxEigen; //           =   0.05; // Maximal eigenvalue of a plane 
	public double     plMaxEigen; //           =   0.05; // Maximal eigenvalue of a plane 
	public double     plEigenFloor; //         =   0.01; // Add to eigenvalues of each participating plane and result to validate connections 
	public double     plEigenFloor; //         =   0.01; // Add to eigenvalues of each participating plane and result to validate connections 
	public double     plEigenStick; //         =   20.0; // Consider plane to be a "stick" if second eigenvalue is below 


	public double     plWorstWorsening; //     =   2.0;  // Worst case worsening after merge
	public double     plWorstWorsening; //     =   2.0;  // Worst case worsening after merge
	public double     plWorstWorsening2; //    =   5.0;  // Worst case worsening for thin planes
	public double     plWorstWorsening2; //    =   5.0;  // Worst case worsening for thin planes
@@ -92,7 +93,8 @@ public class LinkPlanes {


		plDispNorm =        clt_parameters.plDispNorm;
		plDispNorm =        clt_parameters.plDispNorm;
		plMaxEigen =        clt_parameters.plMaxEigen;
		plMaxEigen =        clt_parameters.plMaxEigen;
		plEigenFloor =      clt_parameters.plEigenFloor;    // final double eigenFloor, // Add to eigenvalues of each participating plane and result to validate connections 
		plEigenFloor =      clt_parameters.plEigenFloor; 
		plEigenStick =      clt_parameters.plEigenStick; 
		plMinStrength =     clt_parameters.plMinStrength;
		plMinStrength =     clt_parameters.plMinStrength;
		plMaxOverlap =      clt_parameters.plMaxOverlap;
		plMaxOverlap =      clt_parameters.plMaxOverlap;
		
		
@@ -963,6 +965,9 @@ public class LinkPlanes {
			boolean hasConflict(LinkPair lp){
			boolean hasConflict(LinkPair lp){
				return (src == lp.src) || (dst == lp.dst);
				return (src == lp.src) || (dst == lp.dst);
			}
			}
			public String toString(){
				return String.format("%d-(%6.3f)->%d", src,cost,dst);
			}
			
			
		}
		}
		for (int ithread = 0; ithread < threads.length; ithread++) {
		for (int ithread = 0; ithread < threads.length; ithread++) {
@@ -981,16 +986,16 @@ public class LinkPlanes {
								if ((nsTile >= 0) && (planes[nsTile] != null)){
								if ((nsTile >= 0) && (planes[nsTile] != null)){
									int num_dp = planes[nsTile].length;
									int num_dp = planes[nsTile].length;
									double [][] inter_costs = new double [num_sp][num_dp];
									double [][] inter_costs = new double [num_sp][num_dp];
									for (int np0 = 0; np0 < num_sp; np0++) if (planes[np0]!=null){
									for (int np0 = 0; np0 < num_sp; np0++) if (planes[nsTile0][np0]!=null){
										for (int np = 0; np < num_dp; np++)if (planes[np]!=null){
										for (int np = 0; np < num_dp; np++)if (planes[nsTile][np]!=null){
											inter_costs[np0][np] = 0.5* (
											inter_costs[np0][np] = 0.5* (
													planes[nsTile0][np0].getLinkCosts(dir, np)+
													planes[nsTile0][np0].getLinkCosts(dir, np)+
													planes[nsTile][np].getLinkCosts(dir_back, np0));
													planes[nsTile][np].getLinkCosts(dir_back, np0));
										}
										}
									}
									}
									HashSet<LinkPair> pairs_set = new HashSet<LinkPair>();
									HashSet<LinkPair> pairs_set = new HashSet<LinkPair>();
									for (int np0 = 0; np0 < num_sp; np0++) if (planes[np0]!=null){
									for (int np0 = 0; np0 < num_sp; np0++) if (planes[nsTile0][np0]!=null){
										for (int np = 0; np < num_dp; np++)if (planes[np]!=null){
										for (int np = 0; np < num_dp; np++)if (planes[nsTile][np]!=null){
											if (!Double.isNaN(inter_costs[np0][np]) && (inter_costs[np0][np] <= max_cost)){
											if (!Double.isNaN(inter_costs[np0][np]) && (inter_costs[np0][np] <= max_cost)){
												pairs_set.add(new LinkPair(np0, np, inter_costs[np0][np]));
												pairs_set.add(new LinkPair(np0, np, inter_costs[np0][np]));
											}
											}
@@ -998,7 +1003,7 @@ public class LinkPlanes {
									}
									}
									HashSet<LinkPair> links_set = new HashSet<LinkPair>();
									HashSet<LinkPair> links_set = new HashSet<LinkPair>();
									while (!pairs_set.isEmpty()){
									while (!pairs_set.isEmpty()){
										LinkPair link =Collections.max(pairs_set, new Comparator<LinkPair>() {
										LinkPair link =Collections.min(pairs_set, new Comparator<LinkPair>() {
											@Override
											@Override
											public int compare(LinkPair lhs, LinkPair rhs) { // ascending
											public int compare(LinkPair lhs, LinkPair rhs) { // ascending
												return (lhs.cost < rhs.cost) ? -1 : (lhs.cost > rhs.cost ) ? 1 : 0;
												return (lhs.cost < rhs.cost) ? -1 : (lhs.cost > rhs.cost ) ? 1 : 0;
@@ -2324,14 +2329,22 @@ public class LinkPlanes {
		ImageDtt.startAndJoin(threads);
		ImageDtt.startAndJoin(threads);
		return valid_candidates;
		return valid_candidates;
	}
	}
	
	
	/**
	 * Possible problem is that "normalizing" merge quality for low weights is not applicable for "star" plane that include neighhbors
	 * Switch to a single "cost" function (costSameTileConnectionsAlt())
	 * @param planes
	 * @param merge_candidates
	 * @param valid_candidates
	 * @param debugLevel
	 * @param dbg_X
	 * @param dbg_Y
	 */
	public  void costSameTileConnections(
	public  void costSameTileConnections(
			final boolean ignore_weights,
			final double threshold_worst,
			final double threshold_world_worst,
			final TilePlanes.PlaneData [][] planes,
			final TilePlanes.PlaneData [][] planes,
			final int [][][]                merge_candidates,
			final int [][][]                merge_candidates,
			final boolean [][][]            valid_candidates, // will be updated
			final boolean [][][]            valid_candidates, // will be updated
//			final boolean    merge_low_eigen,
			final int                       debugLevel,
			final int                       debugLevel,
			final int                       dbg_X,
			final int                       dbg_X,
			final int                       dbg_Y)
			final int                       dbg_Y)
@@ -2343,8 +2356,6 @@ public class LinkPlanes {
		final int stilesX =       (tilesX + superTileSize -1)/superTileSize;  
		final int stilesX =       (tilesX + superTileSize -1)/superTileSize;  
		final int stilesY =       (tilesY + superTileSize -1)/superTileSize;
		final int stilesY =       (tilesY + superTileSize -1)/superTileSize;
		final int nStiles =       stilesX * stilesY;
		final int nStiles =       stilesX * stilesY;
		final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
//		final boolean [][] merge_pairs = new boolean [nStiles][];
		final double [][][][][][]  merged_neib_ev = new double [nStiles][][][][][];
		final double [][][][][][]  merged_neib_ev = new double [nStiles][][][][][];
		final int debug_stile = dbg_Y * stilesX + dbg_X;
		final int debug_stile = dbg_Y * stilesX + dbg_X;
		final Thread[] threads = ImageDtt.newThreadArray((debugLevel > 1)? 1 : st.tileProcessor.threadsMax);
		final Thread[] threads = ImageDtt.newThreadArray((debugLevel > 1)? 1 : st.tileProcessor.threadsMax);
@@ -2401,8 +2412,153 @@ public class LinkPlanes {
											}
											}
											
											
										}
										}
///		final double threshold_worst,
										if (dl>0){
//		final double threshold_world_worst,
											double [][] costs = new double[2][]; 
											costs[0] = getFitQualities(
													planes[nsTile0][np1].getNonexclusiveStarFb(), // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
													planes[nsTile0][np2].getNonexclusiveStarFb(),          // TilePlanes.PlaneData plane2,
													Double.NaN, // double               merged_ev,    // if NaN will calculate assuming the same supertile
													Double.NaN, // double               merged_ev_eq, // if NaN will calculate assuming the same supertile
													Double.NaN, // double               merged_wev,    // if NaN will calculate assuming the same supertile - for world
													Double.NaN, // double               merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
													nsTile0+":"+np1+":"+np2,  // String prefix,
													0); // int debugLevel)
											costs[1] = getFitQualities(
													planes[nsTile0][np1].getNonexclusiveStarEqFb(), // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
													planes[nsTile0][np2].getNonexclusiveStarEqFb(),          // TilePlanes.PlaneData plane2,
													Double.NaN, // double               merged_ev,    // if NaN will calculate assuming the same supertile
													Double.NaN, // double               merged_ev_eq, // if NaN will calculate assuming the same supertile
													Double.NaN, // double               merged_wev,    // if NaN will calculate assuming the same supertile - for world
													Double.NaN, // double               merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
													nsTile0+":"+np1+":"+np2,  // String prefix,
													0); // int debugLevel)
											System.out.println("costSameTileConnections(): nsTile="+nsTile0+":"+np1+":"+np2+" costs:");
											System.out.print("costSameTileConnections(): nsTile="+nsTile0+":"+np1+":"+np2+" costs weighted: ");
											for (int i = 0; i < costs[0].length;i++) {
												System.out.print(costs[0][i]+" ");
											}
											System.out.println();
											System.out.print("costSameTileConnections(): nsTile="+nsTile0+":"+np1+":"+np2+" costs equalized: ");
											for (int i = 0; i < costs[1].length;i++) {
												System.out.print(costs[1][i]+" ");
											}
											System.out.println();
										}
								}
							}
						}
					}
				}
			};
		}		      
		ImageDtt.startAndJoin(threads);
	}
	public  void costSameTileConnectionsAlt(
			final double                    threshold,
			final double                    threshold_nostar,
			final TilePlanes.PlaneData [][] planes,
			final int [][][]                merge_candidates,
			final boolean [][][]            valid_candidates, // will be updated
			final int                       debugLevel,
			final int                       dbg_X,
			final int                       dbg_Y)
	{
		final int tilesX =        st.tileProcessor.getTilesX();
		final int tilesY =        st.tileProcessor.getTilesY();
		final int superTileSize = st.tileProcessor.getSuperTileSize();
		//				final int tileSize =      tileProcessor.getTileSize();
		final int stilesX =       (tilesX + superTileSize -1)/superTileSize;  
		final int stilesY =       (tilesY + superTileSize -1)/superTileSize;
		final int nStiles =       stilesX * stilesY;
		final double [][][][][][]  merged_neib_ev = new double [nStiles][][][][][];
		final int debug_stile = dbg_Y * stilesX + dbg_X;
		final Thread[] threads = ImageDtt.newThreadArray((debugLevel > 1)? 1 : st.tileProcessor.threadsMax);
		final AtomicInteger ai = new AtomicInteger(0);
		for (int ithread = 0; ithread < threads.length; ithread++) {
			threads[ithread] = new Thread() {
				public void run() {
					for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) if ( merge_candidates[nsTile0] != null) {
						int dl = ((debugLevel > 0) && (nsTile0 == debug_stile)) ? 3: ((debugLevel > 1) ? 2:0);
						if (dl > 2){
							System.out.println("costSameTileConnectionsAlt(): nsTile="+nsTile0);
						}
						int n_planes = planes[nsTile0].length;
						//						overlap_merge_candidates[nsTile] = new boolean [n_planes][n_planes];
						merged_neib_ev[nsTile0] = new double [n_planes][n_planes][4][][];
						// get original directions
						for (int np1 = 0; np1 < planes[nsTile0].length; np1++) if (planes[nsTile0][np1] != null){
							for (int np2 = np1 + 1; np2 < planes[nsTile0].length; np2++) if (planes[nsTile0][np2] != null){
								if (valid_candidates[nsTile0][np1][np2]) { // only check pair considered valid
									String prefix = "costSameTileConnectionsAlt() fit weighted: nsTile0="+nsTile0+" np1="+np1+" np2="+np2;
									double [] costs = new double[2]; 
									costs[0] = getLinkCost(
											planes[nsTile0][np1].getNonexclusiveStarFb(), // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
											planes[nsTile0][np2].getNonexclusiveStarFb(),          // TilePlanes.PlaneData plane2,
											Double.NaN, // double               merged_ev,    // if NaN will calculate assuming the same supertile
											Double.NaN, // double               merged_ev_eq, // if NaN will calculate assuming the same supertile
											Double.NaN, // double               merged_wev,    // if NaN will calculate assuming the same supertile - for world
											Double.NaN, // double               merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
											prefix,  // String prefix,
											0); // int debugLevel)
									prefix = "costSameTileConnectionsAlt() fit equal weight: nsTile0="+nsTile0+" np1="+np1+" np2="+np2;
									costs[1] = getLinkCost(
											planes[nsTile0][np1].getNonexclusiveStarEqFb(), // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
											planes[nsTile0][np2].getNonexclusiveStarEqFb(),          // TilePlanes.PlaneData plane2,
											Double.NaN, // double               merged_ev,    // if NaN will calculate assuming the same supertile
											Double.NaN, // double               merged_ev_eq, // if NaN will calculate assuming the same supertile
											Double.NaN, // double               merged_wev,    // if NaN will calculate assuming the same supertile - for world
											Double.NaN, // double               merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
											prefix,  // String prefix,
											0); // int debugLevel)
									boolean star1 = (planes[nsTile0][np1].getNonexclusiveStar() != null) && (planes[nsTile0][np2].getNonexclusiveStar() != null);
									boolean star2 = (planes[nsTile0][np1].getNonexclusiveStarEq() != null) && (planes[nsTile0][np2].getNonexclusiveStarEq() != null);
									boolean fit1 = 	costs[0] < (star1 ? threshold : threshold_nostar);
									boolean fit2 = 	costs[1] < (star2 ? threshold : threshold_nostar);
									if (!fit1 || !fit2){
										valid_candidates[nsTile0][np1][np2] = false;
										valid_candidates[nsTile0][np2][np1] = false;
										if (dl > -1){
											System.out.println("costSameTileConnectionsAlt(): nsTile="+nsTile0+":"+np1+":"+np2+
													" REMOVING PAIR, fit1="+fit1+" fit2="+fit2+ " (star1="+star1+", star2="+star2+")");
										}
									} else {
										if (dl > -1){
											System.out.println("costSameTileConnectionsAlt(): nsTile="+nsTile0+":"+np1+":"+np2+
													" KEEPING PAIR, fit1="+fit1+" fit2="+fit2+ " (star1="+star1+", star2="+star2+")");
										}
									}
									if (dl>0){
										double [][] costs0 = new double[2][]; 
										costs0[0] = getFitQualities(
												planes[nsTile0][np1].getNonexclusiveStarFb(), // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
												planes[nsTile0][np2].getNonexclusiveStarFb(),          // TilePlanes.PlaneData plane2,
												Double.NaN, // double               merged_ev,    // if NaN will calculate assuming the same supertile
												Double.NaN, // double               merged_ev_eq, // if NaN will calculate assuming the same supertile
												Double.NaN, // double               merged_wev,    // if NaN will calculate assuming the same supertile - for world
												Double.NaN, // double               merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
												nsTile0+":"+np1+":"+np2,  // String prefix,
												0); // int debugLevel)
										costs0[1] = getFitQualities(
												planes[nsTile0][np1].getNonexclusiveStarEqFb(), // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
												planes[nsTile0][np2].getNonexclusiveStarEqFb(),          // TilePlanes.PlaneData plane2,
												Double.NaN, // double               merged_ev,    // if NaN will calculate assuming the same supertile
												Double.NaN, // double               merged_ev_eq, // if NaN will calculate assuming the same supertile
												Double.NaN, // double               merged_wev,    // if NaN will calculate assuming the same supertile - for world
												Double.NaN, // double               merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
												nsTile0+":"+np1+":"+np2,  // String prefix,
												0); // int debugLevel)
										System.out.println("costSameTileConnections(): nsTile="+nsTile0+":"+np1+":"+np2+" costs:");
										System.out.print("costSameTileConnections(): nsTile="+nsTile0+":"+np1+":"+np2+" costs weighted: ");
										for (int i = 0; i < costs0[0].length;i++) {
											System.out.print(costs0[0][i]+" ");
										}
										System.out.println();
										System.out.print("costSameTileConnections(): nsTile="+nsTile0+":"+np1+":"+np2+" costs equalized: ");
										for (int i = 0; i < costs0[1].length;i++) {
											System.out.print(costs0[1][i]+" ");
										}
										System.out.println();
									}
								}
								}
							}
							}
						}
						}
@@ -2411,7 +2567,6 @@ public class LinkPlanes {
			};
			};
		}		      
		}		      
		ImageDtt.startAndJoin(threads);
		ImageDtt.startAndJoin(threads);
//		return merged_neib_ev;
	}
	}


	public  double  [][][][][][] costSameTileConnectionsOld(
	public  double  [][][][][][] costSameTileConnectionsOld(
+26 −3
Original line number Original line Diff line number Diff line
@@ -237,7 +237,7 @@ public class TilePlanes {
			double [] px_py = getCenterPxPy();
			double [] px_py = getCenterPxPy();
			if (zxy != null) s += String.format("\nzxy =     [%8.3f, %8.3f, %8.3f] (pix)",zxy[0],zxy[1]+px_py[0],zxy[2]+px_py[1]);
			if (zxy != null) s += String.format("\nzxy =     [%8.3f, %8.3f, %8.3f] (pix)",zxy[0],zxy[1]+px_py[0],zxy[2]+px_py[1]);
			else  s +=                          "\nzxy =     null";
			else  s +=                          "\nzxy =     null";
			if (values != null)	s += String.format(", values = [%8.3f, %8.3f, %8.3f] pix^2",values[0],values[1],values[2]);
			if (values != null)	s += String.format(", values = [%8.5f, %8.4f, %8.3f] pix^2",values[0],values[1],values[2]);
			else  s +=                             " values = null";
			else  s +=                             " values = null";
			if (vectors != null) s += String.format("\nvectors = [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f]",
			if (vectors != null) s += String.format("\nvectors = [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f]",
					vectors[0][0],vectors[0][1],vectors[0][2], vectors[1][0],vectors[1][1],vectors[1][2], vectors[2][0],vectors[2][1],vectors[2][2]);
					vectors[0][0],vectors[0][1],vectors[0][2], vectors[1][0],vectors[1][1],vectors[1][2], vectors[2][0],vectors[2][1],vectors[2][2]);
@@ -247,7 +247,7 @@ public class TilePlanes {
			else s +=                                  " normal =   null";
			else s +=                                  " normal =   null";
			if (wxyz != null)       s += String.format("\nwxyz =    [%8.2f, %8.2f, %8.2f] (m)",wxyz[0],wxyz[1],wxyz[2]);
			if (wxyz != null)       s += String.format("\nwxyz =    [%8.2f, %8.2f, %8.2f] (m)",wxyz[0],wxyz[1],wxyz[2]);
			else s +=                                  "\nwxyz =  null";
			else s +=                                  "\nwxyz =  null";
			if (wvalues != null)    s += String.format(" wvals = [%8.2f, %8.2f, %8.2f] (m^2)",wvalues[0],wvalues[1],wvalues[2]);
			if (wvalues != null)    s += String.format(" wvals = [%8.4f, %8.3f, %8.2f] (m^2)",wvalues[0],wvalues[1],wvalues[2]);
			else  s +=                                 " wvals =  null";
			else  s +=                                 " wvals =  null";
			if (wvectors != null) s += String.format("\nwvect =   [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f]",
			if (wvectors != null) s += String.format("\nwvect =   [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f], [%8.5f, %8.5f, %8.5f]",
					wvectors[0][0],wvectors[0][1],wvectors[0][2], wvectors[1][0],wvectors[1][1],wvectors[1][2], wvectors[2][0],wvectors[2][1],wvectors[2][2]);
					wvectors[0][0],wvectors[0][1],wvectors[0][2], wvectors[1][0],wvectors[1][1],wvectors[1][2], wvectors[2][0],wvectors[2][1],wvectors[2][2]);
@@ -287,7 +287,30 @@ public class TilePlanes {
						nonexclusiveStarEq.world_xyz[0],nonexclusiveStarEq.world_xyz[1],nonexclusiveStarEq.world_xyz[2]);
						nonexclusiveStarEq.world_xyz[0],nonexclusiveStarEq.world_xyz[1],nonexclusiveStarEq.world_xyz[2]);
				else s +=                                  " normal =   null";
				else s +=                                  " normal =   null";
			}
			}
			s+="\n\n";
			s+="\n";
			if (link_costs != null){
				for (int dir = 0; dir < link_costs.length; dir++){
					s+=String.format("dir=%d: ", dir);
					if (link_costs[dir] != null) {
						int best_np = -1;
						for (int np = 0; np < link_costs[dir].length; np++){
							if (!Double.isNaN(link_costs[dir][np]) && ((best_np < 0) || (link_costs[dir][np] < link_costs[dir][best_np]))){
								best_np = np;
							}
						}
						for (int np = 0; np < link_costs[dir].length; np++){
							if (np == best_np){
								s+=String.format("%7.3f[%d] ", link_costs[dir][np],np);
								
							} else {
								s+=String.format("%7.3f    ", link_costs[dir][np]);
							}
						}
					}
					s+="\n";
				}
			}
			s+="\n";
			return s;
			return s;
		}
		}
		
		
+47 −5
Original line number Original line Diff line number Diff line
@@ -3317,19 +3317,33 @@ public class TileProcessor {
					clt_parameters.tileX,
					clt_parameters.tileX,
					clt_parameters.tileY);
					clt_parameters.tileY);


//			 * Possible problem is that "normalizing" merge quality for low weights is not applicable for "star" plane that include neighhbors
//			 * Switch to a single "cost" function (costSameTileConnectionsAlt())
// Still - how to merge stray tiles that do not have neighbors/star? Still merge them "old way"	(costSameTileConnections()) if at least 1 does not
//			have a "star"


//			double  [][][][][][]  merge_cost_data = 
//			double  [][][][][][]  merge_cost_data = 
					lp.costSameTileConnections(
					lp.costSameTileConnections(
					false, // final boolean ignore_weights,
					st.planes, // final TilePlanes.PlaneData [][] planes,
					1000.0, // final double threshold_worst,
					1000.0, //final double threshold_world_worst,
					st.planes, // ffinal TilePlanes.PlaneData [][] planes,
					merge_candidates,       // final int [][][] merge_candidates,
					merge_candidates,       // final int [][][] merge_candidates,
					plane_nooverlaps, // final boolean [][][]   valid_candidates, // will be updated
					plane_nooverlaps, // final boolean [][][]   valid_candidates, // will be updated
					2,                      // -1, // debugLevel,                  // final int        debugLevel)
					2,                      // -1, // debugLevel,                  // final int        debugLevel)
					clt_parameters.tileX,
					clt_parameters.tileX,
					clt_parameters.tileY);
					clt_parameters.tileY);
//			System.out.println("merge_cost_data.length = " + merge_cost_data.length);
//			System.out.println("merge_cost_data.length = " + merge_cost_data.length);
					
					lp.costSameTileConnectionsAlt(
					5.0,  // final double         threshold,
					10.0, // final double         threshold_nostar,

					st.planes, // final TilePlanes.PlaneData [][] planes,
					merge_candidates,       // final int [][][] merge_candidates,
					plane_nooverlaps, // final boolean [][][]   valid_candidates, // will be updated
					2,                      // -1, // debugLevel,                  // final int        debugLevel)
					clt_parameters.tileX,
					clt_parameters.tileY);
					
					
			int [][][] merge_groups = lp.extractMergeSameTileGroups(
			int [][][] merge_groups = lp.extractMergeSameTileGroups(
					st.planes,              // final TilePlanes.PlaneData [][] planes,
					st.planes,              // final TilePlanes.PlaneData [][] planes,
					merge_candidates,       // final int [][][] merge_candidates,
					merge_candidates,       // final int [][][] merge_candidates,
@@ -3805,6 +3819,12 @@ public class TileProcessor {
					0, // 1,// 0, // final int debugLevel)
					0, // 1,// 0, // final int debugLevel)
					clt_parameters.tileX,
					clt_parameters.tileX,
					clt_parameters.tileY);
					clt_parameters.tileY);
			lp.interPlaneCosts(
					st.planes_mod, // final TilePlanes.PlaneData [][] planes,			
					2, // -1, // debugLevel,                  // final int        debugLevel)
					clt_parameters.tileX,
					clt_parameters.tileY);
			// recalculate links? more smooth?
			
			
		} else {
		} else {
			st.planes_mod = st.planes; // just use the measured ones
			st.planes_mod = st.planes; // just use the measured ones
@@ -3824,6 +3844,22 @@ public class TileProcessor {
					clt_parameters.tileY); 
					clt_parameters.tileY); 


			int [] wh = st.getShowPlanesWidthHeight();
			int [] wh = st.getShowPlanesWidthHeight();
			double [][] plane_data_nonan_meas = st.getShowPlanes(
					        st.getPlanes(),
							clt_parameters.plMinStrength, //  minWeight,
							clt_parameters.plMaxEigen, //  maxEigen,
							clt_parameters.plDispNorm,
							false, //boolean use_NaN)
							0.0,
							10.0);
			double [][] plane_data_nan_meas = st.getShowPlanes(
					        st.getPlanes(),
							clt_parameters.plMinStrength, //  minWeight,
							clt_parameters.plMaxEigen, //  maxEigen,
							clt_parameters.plDispNorm,
							true, //boolean use_NaN)
							0.0,
							10.0);
			double [][] plane_data_nonan = st.getShowPlanes(
			double [][] plane_data_nonan = st.getShowPlanes(
					(planes_mod != null) ? st.getPlanesMod():st.getPlanes(),
					(planes_mod != null) ? st.getPlanesMod():st.getPlanes(),
							clt_parameters.plMinStrength, //  minWeight,
							clt_parameters.plMinStrength, //  minWeight,
@@ -3840,8 +3876,14 @@ public class TileProcessor {
							true, //boolean use_NaN)
							true, //boolean use_NaN)
							0.0,
							0.0,
							10.0);
							10.0);
			double [][] plane_data = new double [plane_data_nonan.length + plane_data_nan.length + 3][];
			double [][] plane_data = new double [plane_data_nonan_meas.length + plane_data_nan_meas.length+ plane_data_nonan.length + plane_data_nan.length + 3][];
			int indx = 0;
			int indx = 0;
			for (int i = 0; i < plane_data_nonan_meas.length; i++){
				plane_data[indx++] = plane_data_nonan_meas[i];
			}
			for (int i = 0; i < plane_data_nan_meas.length; i++){
				plane_data[indx++] = plane_data_nan_meas[i];
			}
			for (int i = 0; i < plane_data_nonan.length; i++){
			for (int i = 0; i < plane_data_nonan.length; i++){
				plane_data[indx++] = plane_data_nonan[i];
				plane_data[indx++] = plane_data_nonan[i];
			}
			}