Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
18261553
Commit
18261553
authored
May 20, 2017
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
trying another way to resolve conflicts/ improve supertile connections
parent
1ca1c6d0
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
812 additions
and
109 deletions
+812
-109
ConnectionCosts.java
src/main/java/ConnectionCosts.java
+3
-4
EyesisCorrectionParameters.java
src/main/java/EyesisCorrectionParameters.java
+22
-1
SuperTiles.java
src/main/java/SuperTiles.java
+412
-99
TileProcessor.java
src/main/java/TileProcessor.java
+13
-5
TwoLayerNeighbors.java
src/main/java/TwoLayerNeighbors.java
+362
-0
No files found.
src/main/java/ConnectionCosts.java
View file @
18261553
import
java.awt.Point
;
import
java.util.HashMap
;
import
java.util.HashSet
;
/**
/**
**
**
** ConnectionCosts - calculate and incrementally update cost of supertile connections
** ConnectionCosts - calculate and incrementally update cost of supertile connections
...
@@ -25,6 +21,9 @@ import java.util.HashSet;
...
@@ -25,6 +21,9 @@ import java.util.HashSet;
** -----------------------------------------------------------------------------**
** -----------------------------------------------------------------------------**
**
**
*/
*/
import
java.awt.Point
;
import
java.util.HashMap
;
import
java.util.HashSet
;
public
class
ConnectionCosts
{
public
class
ConnectionCosts
{
TilePlanes
.
PlaneData
[][]
planes
=
null
;
TilePlanes
.
PlaneData
[][]
planes
=
null
;
...
...
src/main/java/EyesisCorrectionParameters.java
View file @
18261553
...
@@ -2175,7 +2175,12 @@ public class EyesisCorrectionParameters {
...
@@ -2175,7 +2175,12 @@ public class EyesisCorrectionParameters {
public
double
plMaxWorldSin2
=
0.1
;
// Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable
public
double
plMaxWorldSin2
=
0.1
;
// Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable
public
double
plWeakWorsening
=
1.0
;
// Relax merge requirements for weaker planes
public
double
plWeakWorsening
=
1.0
;
// Relax merge requirements for weaker planes
public
int
plStarSteps
=
1
;
// How far to look around when calculationg connection cost
public
boolean
plConflDualTri
=
false
;
// Resolve dual triangles conflict (odoodo)
public
boolean
plConflMulti
=
false
;
// Resolve multiple odo triangles conflicts
public
boolean
plConflDiag
=
false
;
// Resolve diagonal (ood) conflicts
public
boolean
plConflStar
=
true
;
// Resolve all conflicts around a supertile
public
int
plStarSteps
=
2
;
// How far to look around when calculationg connection cost
public
double
plStarOrtho
=
0.5
;
// When calculating cost for the connections scale 4 ortho neighbors
public
double
plStarOrtho
=
0.5
;
// When calculating cost for the connections scale 4 ortho neighbors
public
double
plStarDiag
=
0.25
;
// When calculating cost for the connections scale 4 diagonal neighbors
public
double
plStarDiag
=
0.25
;
// When calculating cost for the connections scale 4 diagonal neighbors
public
double
plStarPwr
=
0.5
;
// Divide cost by number of connections to this power
public
double
plStarPwr
=
0.5
;
// Divide cost by number of connections to this power
...
@@ -2529,6 +2534,10 @@ public class EyesisCorrectionParameters {
...
@@ -2529,6 +2534,10 @@ public class EyesisCorrectionParameters {
properties
.
setProperty
(
prefix
+
"plMaxWorldSin2"
,
this
.
plMaxWorldSin2
+
""
);
properties
.
setProperty
(
prefix
+
"plMaxWorldSin2"
,
this
.
plMaxWorldSin2
+
""
);
properties
.
setProperty
(
prefix
+
"plWeakWorsening"
,
this
.
plWeakWorsening
+
""
);
properties
.
setProperty
(
prefix
+
"plWeakWorsening"
,
this
.
plWeakWorsening
+
""
);
properties
.
setProperty
(
prefix
+
"plConflDualTri"
,
this
.
plConflDualTri
+
""
);
properties
.
setProperty
(
prefix
+
"plConflMulti"
,
this
.
plConflMulti
+
""
);
properties
.
setProperty
(
prefix
+
"plConflDiag"
,
this
.
plConflDiag
+
""
);
properties
.
setProperty
(
prefix
+
"plConflStar"
,
this
.
plConflStar
+
""
);
properties
.
setProperty
(
prefix
+
"plStarSteps"
,
this
.
plStarSteps
+
""
);
properties
.
setProperty
(
prefix
+
"plStarSteps"
,
this
.
plStarSteps
+
""
);
properties
.
setProperty
(
prefix
+
"plStarOrtho"
,
this
.
plStarOrtho
+
""
);
properties
.
setProperty
(
prefix
+
"plStarOrtho"
,
this
.
plStarOrtho
+
""
);
properties
.
setProperty
(
prefix
+
"plStarDiag"
,
this
.
plStarDiag
+
""
);
properties
.
setProperty
(
prefix
+
"plStarDiag"
,
this
.
plStarDiag
+
""
);
...
@@ -2863,6 +2872,10 @@ public class EyesisCorrectionParameters {
...
@@ -2863,6 +2872,10 @@ public class EyesisCorrectionParameters {
if
(
properties
.
getProperty
(
prefix
+
"plMaxWorldSin2"
)!=
null
)
this
.
plMaxWorldSin2
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plMaxWorldSin2"
));
if
(
properties
.
getProperty
(
prefix
+
"plMaxWorldSin2"
)!=
null
)
this
.
plMaxWorldSin2
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plMaxWorldSin2"
));
if
(
properties
.
getProperty
(
prefix
+
"plWeakWorsening"
)!=
null
)
this
.
plWeakWorsening
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plWeakWorsening"
));
if
(
properties
.
getProperty
(
prefix
+
"plWeakWorsening"
)!=
null
)
this
.
plWeakWorsening
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plWeakWorsening"
));
if
(
properties
.
getProperty
(
prefix
+
"plConflDualTri"
)!=
null
)
this
.
plConflDualTri
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"plConflDualTri"
));
if
(
properties
.
getProperty
(
prefix
+
"plConflMulti"
)!=
null
)
this
.
plConflMulti
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"plConflMulti"
));
if
(
properties
.
getProperty
(
prefix
+
"plConflDiag"
)!=
null
)
this
.
plConflDiag
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"plConflDiag"
));
if
(
properties
.
getProperty
(
prefix
+
"plConflStar"
)!=
null
)
this
.
plConflStar
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"plConflStar"
));
if
(
properties
.
getProperty
(
prefix
+
"plStarSteps"
)!=
null
)
this
.
plStarSteps
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"plStarSteps"
));
if
(
properties
.
getProperty
(
prefix
+
"plStarSteps"
)!=
null
)
this
.
plStarSteps
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"plStarSteps"
));
if
(
properties
.
getProperty
(
prefix
+
"plStarOrtho"
)!=
null
)
this
.
plStarOrtho
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plStarOrtho"
));
if
(
properties
.
getProperty
(
prefix
+
"plStarOrtho"
)!=
null
)
this
.
plStarOrtho
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plStarOrtho"
));
if
(
properties
.
getProperty
(
prefix
+
"plStarDiag"
)!=
null
)
this
.
plStarDiag
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plStarDiag"
));
if
(
properties
.
getProperty
(
prefix
+
"plStarDiag"
)!=
null
)
this
.
plStarDiag
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plStarDiag"
));
...
@@ -3225,6 +3238,10 @@ public class EyesisCorrectionParameters {
...
@@ -3225,6 +3238,10 @@ public class EyesisCorrectionParameters {
gd
.
addNumericField
(
"Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable"
,
this
.
plMaxWorldSin2
,
6
);
gd
.
addNumericField
(
"Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable"
,
this
.
plMaxWorldSin2
,
6
);
gd
.
addNumericField
(
"Relax merge requirements for weaker planes"
,
this
.
plWeakWorsening
,
6
);
gd
.
addNumericField
(
"Relax merge requirements for weaker planes"
,
this
.
plWeakWorsening
,
6
);
gd
.
addCheckbox
(
"Resolve dual triangles conflict (odoodo)"
,
this
.
plConflDualTri
);
gd
.
addCheckbox
(
"Resolve multiple odo triangles conflicts"
,
this
.
plConflMulti
);
gd
.
addCheckbox
(
"Resolve diagonal (ood) conflicts"
,
this
.
plConflDiag
);
gd
.
addCheckbox
(
"Resolve all conflicts around a supertile"
,
this
.
plConflStar
);
gd
.
addNumericField
(
"How far to look around when calculationg connection cost"
,
this
.
plStarSteps
,
0
);
gd
.
addNumericField
(
"How far to look around when calculationg connection cost"
,
this
.
plStarSteps
,
0
);
gd
.
addNumericField
(
"When calculating cost for the connections scale 4 ortho neighbors"
,
this
.
plStarOrtho
,
6
);
gd
.
addNumericField
(
"When calculating cost for the connections scale 4 ortho neighbors"
,
this
.
plStarOrtho
,
6
);
gd
.
addNumericField
(
"When calculating cost for the connections scale 4 diagonal neighbors"
,
this
.
plStarDiag
,
6
);
gd
.
addNumericField
(
"When calculating cost for the connections scale 4 diagonal neighbors"
,
this
.
plStarDiag
,
6
);
...
@@ -3572,6 +3589,10 @@ public class EyesisCorrectionParameters {
...
@@ -3572,6 +3589,10 @@ public class EyesisCorrectionParameters {
this
.
plMaxWorldSin2
=
gd
.
getNextNumber
();
this
.
plMaxWorldSin2
=
gd
.
getNextNumber
();
this
.
plWeakWorsening
=
gd
.
getNextNumber
();
this
.
plWeakWorsening
=
gd
.
getNextNumber
();
this
.
plConflDualTri
=
gd
.
getNextBoolean
();
this
.
plConflMulti
=
gd
.
getNextBoolean
();
this
.
plConflDiag
=
gd
.
getNextBoolean
();
this
.
plConflStar
=
gd
.
getNextBoolean
();
this
.
plStarSteps
=
(
int
)
gd
.
getNextNumber
();
this
.
plStarSteps
=
(
int
)
gd
.
getNextNumber
();
this
.
plStarOrtho
=
gd
.
getNextNumber
();
this
.
plStarOrtho
=
gd
.
getNextNumber
();
this
.
plStarDiag
=
gd
.
getNextNumber
();
this
.
plStarDiag
=
gd
.
getNextNumber
();
...
...
src/main/java/SuperTiles.java
View file @
18261553
...
@@ -4061,58 +4061,6 @@ public class SuperTiles{
...
@@ -4061,58 +4061,6 @@ public class SuperTiles{
}
}
public
int
[]
resolveMultiTriangularConflicts
(
int
[][][]
conflicts
,
Conflicts
conflict_stats
,
// to be updated after applying resolution
int
starSteps
,
// How far to look around when calculationg connection cost
double
orthoWeight
,
double
diagonalWeight
,
double
starPwr
,
// Divide cost by number of connections to this power
double
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
boolean
preferDisparity
,
int
debugLevel
,
int
dbg_X
,
int
dbg_Y
)
{
final
int
tilesX
=
tileProcessor
.
getTilesX
();
final
int
tilesY
=
tileProcessor
.
getTilesY
();
final
int
superTileSize
=
tileProcessor
.
getSuperTileSize
();
// final int tileSize = tileProcessor.getTileSize();
final
int
stilesX
=
(
tilesX
+
superTileSize
-
1
)/
superTileSize
;
final
int
stilesY
=
(
tilesY
+
superTileSize
-
1
)/
superTileSize
;
final
int
dbgTile
=
dbg_Y
*
stilesX
+
dbg_X
;
final
TileSurface
.
TileNeibs
tnSurface
=
tileSurface
.
new
TileNeibs
(
stilesX
,
stilesY
);
int
[]
rslt
=
{
0
,
0
};
for
(
int
nsTile
=
0
;
nsTile
<
conflicts
.
length
;
nsTile
++)
if
(
conflicts
[
nsTile
]
!=
null
)
{
// conflicts may disappear after being fixed, recheck for null
for
(
int
nConfl
=
0
;
(
conflicts
[
nsTile
]
!=
null
)
&&
(
nConfl
<
conflicts
[
nsTile
].
length
);
nConfl
++){
int
dl
=
((
debugLevel
>
0
)
&&
(
nsTile
==
dbgTile
))
?
3
:
0
;
boolean
OK
=
resolveMultiTriangularConflict
(
nsTile
,
conflicts
[
nsTile
][
nConfl
][
0
],
// int nl1,
conflicts
[
nsTile
][
nConfl
][
1
],
// int nl2,
conflicts
[
nsTile
][
nConfl
][
2
],
// int dir_mask,
tnSurface
,
conflicts
,
conflict_stats
,
// to be updated after applying resolution
// maxEigen, // maximal eigenvalue of planes to consider
starSteps
,
// How far to look around when calculationg connection cost
orthoWeight
,
diagonalWeight
,
starPwr
,
// double starPwr, // Divide cost by number of connections to this power
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
preferDisparity
,
dl
);
// debugLevel,
if
(
OK
)
rslt
[
0
]++;
else
rslt
[
1
]++;
}
}
return
rslt
;
}
public
boolean
resolveMultiTriangularConflict
(
public
boolean
resolveMultiTriangularConflict
(
int
nsTile
,
int
nsTile
,
int
nl1
,
int
nl1
,
...
@@ -4238,6 +4186,13 @@ public class SuperTiles{
...
@@ -4238,6 +4186,13 @@ public class SuperTiles{
double
[]
variant_costs_diff
=
new
double
[
neibs_vars
.
length
];
double
[]
variant_costs_diff
=
new
double
[
neibs_vars
.
length
];
for
(
int
variant
=
0
;
variant
<
neibs_vars
.
length
;
variant
++){
for
(
int
variant
=
0
;
variant
<
neibs_vars
.
length
;
variant
++){
if
(
debugLevel
>
0
)
{
System
.
out
.
println
(
"resolveMultiTriangularConflict(): resolving conflict for tile "
+
nsTile
+
", nl1 = "
+
nl1
+
", nl2 = "
+
nl2
+
", dir_mask = "
+
dir_mask
+
" variant = "
+
variant
);
}
variant_costs_diff
[
variant
]
=
connectionCosts
.
getConnectionsCostDiff
(
variant_costs_diff
[
variant
]
=
connectionCosts
.
getConnectionsCostDiff
(
neibs_vars
[
variant
],
neibs_vars
[
variant
],
debugLevel
);
debugLevel
);
...
@@ -4289,7 +4244,7 @@ public class SuperTiles{
...
@@ -4289,7 +4244,7 @@ public class SuperTiles{
System
.
out
.
println
(
"resolveMultiTriangularConflict() OLD: resolving conflict for tile "
+
nsTile
+
System
.
out
.
println
(
"resolveMultiTriangularConflict() OLD: resolving conflict for tile "
+
nsTile
+
", nl1 = "
+
nl1
+
", nl1 = "
+
nl1
+
", nl2 = "
+
nl2
+
", nl2 = "
+
nl2
+
", dir_mask = "
+
dir_mask
+
" variant = "
+
variant
+
" improvement (negative diff) = "
+
variant_costs_diff
[
variant
]);
", dir_mask = "
+
dir_mask
+
" variant = "
+
variant
+
" improvement (negative diff) = "
+
variant_costs_diff
_old
[
variant
]);
}
}
if
(
debugLevel
>
-
1
)
{
if
(
debugLevel
>
-
1
)
{
...
@@ -4375,6 +4330,336 @@ public class SuperTiles{
...
@@ -4375,6 +4330,336 @@ public class SuperTiles{
return
true
;
return
true
;
}
}
public
int
[]
resolveMultiTriangularConflicts
(
int
[][][]
conflicts
,
Conflicts
conflict_stats
,
// to be updated after applying resolution
int
starSteps
,
// How far to look around when calculationg connection cost
double
orthoWeight
,
double
diagonalWeight
,
double
starPwr
,
// Divide cost by number of connections to this power
double
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
boolean
preferDisparity
,
int
debugLevel
,
int
dbg_X
,
int
dbg_Y
)
{
final
int
tilesX
=
tileProcessor
.
getTilesX
();
final
int
tilesY
=
tileProcessor
.
getTilesY
();
final
int
superTileSize
=
tileProcessor
.
getSuperTileSize
();
// final int tileSize = tileProcessor.getTileSize();
final
int
stilesX
=
(
tilesX
+
superTileSize
-
1
)/
superTileSize
;
final
int
stilesY
=
(
tilesY
+
superTileSize
-
1
)/
superTileSize
;
final
int
dbgTile
=
dbg_Y
*
stilesX
+
dbg_X
;
final
TileSurface
.
TileNeibs
tnSurface
=
tileSurface
.
new
TileNeibs
(
stilesX
,
stilesY
);
int
[]
rslt
=
{
0
,
0
};
for
(
int
nsTile
=
0
;
nsTile
<
conflicts
.
length
;
nsTile
++)
if
(
conflicts
[
nsTile
]
!=
null
)
{
// conflicts may disappear after being fixed, recheck for null
for
(
int
nConfl
=
0
;
(
conflicts
[
nsTile
]
!=
null
)
&&
(
nConfl
<
conflicts
[
nsTile
].
length
);
nConfl
++){
int
dl
=
((
debugLevel
>
0
)
&&
(
nsTile
==
dbgTile
))
?
3
:
0
;
boolean
OK
=
resolveMultiTriangularConflict
(
nsTile
,
conflicts
[
nsTile
][
nConfl
][
0
],
// int nl1,
conflicts
[
nsTile
][
nConfl
][
1
],
// int nl2,
conflicts
[
nsTile
][
nConfl
][
2
],
// int dir_mask,
tnSurface
,
conflicts
,
conflict_stats
,
// to be updated after applying resolution
// maxEigen, // maximal eigenvalue of planes to consider
starSteps
,
// How far to look around when calculationg connection cost
orthoWeight
,
diagonalWeight
,
starPwr
,
// double starPwr, // Divide cost by number of connections to this power
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
preferDisparity
,
dl
);
// debugLevel,
if
(
OK
)
rslt
[
0
]++;
else
rslt
[
1
]++;
}
}
return
rslt
;
}
public
int
[]
resolveStarConflicts
(
int
[][][]
conflicts
,
Conflicts
conflict_stats
,
// to be updated after applying resolution
int
starSteps
,
// How far to look around when calculationg connection cost
double
orthoWeight
,
double
diagonalWeight
,
double
starPwr
,
// Divide cost by number of connections to this power
double
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
boolean
preferDisparity
,
int
debugLevel
,
int
dbg_X
,
int
dbg_Y
)
{
final
int
tilesX
=
tileProcessor
.
getTilesX
();
final
int
tilesY
=
tileProcessor
.
getTilesY
();
final
int
superTileSize
=
tileProcessor
.
getSuperTileSize
();
// final int tileSize = tileProcessor.getTileSize();
final
int
stilesX
=
(
tilesX
+
superTileSize
-
1
)/
superTileSize
;
final
int
stilesY
=
(
tilesY
+
superTileSize
-
1
)/
superTileSize
;
final
int
dbgTile
=
dbg_Y
*
stilesX
+
dbg_X
;
final
TileSurface
.
TileNeibs
tnSurface
=
tileSurface
.
new
TileNeibs
(
stilesX
,
stilesY
);
int
[]
rslt
=
{
0
,
0
};
for
(
int
nsTile
=
0
;
nsTile
<
conflicts
.
length
;
nsTile
++)
if
(
conflicts
[
nsTile
]
!=
null
)
{
// conflicts may disappear after being fixed, recheck for null
for
(
int
nConfl
=
0
;
(
conflicts
[
nsTile
]
!=
null
)
&&
(
nConfl
<
conflicts
[
nsTile
].
length
);
nConfl
++){
int
dl
=
((
debugLevel
>
0
)
&&
(
nsTile
==
dbgTile
))
?
3
:
0
;
boolean
OK
=
resolveStarConflict
(
nsTile
,
conflicts
[
nsTile
][
nConfl
][
0
],
// int nl1,
conflicts
[
nsTile
][
nConfl
][
1
],
// int nl2,
// conflicts[nsTile][nConfl][2], // int dir_mask,
tnSurface
,
conflicts
,
conflict_stats
,
// to be updated after applying resolution
// maxEigen, // maximal eigenvalue of planes to consider
starSteps
,
// How far to look around when calculationg connection cost
orthoWeight
,
diagonalWeight
,
starPwr
,
// double starPwr, // Divide cost by number of connections to this power
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
preferDisparity
,
dl
);
// debugLevel,
if
(
OK
)
rslt
[
0
]++;
else
rslt
[
1
]++;
}
}
return
rslt
;
}
public
boolean
resolveStarConflict
(
int
nsTile
,
int
nl1
,
int
nl2
,
// int dir_mask,
TileSurface
.
TileNeibs
tnSurface
,
int
[][][]
conflicts
,
Conflicts
conflict_stats
,
// to be updated after applying resolution
int
starSteps
,
// How far to look around when calculationg connection cost
double
orthoWeight
,
double
diagonalWeight
,
double
starPwr
,
// Divide cost by number of connections to this power
double
dblTriLoss
,
// When resolving double triangles allow minor degradation (0.0 - strict)
boolean
preferDisparity
,
int
debugLevel
)
{
Conflicts
iconflicts
=
new
Conflicts
(
this
);
TwoLayerNeighbors
twoLayerNeighbors
=
new
TwoLayerNeighbors
();
for
(
int
dir
=
-
1
;
dir
<
8
;
dir
++){
int
nt
=
tnSurface
.
getNeibIndex
(
nsTile
,
dir
);
if
((
nt
>=
0
)
&&
(
planes
[
nt
]
!=
null
))
{
int
[][]
neibs
=
new
int
[
planes
[
nt
].
length
][];
for
(
int
nl
=
0
;
nl
<
planes
[
nt
].
length
;
nl
++)
if
(
planes
[
nt
][
nl
]
!=
null
){
neibs
[
nl
]
=
planes
[
nt
][
nl
].
getNeibBest
();
}
twoLayerNeighbors
.
setNeighbors
(
neibs
,
dir
);
}
}
twoLayerNeighbors
.
setLayers
(
nl1
,
nl2
);
int
[][][][]
neibs_vars_dir
=
twoLayerNeighbors
.
getNeighborVariants
();
int
[]
mod_supertiles
=
{
nsTile
};
mod_supertiles
=
getInvolvedSupertiles
(
// first mod_supertiles.length entries will be mod_supertiles[]
mod_supertiles
,
tnSurface
);
HashMap
<
Integer
,
Integer
>
replacement_tiles
=
new
HashMap
<
Integer
,
Integer
>();
for
(
int
i
=
0
;
i
<
mod_supertiles
.
length
;
i
++){
replacement_tiles
.
put
(
mod_supertiles
[
i
],
new
Integer
(
i
));
}
// up to 9 tiles
int
[]
indexToDir
=
new
int
[
mod_supertiles
.
length
];
for
(
int
i
=
0
;
i
<
indexToDir
.
length
;
i
++)
indexToDir
[
i
]
=
-
1
;
for
(
int
dir
=
-
1
;
dir
<
8
;
dir
++){
int
nindx
=
(
dir
<
0
)
?
8
:
dir
;
int
nt
=
tnSurface
.
getNeibIndex
(
nsTile
,
dir
);
int
indx
=
replacement_tiles
.
get
(
nt
);
if
(
indx
>=
0
)
{
indexToDir
[
indx
]
=
nindx
;
}
}
int
[][][][]
neibs_vars
=
new
int
[
neibs_vars_dir
.
length
][][][];
for
(
int
variant
=
0
;
variant
<
neibs_vars_dir
.
length
;
variant
++){
neibs_vars
[
variant
]
=
new
int
[
indexToDir
.
length
][][];
for
(
int
i
=
0
;
i
<
indexToDir
.
length
;
i
++){
if
(
indexToDir
[
i
]
>=
0
){
neibs_vars
[
variant
][
i
]
=
neibs_vars_dir
[
variant
][
indexToDir
[
i
]];
}
else
{
System
.
out
.
println
(
"resolveStarConflict(): a BUG: indexToDir["
+
i
+
"] = "
+
indexToDir
[
i
]);
}
}
}
// See how this application will influence number of conflicts
// All supertiles that may have different conflicts
int
[]
nsTiles
=
getInvolvedSupertiles
(
// first mod_supertiles.length entries will be mod_supertiles[]
mod_supertiles
,
tnSurface
);
ConnectionCosts
connectionCosts
=
new
ConnectionCosts
(
orthoWeight
,
diagonalWeight
,
starPwr
,
// Divide cost by number of connections to this power
starSteps
,
this
.
planes
,
tnSurface
,
preferDisparity
);
int
[][][]
neibs_prev
=
connectionCosts
.
initConnectionCosts
(
mod_supertiles
);
int
[][][]
conflicts_old
=
new
int
[
nsTiles
.
length
][][];
for
(
int
isTile
=
0
;
isTile
<
nsTiles
.
length
;
isTile
++){
conflicts_old
[
isTile
]
=
iconflicts
.
detectTriangularTileConflicts
(
nsTiles
[
isTile
],
// int nsTile0,
replacement_tiles
,
//HashMap<Integer,Integer> replacement_tiles, //
neibs_prev
,
// int [][][] replacement_neibs,
tnSurface
);
// TileSurface.TileNeibs tnSurface)
}
if
(
debugLevel
>
1
)
{
System
.
out
.
println
(
"Involved supertiles:"
);
for
(
int
i
=
0
;
i
<
nsTiles
.
length
;
i
++){
System
.
out
.
println
(
i
+
":"
+
nsTiles
[
i
]);
}
}
if
(
debugLevel
>
1
)
{
System
.
out
.
println
(
"Calculating original conflicts"
);
}
iconflicts
.
addConflicts
(
conflicts_old
,
debugLevel
-
1
);
// debugLevel);
// After getting old (referfence data) iterate through all variants, for each calculate cost and number of conflicts.
// First - just collect data - cost and full statistics of the conflicts, print them
// Then select the best one (not incrementing number of conflicts? and reducing cost)
int
[][][][]
variant_conflicts
=
new
int
[
neibs_vars
.
length
][
nsTiles
.
length
][][];
Conflicts
[]
variant_conflicts_stats
=
new
Conflicts
[
neibs_vars
.
length
];
double
[]
variant_costs_diff
=
new
double
[
neibs_vars
.
length
];
for
(
int
variant
=
0
;
variant
<
neibs_vars
.
length
;
variant
++){
if
(
debugLevel
>
0
)
{
System
.
out
.
println
(
"resolveStarConflict(): resolving conflict for tile "
+
nsTile
+
", nl1 = "
+
nl1
+
", nl2 = "
+
nl2
+
", variant = "
+
variant
);
}
variant_costs_diff
[
variant
]
=
connectionCosts
.
getConnectionsCostDiff
(
neibs_vars
[
variant
],
debugLevel
);
if
(
debugLevel
>
-
1
)
{
System
.
out
.
println
(
"resolveStarConflict(): resolving conflict for tile "
+
nsTile
+
", nl1 = "
+
nl1
+
", nl2 = "
+
nl2
+
", variant = "
+
variant
+
" improvement (negative diff) = "
+
variant_costs_diff
[
variant
]);
}
for
(
int
isTile
=
0
;
isTile
<
nsTiles
.
length
;
isTile
++){
variant_conflicts
[
variant
][
isTile
]
=
iconflicts
.
detectTriangularTileConflicts
(
nsTiles
[
isTile
],
// int nsTile0,
replacement_tiles
,
//HashMap<Integer,Integer> replacement_tiles, //
neibs_vars
[
variant
],
// neibs, // int [][][] replacement_neibs,
tnSurface
);
// TileSurface.TileNeibs tnSurface)
}
variant_conflicts_stats
[
variant
]
=
new
Conflicts
(
variant_conflicts
[
variant
],
this
,
debugLevel
-
1
);
// debugLevel);
variant_conflicts_stats
[
variant
].
subConflicts
(
iconflicts
);
// subtract old number of different types of conflicts
if
(
debugLevel
>
-
1
)
{
variant_conflicts_stats
[
variant
].
printConflictSummary
(
"Conflicts difference after resolution:"
,
true
,
true
,
false
);
}
}
// How to compare? 1 attempt: none of the conflicts get worse, some get better or cost goes down
int
best_variant
=
-
1
;
int
[][]
num_better_worse
=
new
int
[
neibs_vars
.
length
][
2
];
for
(
int
variant
=
0
;
variant
<
neibs_vars
.
length
;
variant
++){
int
num_worse
=
variant_conflicts_stats
[
variant
].
numBetterWorse
(
false
,
// boolean better,
false
,
// boolean use_all,
true
,
// boolean use_odo,
false
);
// ); // boolean use_ood)
int
num_better
=
variant_conflicts_stats
[
variant
].
numBetterWorse
(
true
,
// boolean better,
false
,
// boolean use_all,
true
,
// boolean use_odo,
false
);
// ); // boolean use_ood)
num_better_worse
[
variant
][
0
]
=
num_better
;
num_better_worse
[
variant
][
1
]
=
num_worse
;
if
((
num_worse
==
0
)
&&
(
variant_costs_diff
[
variant
]
<=
dblTriLoss
)
&&
// not too worse
((
variant_costs_diff
[
variant
]
<
0
)
||
(
num_better
>
0
))
&&
// either
((
best_variant
<
0
)
||
(
num_better_worse
[
variant
][
0
]
>
num_better_worse
[
best_variant
][
0
])
||
((
num_better_worse
[
variant
][
0
]
==
num_better_worse
[
best_variant
][
0
])
&&
(
variant_costs_diff
[
variant
]
<
variant_costs_diff
[
best_variant
])))){
best_variant
=
variant
;
}
}
if
(
debugLevel
>
1
){
System
.
out
.
println
(
"resolveStarConflict(): for tile "
+
nsTile
);
}
if
((
best_variant
<
0
)
||
(
variant_costs_diff
[
best_variant
]
>
dblTriLoss
)){
if
(
debugLevel
>
-
1
)
{
System
.
out
.
println
(
"resolveMultiTriangularConflict(): FAILED find a sutable solution for tile "
+
nsTile
+
", nl1 = "
+
nl1
+
", nl2 = "
+
nl2
+
" of "
+
neibs_vars
.
length
+
" variants"
);
return
false
;
}
}
else
{
if
(
debugLevel
>
-
1
)
{
System
.
out
.
println
(
"resolveStarConflict(): SUCCESS to find a sutable solution for tile "
+
nsTile
+
", nl1 = "
+
nl1
+
", nl2 = "
+
nl2
+
". Of "
+
neibs_vars
.
length
+
" variants - use variant # "
+
best_variant
+
" cost difference (negative) = "
+
variant_costs_diff
[
best_variant
]+
" num conflict reductions = "
+
num_better_worse
[
best_variant
][
0
]);
variant_conflicts_stats
[
best_variant
].
printConflictSummary
(
"Conflicts number change per type: "
,
true
,
// use_all,
true
,
//use_odo,
true
);
// use_ood);
iconflicts
.
printConflictSummary
(
"Conflicts before resolution: "
,
true
,
// use_all,
true
,
//use_odo,
true
);
// use_ood);
// update statistics
conflict_stats
.
addConflicts
(
variant_conflicts_stats
[
best_variant
]);
// update conflict
for
(
int
i
=
0
;
i
<
nsTiles
.
length
;
i
++){
conflicts
[
nsTiles
[
i
]]=
variant_conflicts
[
best_variant
][
i
];
}
// apply resolution
for
(
int
i
=
0
;
i
<
mod_supertiles
.
length
;
i
++){
for
(
int
nl
=
0
;
nl
<
neibs_vars
[
best_variant
][
i
].
length
;
nl
++)
if
(
neibs_vars
[
best_variant
][
i
][
nl
]
!=
null
){
planes
[
mod_supertiles
[
i
]][
nl
].
setNeibBest
(
neibs_vars
[
best_variant
][
i
][
nl
]);
}
}
}
}
return
true
;
}
//
//
/**
/**
* Generate variants for changing connections while preserving number of connections between each pair of tiles
* Generate variants for changing connections while preserving number of connections between each pair of tiles
...
@@ -4625,6 +4910,10 @@ public class SuperTiles{
...
@@ -4625,6 +4910,10 @@ public class SuperTiles{
public
void
resolveConflicts
(
public
void
resolveConflicts
(
double
maxEigen
,
// maximal eigenvalue of planes to consider
double
maxEigen
,
// maximal eigenvalue of planes to consider
boolean
conflDualTri
,
// Resolve dual triangles conflict (odoodo)
boolean
conflMulti
,
// Resolve multiple odo triangles conflicts
boolean
conflDiag
,
// Resolve diagonal (ood) conflicts
boolean
conflStar
,
// Resolve all conflicts around a supertile
int
starSteps
,
// How far to look around when calculationg connection cost
int
starSteps
,
// How far to look around when calculationg connection cost
double
orthoWeight
,
double
orthoWeight
,
double
diagonalWeight
,
double
diagonalWeight
,
...
@@ -4646,7 +4935,12 @@ public class SuperTiles{
...
@@ -4646,7 +4935,12 @@ public class SuperTiles{
-
1
);
// debugLevel);
-
1
);
// debugLevel);
for
(
int
pass
=
0
;
pass
<
10
;
pass
++)
{
for
(
int
pass
=
0
;
pass
<
10
;
pass
++)
{
int
[]
dual_tri_results
=
resolveDualTriangularConflicts
(
int
[]
dual_tri_results
=
{
0
,
0
};
int
[]
multi_resoultion_results
=
{
0
,
0
};
int
[]
diagonal_resoultion_results
=
{
0
,
0
};
int
[]
conflict_star_results
=
{
0
,
0
};
if
(
conflDualTri
)
{
dual_tri_results
=
resolveDualTriangularConflicts
(
conflicts0
,
// int [][][] conflicts,
conflicts0
,
// int [][][] conflicts,
conflicts0_stats
,
conflicts0_stats
,
maxEigen
,
maxEigen
,
...
@@ -4660,9 +4954,9 @@ public class SuperTiles{
...
@@ -4660,9 +4954,9 @@ public class SuperTiles{
dbg_X
,
dbg_X
,
dbg_Y
);
dbg_Y
);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": dual_tri_results (success/failures) = "
+
dual_tri_results
[
0
]+
" / "
+
dual_tri_results
[
1
]);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": dual_tri_results (success/failures) = "
+
dual_tri_results
[
0
]+
" / "
+
dual_tri_results
[
1
]);
}
if
(
conflMulti
)
{
int
[]
conflict
_resoultion_results
=
resolveMultiTriangularConflicts
(
multi
_resoultion_results
=
resolveMultiTriangularConflicts
(
conflicts0
,
// int [][][] conflicts,
conflicts0
,
// int [][][] conflicts,
conflicts0_stats
,
conflicts0_stats
,
starSteps
,
// How far to look around when calculationg connection cost
starSteps
,
// How far to look around when calculationg connection cost
...
@@ -4674,9 +4968,10 @@ public class SuperTiles{
...
@@ -4674,9 +4968,10 @@ public class SuperTiles{
debugLevel
,
// 1, // final int debugLevel)
debugLevel
,
// 1, // final int debugLevel)
dbg_X
,
dbg_X
,
dbg_Y
);
dbg_Y
);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": multi_tri_results (success/failures) = "
+
conflict_resoultion_results
[
0
]+
" / "
+
conflict_resoultion_results
[
1
]);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": multi_tri_results (success/failures) = "
+
multi_resoultion_results
[
0
]+
" / "
+
multi_resoultion_results
[
1
]);
}
int
[]
diagonal_resoultion_results
=
resolveDiagonalTriangularConflicts
(
if
(
conflDiag
)
{
diagonal_resoultion_results
=
resolveDiagonalTriangularConflicts
(
conflicts0
,
// int [][][] conflicts,
conflicts0
,
// int [][][] conflicts,
conflicts0_stats
,
conflicts0_stats
,
starSteps
,
// How far to look around when calculationg connection cost
starSteps
,
// How far to look around when calculationg connection cost
...
@@ -4689,9 +4984,27 @@ public class SuperTiles{
...
@@ -4689,9 +4984,27 @@ public class SuperTiles{
dbg_X
,
dbg_X
,
dbg_Y
);
dbg_Y
);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": resolveDiagonalTriangularConflicts (success/failures) = "
+
diagonal_resoultion_results
[
0
]+
" / "
+
diagonal_resoultion_results
[
1
]);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": resolveDiagonalTriangularConflicts (success/failures) = "
+
diagonal_resoultion_results
[
0
]+
" / "
+
diagonal_resoultion_results
[
1
]);
}
if
(
conflStar
)
{
conflict_star_results
=
resolveStarConflicts
(
conflicts0
,
// int [][][] conflicts,
conflicts0_stats
,
starSteps
,
// How far to look around when calculationg connection cost
orthoWeight
,
// double orthoWeight,
diagonalWeight
,
// double diagonalWeight,
starPwr
,
// double starPwr, // Divide cost by number of connections to this power
dblTriLoss
,
// double diagonalWeight,
preferDisparity
,
debugLevel
,
// 1, // final int debugLevel)
dbg_X
,
dbg_Y
);
System
.
out
.
println
(
"Pass "
+(
pass
+
1
)+
": resolveStarConflicts (success/failures) = "
+
conflict_star_results
[
0
]+
" / "
+
conflict_star_results
[
1
]);
}
if
(
(
dual_tri_results
[
0
]
==
0
)
&&
if
(
(
dual_tri_results
[
0
]
==
0
)
&&
(
conflict_resoultion_results
[
0
]
==
0
)
&&
(
multi_resoultion_results
[
0
]
==
0
)
&&
(
diagonal_resoultion_results
[
0
]
==
0
))
{
(
diagonal_resoultion_results
[
0
]
==
0
)
&&
(
conflict_star_results
[
0
]
==
0
))
{
System
.
out
.
println
(
"No more improvements"
);
System
.
out
.
println
(
"No more improvements"
);
break
;
break
;
}
}
...
@@ -4771,7 +5084,7 @@ public class SuperTiles{
...
@@ -4771,7 +5084,7 @@ public class SuperTiles{
for
(
int
dir4
=
0
;
dir4
<
4
;
dir4
++
){
for
(
int
dir4
=
0
;
dir4
<
4
;
dir4
++
){
// conflicts may disappear after being fixed, recheck for null
// conflicts may disappear after being fixed, recheck for null
if
((
conflicts
[
nsTile
]
!=
null
)
&&
(
conflicts
[
nsTile
][
nConfl
]
!=
null
)
&&
((
conflicts
[
nsTile
][
nConfl
][
2
]
&
(
1
<<
dir4
))
>
0
)
&&
((
conflicts
[
nsTile
][
nConfl
][
2
]
&
(
16
<<
dir4
))
>
0
))
{
if
((
conflicts
[
nsTile
]
!=
null
)
&&
(
conflicts
[
nsTile
][
nConfl
]
!=
null
)
&&
((
conflicts
[
nsTile
][
nConfl
][
2
]
&
(
1
<<
dir4
))
>
0
)
&&
((
conflicts
[
nsTile
][
nConfl
][
2
]
&
(
16
<<
dir4
))
>
0
))
{
if
(
debugLevel
>
1
){
if
(
debugLevel
>
0
)
{
//
1){
System
.
out
.
println
(
"resolveDualTriangularConflicts(): resolving dual triangular conflict for tile "
+
nsTile
+
System
.
out
.
println
(
"resolveDualTriangularConflicts(): resolving dual triangular conflict for tile "
+
nsTile
+
", nl1 = "
+
conflicts
[
nsTile
][
nConfl
][
0
]+
", nl1 = "
+
conflicts
[
nsTile
][
nConfl
][
0
]+
", nl2 = "
+
conflicts
[
nsTile
][
nConfl
][
1
]+
", nl2 = "
+
conflicts
[
nsTile
][
nConfl
][
1
]+
...
...
src/main/java/TileProcessor.java
View file @
18261553
...
@@ -3431,6 +3431,10 @@ public class TileProcessor {
...
@@ -3431,6 +3431,10 @@ public class TileProcessor {
st
.
resolveConflicts
(
st
.
resolveConflicts
(
clt_parameters
.
plMaxEigen
,
clt_parameters
.
plMaxEigen
,
clt_parameters
.
plConflDualTri
,
// boolean conflDualTri, // Resolve dual triangles conflict (odoodo)
clt_parameters
.
plConflMulti
,
// boolean conflMulti, // Resolve multiple odo triangles conflicts
clt_parameters
.
plConflDiag
,
// boolean conflDiag, // Resolve diagonal (ood) conflicts
clt_parameters
.
plConflStar
,
// boolean conflStar, // Resolve all conflicts around a supertile
clt_parameters
.
plStarSteps
,
// int starSteps, // How far to look around when calculationg connection cost
clt_parameters
.
plStarSteps
,
// int starSteps, // How far to look around when calculationg connection cost
clt_parameters
.
plStarOrtho
,
// double orthoWeight,
clt_parameters
.
plStarOrtho
,
// double orthoWeight,
clt_parameters
.
plStarDiag
,
// double diagonalWeight,
clt_parameters
.
plStarDiag
,
// double diagonalWeight,
...
@@ -3533,6 +3537,10 @@ public class TileProcessor {
...
@@ -3533,6 +3537,10 @@ public class TileProcessor {
st
.
resolveConflicts
(
st
.
resolveConflicts
(
clt_parameters
.
plMaxEigen
,
clt_parameters
.
plMaxEigen
,
clt_parameters
.
plConflDualTri
,
// boolean conflDualTri, // Resolve dual triangles conflict (odoodo)
clt_parameters
.
plConflMulti
,
// boolean conflMulti, // Resolve multiple odo triangles conflicts
clt_parameters
.
plConflDiag
,
// boolean conflDiag, // Resolve diagonal (ood) conflicts
clt_parameters
.
plConflStar
,
// boolean conflStar, // Resolve all conflicts around a supertile
clt_parameters
.
plStarSteps
,
// int starSteps, // How far to look around when calculationg connection cost
clt_parameters
.
plStarSteps
,
// int starSteps, // How far to look around when calculationg connection cost
clt_parameters
.
plStarOrtho
,
// double orthoWeight,
clt_parameters
.
plStarOrtho
,
// double orthoWeight,
clt_parameters
.
plStarDiag
,
// double diagonalWeight,
clt_parameters
.
plStarDiag
,
// double diagonalWeight,
...
...
src/main/java/TwoLayerNeighbors.java
0 → 100644
View file @
18261553
import
java.awt.Point
;
import
java.util.ArrayList
;
/**
**
** TwoLayerNeighbors - Handle connection swapping for resolving conflicts
** between two layer connections
**
** Copyright (C) 2017 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** TwoLayerNeighbors.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
public
class
TwoLayerNeighbors
{
/**
* connection variants (excluding from the center) as
* {start_dir, end_dir, relative_dir}
*/
static
int
[][]
PAIRS
=
{
{
0
,
1
,
2
},
{
1
,
2
,
4
},
{
2
,
3
,
4
},
{
3
,
4
,
6
},
{
4
,
5
,
6
},
{
5
,
6
,
0
},
{
6
,
7
,
0
},
{
7
,
0
,
2
},
{
0
,
2
,
3
},
{
2
,
4
,
5
},
{
4
,
6
,
7
},
{
6
,
0
,
1
}};
/**
* Direction from dir1 (from center) to dir2 (from center)
* -1 - same (dir1 == dir2)
* -2 - impossible (no direct connection
*/
static
int
[][]
rel_dirs
=
{
//0 1 2 3 4 5 6 7 // dir2 values
{-
1
,
2
,
3
,
-
2
,
-
2
,
-
2
,
5
,
6
},
// dir1 = 0;
{
6
,
-
1
,
4
,
-
2
,
-
2
,
-
2
,
-
2
,
-
2
},
// dir1 = 1;
{
7
,
0
,
-
1
,
4
,
5
,
-
2
,
-
2
,
-
2
},
// dir1 = 2;
{-
2
,
-
2
,
0
,
-
1
,
6
,
-
2
,
-
2
,
-
2
},
// dir1 = 3;
{-
2
,
-
2
,
1
,
2
,
-
1
,
6
,
7
,
-
2
},
// dir1 = 4;
{-
2
,
-
2
,
-
2
,
-
2
,
2
,
-
1
,
0
,
-
2
},
// dir1 = 5;
{
1
,
-
2
,
-
2
,
-
2
,
3
,
4
,
-
1
,
0
},
// dir1 = 6;
{
2
,
-
2
,
-
2
,
-
2
,
-
2
,
-
2
,
4
,
-
1
}};
// dir1 = 7
int
nl1
;
int
nl2
;
NeibVariant
neibs_init
=
new
NeibVariant
();
int
[][]
layers_around
=
new
int
[
8
][];
int
[]
options_around
=
new
int
[
8
];
int
[][]
num_se
=
new
int
[
PAIRS
.
length
][];
int
[][][]
conns
=
new
int
[
PAIRS
.
length
][][];
int
[]
selection_star
=
null
;
int
[]
selection_conns
=
null
;
class
NeibVariant
{
int
[][][]
neighbors
=
new
int
[
9
][][];
public
int
[][][]
toArray
()
{
return
neighbors
;
}
public
void
setNeighbors
(
int
[][]
neibs
,
int
dir
)
{
if
(
dir
<
0
)
neighbors
[
8
]
=
neibs
;
else
neighbors
[
dir
]
=
neibs
;
}
public
int
[][]
getNeighbors
(
int
dir
)
{
if
(
dir
<
0
)
return
neighbors
[
8
];
else
return
neighbors
[
dir
];
}
public
NeibVariant
clone
(){
NeibVariant
variant
=
new
NeibVariant
();
variant
.
neighbors
=
neighbors
.
clone
();
for
(
int
dir
=
0
;
dir
<
neighbors
.
length
;
dir
++){
if
(
neighbors
[
dir
]
!=
null
)
{
variant
.
neighbors
[
dir
]
=
neighbors
[
dir
].
clone
();
for
(
int
i
=
0
;
i
<
neighbors
[
dir
].
length
;
i
++){
if
(
neighbors
[
dir
][
i
]
!=
null
){
variant
.
neighbors
[
dir
][
i
]
=
neighbors
[
dir
][
i
].
clone
();
}
}
}
}
return
variant
;
}
public
int
getDir2From1
(
int
dir1
,
int
dir2
)
{
if
(
dir1
<
0
)
return
dir2
;
if
(
dir2
<
0
)
return
((
dir1
+
4
)
%
8
);
return
rel_dirs
[
dir1
][
dir2
];
}
/**
* Connect tile at dir1 (-1 - center), layer nl1 to dir2, layer nl2
* Create connect in both directions, reconnect other ends of the broken links or plug with -1
* if there was none
* @param dir1 direction from the center to the start of the connection (-1 - center)
* @param nl1 start layer to connect (-1 - just disconnect the end)
* @param dir2 direction from the center to the end of the connection (-1 - center)
* @param nl2 end layer to connect (-1 - just disconnect the start)
*/
public
void
connect
(
int
dir1
,
int
nl1
,
int
dir2
,
int
nl2
){
int
dir12
=
getDir2From1
(
dir1
,
dir2
);
if
(
dir12
<
0
){
throw
new
IllegalArgumentException
(
"Invalid connection from "
+
dir1
+
" to "
+
dir2
+
": resulted in direction 1->2 = "
+
dir12
);
}
int
dir21
=
(
dir12
+
4
)
%
8
;
int
[][]
neibs_start
=
getNeighbors
(
dir1
);
int
[][]
neibs_end
=
getNeighbors
(
dir2
);
int
old_nl2
=
-
1
,
old_nl1
=
-
1
;
if
(
nl1
>=
0
){
old_nl2
=
neibs_start
[
nl1
][
dir12
];
// where it was connected before, may be -1
if
(
old_nl2
!=
nl2
)
{
neibs_start
[
nl1
][
dir12
]
=
nl2
;
}
}
if
(
nl2
>=
0
){
old_nl1
=
neibs_end
[
nl2
][
dir21
];
neibs_end
[
nl2
][
dir21
]
=
nl1
;
}
// reconnect or plug broken links
if
(
old_nl2
>=
0
){
neibs_end
[
old_nl2
][
dir21
]
=
old_nl1
;
// (old_nl1 may be -1 here)
}
if
(
old_nl1
>=
0
){
neibs_start
[
old_nl1
][
dir12
]
=
old_nl2
;
// (old_nl2 may be -1 here)
}
}
}
/**
* Initialize or advance variand selection. Return false if nothing left
* @return new selection available
*/
public
boolean
nextSelection
(){
if
(
selection_star
==
null
){
selection_star
=
new
int
[
options_around
.
length
];
// 8
selection_conns
=
new
int
[
PAIRS
.
length
];
// 12
return
true
;
}
else
{
// increment connection variant if possible
for
(
int
np
=
0
;
np
<
PAIRS
.
length
;
np
++){
// if (
// (num_se[np] == null) ||
// (conns[np] == null)) {
// System.out.println("nextSelection BUG");
// return false;
// }
if
((
num_se
[
np
]
!=
null
)
&&
(
num_se
[
np
][
0
]
==
2
)
&&
(
num_se
[
np
][
1
]
==
2
)
&&
(
conns
[
np
]
!=
null
)
&&
(
conns
[
np
].
length
==
1
)){
if
(
selection_conns
[
np
]
==
0
){
selection_conns
[
np
]
=
1
;
for
(
int
i
=
0
;
i
<
np
;
i
++){
selection_conns
[
i
]
=
0
;
}
return
true
;
}
}
}
// increment neighbor option, reset connection options;
for
(
int
i
=
0
;
i
<
PAIRS
.
length
;
i
++){
selection_conns
[
i
]
=
0
;
}
for
(
int
dir
=
0
;
dir
<
options_around
.
length
;
dir
++){
if
((
options_around
[
dir
]>
1
)
&&
(
selection_star
[
dir
]
==
0
)){
selection_star
[
dir
]
=
1
;
for
(
int
dir1
=
0
;
dir1
<
dir
;
dir1
++){
selection_star
[
dir1
]
=
0
;
}
return
true
;
}
}
return
false
;
}
}
/**
* Generate variant for the current selection (if consistent)
* @return neibVariant instance fro the current selection or null if the
* selection leads to conflicts
*/
public
NeibVariant
generateVariant
()
{
// verify all connetions are possible
for
(
int
np
=
0
;
np
<
PAIRS
.
length
;
np
++)
if
(
conns
[
np
]
!=
null
){
// single connection for a single variant for start and end - either match or not
if
((
num_se
[
np
]
!=
null
)
&&
(
conns
[
np
].
length
==
1
)
&&
(
num_se
[
np
][
0
]
==
1
)
&&
(
num_se
[
np
][
1
]
==
1
)){
// Start and end of the connection belong to different groups - they can not be connected
if
(
selection_star
[
PAIRS
[
np
][
0
]]
!=
selection_star
[
PAIRS
[
np
][
1
]]){
return
null
;
}
}
}
// current selection is consistent, generate it
NeibVariant
variant
=
neibs_init
.
clone
();
// set connections for the center
for
(
int
dir
=
0
;
dir
<
8
;
dir
++)
if
(
options_around
[
dir
]
>
0
){
// make a first connection, if there are two - other will be created simultaneously
variant
.
connect
(
-
1
,
// int dir1,
((
selection_star
[
dir
]
>
0
)
?
nl2
:
nl1
),
// int nl1,
dir
,
// int dir2,
layers_around
[
dir
][
0
]);
// int nl2);
}
// set all other connections
for
(
int
np
=
0
;
np
<
PAIRS
.
length
;
np
++)
if
(
conns
[
np
]
!=
null
){
int
start_dir
=
PAIRS
[
np
][
0
];
int
end_dir
=
PAIRS
[
np
][
1
];
boolean
swap
=
(
selection_star
[
start_dir
]
!=
selection_star
[
end_dir
])
^
(
selection_conns
[
np
]
>
0
);
int
[]
opts
=
{
0
,
0
};
if
(
swap
){
if
(
num_se
[
np
][
0
]
>
1
){
opts
[
0
]
=
1
;
}
else
{
opts
[
1
]
=
1
;
// assuming there are two variants for the connection end as it should be
}
}
variant
.
connect
(
start_dir
,
// int dir1,
layers_around
[
start_dir
][
opts
[
0
]],
// int nl1,
end_dir
,
// int dir2,
layers_around
[
end_dir
][
opts
[
1
]]);
// int nl2);
return
variant
;
}
return
null
;
}
public
int
[][][][]
getNeighborVariants
()
{
ArrayList
<
NeibVariant
>
variant_list
=
new
ArrayList
<
NeibVariant
>();
while
(
nextSelection
()){
NeibVariant
variant
=
generateVariant
();
if
(
variant
!=
null
){
variant_list
.
add
(
variant
);
}
}
int
[][][][]
variants
=
new
int
[
variant_list
.
size
()][][][];
int
indx
=
0
;
for
(
NeibVariant
variant
:
variant_list
){
variants
[
indx
++]
=
variant
.
toArray
();
}
return
variants
;
}
public
void
setNeighbors
(
int
[][]
neibs
,
int
dir
)
{
neibs_init
.
setNeighbors
(
neibs
,
dir
);
}
public
int
[][]
getInitNeighbors
(
int
dir
)
{
return
neibs_init
.
getNeighbors
(
dir
);
}
public
int
[]
getLayers
()
{
int
[]
layers
=
{
nl1
,
nl2
};
return
layers
;
}
/**
* Return array pairs of start/end options or null if there are no connections for this pair
* @param np
* @return
*/
int
[][]
getConnections
(
int
np
)
{
int
start_dir
=
PAIRS
[
np
][
0
];
int
end_dir
=
PAIRS
[
np
][
1
];
int
dir
=
PAIRS
[
np
][
2
];
if
((
options_around
[
start_dir
]
>
0
)
&&
(
options_around
[
end_dir
]
>
0
)){
ArrayList
<
Point
>
conn_list
=
new
ArrayList
<
Point
>();
for
(
int
opt1
=
0
;
opt1
<
options_around
[
start_dir
];
opt1
++){
int
start_layer
=
layers_around
[
start_dir
][
opt1
];
for
(
int
opt2
=
0
;
opt2
<
options_around
[
end_dir
];
opt2
++){
int
end_layer
=
layers_around
[
end_dir
][
opt2
];
if
(
neibs_init
.
neighbors
[
start_dir
][
start_layer
][
dir
]
==
end_layer
){
conn_list
.
add
(
new
Point
(
opt1
,
opt2
));
}
}
}
if
(!
conn_list
.
isEmpty
()){
int
[][]
pconns
=
new
int
[
conn_list
.
size
()][
2
];
int
indx
=
0
;
for
(
Point
p
:
conn_list
){
pconns
[
indx
]
[
0
]
=
p
.
x
;
pconns
[
indx
++][
1
]
=
p
.
y
;
}
return
pconns
;
}
}
return
null
;
}
public
void
setLayers
(
int
nl1
,
int
nl2
)
{
this
.
nl1
=
nl1
;
this
.
nl2
=
nl1
;
layers_around
=
new
int
[
8
][];
options_around
=
new
int
[
8
];
int
[][]
neighbors_center
=
neibs_init
.
getNeighbors
(-
1
);
for
(
int
dir
=
0
;
dir
<
8
;
dir
++){
if
((
neighbors_center
[
nl1
][
dir
]
>=
0
)
||
(
neighbors_center
[
nl2
][
dir
]
>=
0
)){
options_around
[
dir
]
=
1
;
layers_around
[
dir
]
=
new
int
[
2
];
if
(
neighbors_center
[
nl1
][
dir
]
>=
0
){
layers_around
[
dir
][
0
]
=
neighbors_center
[
nl1
][
dir
];
if
(
neighbors_center
[
nl2
][
dir
]
>=
0
){
layers_around
[
dir
][
1
]
=
neighbors_center
[
nl2
][
dir
];
options_around
[
dir
]
++;
}
else
{
layers_around
[
dir
][
1
]
=
neighbors_center
[
nl1
][
dir
];
}
}
else
{
layers_around
[
dir
][
0
]
=
neighbors_center
[
nl2
][
dir
];
layers_around
[
dir
][
1
]
=
neighbors_center
[
nl2
][
dir
];
}
}
}
for
(
int
np
=
0
;
np
<
PAIRS
.
length
;
np
++){
if
((
options_around
[
PAIRS
[
np
][
0
]]
>
0
)
&&
(
options_around
[
PAIRS
[
np
][
1
]]
>
0
)){
num_se
[
np
]
=
new
int
[
2
];
// {options_around[PAIRS[np][0]],options_around[PAIRS[np][0]]};
num_se
[
np
][
0
]
=
options_around
[
PAIRS
[
np
][
0
]];
num_se
[
np
][
1
]
=
options_around
[
PAIRS
[
np
][
1
]];
conns
[
np
]
=
getConnections
(
np
);
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment