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
93ac2c14
Commit
93ac2c14
authored
Oct 26, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented "infinity" so nodes may have sides open to infinity
parent
8176593d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
117 additions
and
72 deletions
+117
-72
LwocOctree.java
...java/com/elphel/imagej/tileprocessor/lwoc/LwocOctree.java
+115
-68
LwocWorld.java
.../java/com/elphel/imagej/tileprocessor/lwoc/LwocWorld.java
+2
-4
No files found.
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocOctree.java
View file @
93ac2c14
...
...
@@ -37,13 +37,10 @@ import com.elphel.imagej.common.MultiThreading;
public
class
LwocOctree
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
public
static
final
int
NUM_CHILDREN
=
8
;
// static AtomicInteger OCTREE_ID = new AtomicInteger();
static
List
<
LwocScene
>
pendingScenes
;
// synchronized - add not-yet-added scenes pending growing world
static
List
<
LwocMesh
>
pendingMeshes
;
// synchronized - add not-yet-added meshes pending growing world
static
List
<
LwocOctree
>
pendingLeafNodes
;
// synchronized - leaf nodes needed to be split
// static List<LwocWorld> lwoc_worlds; //
int
id
;
// assign unique ID
transient
LwocWorld
world
;
transient
LwocOctree
parent
;
...
...
@@ -51,6 +48,7 @@ public class LwocOctree implements Serializable {
LwocLeaf
leaf
;
//
double
[]
center
;
// x-center, y-center, z-center
double
hsize
;
int
infinity
=
0
;
public
static
void
addPendingScene
(
LwocScene
scene
)
{
synchronized
(
pendingScenes
)
{
...
...
@@ -107,20 +105,36 @@ public class LwocOctree implements Serializable {
}
/**
* LwocOctree constructor
* LwocOctree constructor. Sets infinity bitmap +1 - no limit for negative X,
* +2 - no limit for positive X, +4 - no limit for negative Y, ...,
* +32 - no limit for positive Z.
* @param lwocWorld World global parameters
* @param parent
Parent node
* @param parent
_in
Parent node
* @param xyz Position of the node center in meters
* @param h
size
Node half size - each of the X,Y,Z coordinates of the internal
* @param h
_size
Node half size - each of the X,Y,Z coordinates of the internal
* points are limited within +/-hsize from the node center
*/
public
LwocOctree
(
LwocWorld
lwocWorld
,
LwocOctree
parent
,
LwocOctree
parent
_in
,
double
[]
xyz
,
double
hsize
)
{
this
.
parent
=
parent
;
this
.
hsize
=
hsize
;
double
h_size
)
{
world
=
lwocWorld
;
parent
=
parent_in
;
center
=
xyz
;
hsize
=
h_size
;
// set which directions are to infinity (not limited by hsize)
infinity
=
0
;
double
max_hsize
=
world
.
getMaxHsize
();
LwocOctree
lwoc_root
=
world
.
getLwocRoot
();
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
((
center
[
dm
]
-
hsize
)
<=
(
lwoc_root
.
center
[
dm
]
-
max_hsize
))
{
infinity
|=
(
1
<<
(
2
*
dm
));
}
if
((
center
[
dm
]
+
hsize
)
>=
(
lwoc_root
.
center
[
dm
]
+
max_hsize
))
{
infinity
|=
(
1
<<
(
2
*
dm
+
1
));
}
}
}
/**
...
...
@@ -129,7 +143,6 @@ public class LwocOctree implements Serializable {
* @return Octree node that includes the point or null if the point
* is outside the root node (the whole world)
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
LwocOctree
getLeafNode
(
// if null - needs growing world
double
[]
xyz
)
{
// thread safe
if
(!
world
.
getLwocRoot
().
contains
(
xyz
))
return
null
;
// needs growing world
...
...
@@ -189,7 +202,7 @@ public class LwocOctree implements Serializable {
return
;
// nothing to do
}
else
{
for
(
LwocScene
scene:
pendingScenes
)
{
growXYZ
(
scene
.
getCameraXYZ
());
growXYZ
(
scene
.
getCameraXYZ
());
// will not grow in infinity direction
LwocOctree
node
=
addScene
(
// should not be null
scene
,
check_existed
);
...
...
@@ -215,9 +228,9 @@ public class LwocOctree implements Serializable {
double
[]
corner_xyz
=
center
.
clone
();
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
corner_xyz
[
dm
]
+=
dims
[
dm
];
growXYZ
(
corner_xyz
);
growXYZ
(
corner_xyz
);
// will not grow in infinity direction
corner_xyz
[
dm
]
-=
2
*
dims
[
dm
];
growXYZ
(
corner_xyz
);
growXYZ
(
corner_xyz
);
// will not grow in infinity direction
corner_xyz
[
dm
]
+=
dims
[
dm
];
}
boolean
ok
=
addMeshCenter
(
// should not be null
...
...
@@ -251,17 +264,9 @@ public class LwocOctree implements Serializable {
/**
* Recursively (if needed) splits octree nodes to reduce number of scenes/cameras
* and mesh centers below specified thresholds (limited by the minimal node size)
* @param min_hsize Minimal half-size of the node (in meters). Smaller nodes will not be split
* @param max_mesh_centers Maximal number of mesh centers in a node. Larger number
* triggers node split.
* @param max_cameras Maximasl number of scenes (camera positions) in a node. Larger
* number triggers node split.
* @param check_existed Filter identical meshes or scenes from corresponding lists.
*/
public
static
void
tendPendingLeafNodes
(
final
double
min_hsize
,
final
int
max_mesh_centers
,
final
int
max_cameras
,
// scenes
final
boolean
check_existed
)
{
// remove any possible duplicates
final
ArrayList
<
LwocOctree
>
pendingLeafNodesFiltered
=
new
ArrayList
<
LwocOctree
>();
...
...
@@ -270,26 +275,32 @@ public class LwocOctree implements Serializable {
pendingLeafNodesFiltered
.
add
(
node
);
}
}
// run splitting multithreaded
final
Thread
[]
threads
=
MultiThreading
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
@Override
public
void
run
()
{
for
(
int
indx_node
=
ai
.
getAndIncrement
();
indx_node
<
pendingLeafNodesFiltered
.
size
();
indx_node
=
ai
.
getAndIncrement
())
{
LwocOctree
node
=
pendingLeafNodesFiltered
.
get
(
indx_node
);
// Split recursively until satisfied conditions
node
.
splitNode
(
min_hsize
,
// double min_hsize,
max_mesh_centers
,
// int max_mesh_centers,
max_cameras
,
// int max_cameras,
check_existed
);
// boolean check_existed)
}
// end of tile
}
};
}
MultiThreading
.
startAndJoin
(
threads
);
if
(!
pendingLeafNodesFiltered
.
isEmpty
())
{
LwocWorld
world
=
pendingLeafNodesFiltered
.
get
(
0
).
world
;
final
double
min_hsize
=
world
.
getMinHsize
();
final
int
max_mesh_centers
=
world
.
getMaxMeshCenters
();
final
int
max_cameras
=
world
.
getMaxCameras
();
// run splitting multithreaded
final
Thread
[]
threads
=
MultiThreading
.
newThreadArray
();
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
@Override
public
void
run
()
{
for
(
int
indx_node
=
ai
.
getAndIncrement
();
indx_node
<
pendingLeafNodesFiltered
.
size
();
indx_node
=
ai
.
getAndIncrement
())
{
LwocOctree
node
=
pendingLeafNodesFiltered
.
get
(
indx_node
);
// Split recursively until satisfied conditions
node
.
splitNode
(
min_hsize
,
// double min_hsize,
max_mesh_centers
,
// int max_mesh_centers,
max_cameras
,
// int max_cameras,
check_existed
);
// boolean check_existed)
}
// end of tile
}
};
}
MultiThreading
.
startAndJoin
(
threads
);
}
}
/**
...
...
@@ -388,10 +399,12 @@ public class LwocOctree implements Serializable {
/**
* Grow the world to include specified point Will repeat growing twice (in each direction)
* until the specified point gets inside. Not thread safe, should run in single-thread mode
* Will mark infinity directions (inside LwocOctree constructor), so contains() will return
* true when the world size is big enough.
* @param xyz The point to be included in the world.
*/
public
void
growXYZ
(
double
[]
xyz
)
{
while
(!
world
.
lwoc_root
.
contains
(
xyz
))
{
// already fits, do not grow
while
(!
world
.
lwoc_root
.
contains
(
xyz
))
{
// already fits, do not grow
. Will obey infinity
// grow once
int
indx
=
0
;
//direction to grow
double
[]
new_center
=
new
double
[
3
];
...
...
@@ -405,7 +418,11 @@ public class LwocOctree implements Serializable {
new_center
[
dm
]=
root_center
[
dm
]
-
root_hsize
;
}
}
LwocOctree
new_root
=
new
LwocOctree
(
world
,
null
,
new_center
,
world
.
lwoc_root
.
hsize
*
2
);
LwocOctree
new_root
=
new
LwocOctree
(
// will mark infinities
world
,
null
,
new_center
,
world
.
lwoc_root
.
hsize
*
2
);
new_root
.
children
=
new
LwocOctree
[
NUM_CHILDREN
];
int
child
=
(~
indx
)
&
(
NUM_CHILDREN
-
1
);
// opposite direction, from new root to old root
for
(
int
ichild
=
0
;
ichild
<
NUM_CHILDREN
;
ichild
++)
{
...
...
@@ -413,7 +430,7 @@ public class LwocOctree implements Serializable {
world
.
lwoc_root
.
parent
=
new_root
;
new_root
.
children
[
ichild
]
=
world
.
lwoc_root
;
}
else
{
// create empty leaf nodes
new_root
.
children
[
ichild
]
=
new
LwocOctree
(
new_root
.
children
[
ichild
]
=
new
LwocOctree
(
// will mark infinities
world
,
new_root
,
new
double
[]
{
...
...
@@ -437,16 +454,26 @@ public class LwocOctree implements Serializable {
* @param half_whd half width(x), height(y) and depth(z)
* @return True if it intersects
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
boolean
intersects
(
double
[]
xyz
,
double
[]
half_whd
)
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
((
xyz
[
dm
]
-
half_whd
[
dm
])
>=
(
center
[
dm
]
+
hsize
))
{
// semiinterval
return
false
;
if
(
infinity
==
0
)
{
// this branch is just for performance, it may be removed
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
((
xyz
[
dm
]
-
half_whd
[
dm
])
>=
(
center
[
dm
]
+
hsize
))
{
// semiinterval
return
false
;
}
if
((
xyz
[
dm
]
+
half_whd
[
dm
])
<
(
center
[
dm
]
-
hsize
))
{
return
false
;
}
}
if
((
xyz
[
dm
]
+
half_whd
[
dm
])
<
(
center
[
dm
]
-
hsize
))
{
return
false
;
}
else
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
(((
xyz
[
dm
]
-
half_whd
[
dm
])
>=
(
center
[
dm
]
+
hsize
))
&&
(((
infinity
>>
(
2
*
dm
+
1
))
&
1
)
==
0
))
{
// semiinterval
return
false
;
}
if
(((
xyz
[
dm
]
+
half_whd
[
dm
])
<
(
center
[
dm
]
-
hsize
))
&&
(((
infinity
>>
(
2
*
dm
))
&
1
)
==
0
))
{
return
false
;
}
}
}
return
true
;
...
...
@@ -457,18 +484,29 @@ public class LwocOctree implements Serializable {
* @param xyz point
* @return True if it intersects
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
boolean
contains
(
double
[]
xyz
)
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
(
xyz
[
dm
]
<
(
center
[
dm
]
-
hsize
))
{
// semi-interval
return
false
;
if
(
infinity
==
0
)
{
// this branch is just for performance, it may be removed
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
(
xyz
[
dm
]
<
(
center
[
dm
]
-
hsize
))
{
// semi-interval
return
false
;
}
if
(
xyz
[
dm
]
>=
(
center
[
dm
]
+
hsize
))
{
return
false
;
}
}
if
(
xyz
[
dm
]
>=
(
center
[
dm
]
+
hsize
))
{
return
false
;
return
true
;
}
else
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
((
xyz
[
dm
]
<
(
center
[
dm
]
-
hsize
))
&&
(((
infinity
>>
(
2
*
dm
))
&
1
)
==
0
))
{
// semi-interval
return
false
;
}
if
((
xyz
[
dm
]
>=
(
center
[
dm
]
+
hsize
))
&&
(((
infinity
>>
(
2
*
dm
+
1
))
&
1
)
==
0
))
{
return
false
;
}
}
return
true
;
}
return
true
;
}
/**
...
...
@@ -477,17 +515,26 @@ public class LwocOctree implements Serializable {
* @param half_whd half width(x), height(y) and depth(z)
* @return True if it intersects
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
boolean
contains
(
double
[]
xyz
,
double
[]
half_whd
)
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
((
xyz
[
dm
]
-
half_whd
[
dm
])
<
(
center
[
dm
]
-
hsize
))
{
// semiinterval
return
false
;
if
(
infinity
==
0
)
{
// this branch is just for performance, it may be removed
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
((
xyz
[
dm
]
-
half_whd
[
dm
])
<
(
center
[
dm
]
-
hsize
))
{
// semiinterval
return
false
;
}
if
((
xyz
[
dm
]
+
half_whd
[
dm
])
>=
(
center
[
dm
]
+
hsize
))
{
return
false
;
}
}
if
((
xyz
[
dm
]
+
half_whd
[
dm
])
>=
(
center
[
dm
]
+
hsize
))
{
return
false
;
}
else
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
if
(((
xyz
[
dm
]
-
half_whd
[
dm
])
<
(
center
[
dm
]
-
hsize
))
&&
(((
infinity
>>
(
2
*
dm
))
&
1
)
==
0
)){
// semiinterval
return
false
;
}
if
(((
xyz
[
dm
]
+
half_whd
[
dm
])
>=
(
center
[
dm
]
+
hsize
))
&&
(((
infinity
>>
(
2
*
dm
+
1
))
&
1
)
==
0
)){
return
false
;
}
}
}
return
true
;
...
...
@@ -500,7 +547,7 @@ public class LwocOctree implements Serializable {
* @param check_existed Add only if the same mesh did not exist
* @return number of nodes it was added to (intersecting)
*/
public
boolean
addMeshCenter
(
// returns 0 and adds to pendingMeshes if needs growing
public
boolean
addMeshCenter
(
// returns 0 and adds to pendingMeshes if needs growing
. Obeys infinity
LwocMesh
mesh
,
boolean
check_existed
)
{
...
...
@@ -554,7 +601,7 @@ public class LwocOctree implements Serializable {
public
int
addMesh
(
LwocMesh
mesh
,
boolean
check_existed
)
{
if
(!
intersects
(
if
(!
intersects
(
// supports infinity
mesh
.
getCenter
(),
mesh
.
getDims
()))
{
return
0
;
...
...
@@ -605,7 +652,7 @@ public class LwocOctree implements Serializable {
}
/**
* Restore pointers to .parent and .world
* Restore pointers to .parent and .world
after de-serialization
* @param world
* @param parent
*/
...
...
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocWorld.java
View file @
93ac2c14
...
...
@@ -35,11 +35,10 @@ public class LwocWorld implements Serializable {
private
static
final
long
serialVersionUID
=
1L
;
static
List
<
LwocWorld
>
lwoc_worlds
;
//
public
final
double
max_hsize
;
// = 10000.0; // meter - do not grow more
public
double
min_hsize
;
// = 0.3; // meter - do not subdivide more
public
double
max_hsize
;
// = 10000.0; // meter - do not grow more
public
int
max_mesh_centers
;
// = 10; // maximal number of meshes in a leaf;
public
int
max_cameras
;
// = 10; // maximal number of cameras in a leaf;
// public transient LwocOctree lwoc_root; // = null;
public
LwocOctree
lwoc_root
;
// = null;
public
double
[]
atr
;
// = null; // Azimuth, tilt, roll - may be used to merge
public
double
[]
xyz
;
// = null; // this world offset (before rotation) or
...
...
@@ -53,7 +52,7 @@ public class LwocWorld implements Serializable {
double
[]
atr
,
double
[]
xyz
)
{
setMinHsize
(
min_hsize
);
setMaxHsize
(
max_hsize
);
this
.
max_hsize
=
max_hsize
;
// it is final, only can and has to be set in the constructor
setMaxMeshCenters
(
max_mesh_centers
);
setMaxCameras
(
max_cameras
);
setLwocRoot
(
lwoc_root
);
...
...
@@ -69,7 +68,6 @@ public class LwocWorld implements Serializable {
public
double
[]
getXYZ
()
{
return
xyz
;}
public
void
setMinHsize
(
double
min_hsize
)
{
this
.
min_hsize
=
min_hsize
;}
public
void
setMaxHsize
(
double
max_hsize
)
{
this
.
max_hsize
=
max_hsize
;}
public
void
setMaxMeshCenters
(
int
max_mesh_centers
)
{
this
.
max_mesh_centers
=
max_mesh_centers
;}
public
void
setMaxCameras
(
int
max_cameras
)
{
this
.
max_cameras
=
max_cameras
;}
public
void
setLwocRoot
(
LwocOctree
lwoc_root
)
{
this
.
lwoc_root
=
lwoc_root
;}
...
...
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