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
860cbc5f
Commit
860cbc5f
authored
Oct 22, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated for synchronized methods in growing lists, regeneration of
intersecting meshes after restoring from files.
parent
d35ccbb6
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
137 additions
and
142 deletions
+137
-142
LwocLeaf.java
...n/java/com/elphel/imagej/tileprocessor/lwoc/LwocLeaf.java
+26
-3
LwocMesh.java
...n/java/com/elphel/imagej/tileprocessor/lwoc/LwocMesh.java
+1
-0
LwocOctree.java
...java/com/elphel/imagej/tileprocessor/lwoc/LwocOctree.java
+109
-139
LwocScene.java
.../java/com/elphel/imagej/tileprocessor/lwoc/LwocScene.java
+1
-0
No files found.
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocLeaf.java
View file @
860cbc5f
...
@@ -27,6 +27,7 @@ package com.elphel.imagej.tileprocessor.lwoc;
...
@@ -27,6 +27,7 @@ package com.elphel.imagej.tileprocessor.lwoc;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
public
class
LwocLeaf
{
public
class
LwocLeaf
{
private
static
final
long
serialVersionUID
=
1L
;
ArrayList
<
LwocMesh
>
meshes
;
ArrayList
<
LwocMesh
>
meshes
;
ArrayList
<
LwocMesh
>
mesh_centers
;
ArrayList
<
LwocMesh
>
mesh_centers
;
ArrayList
<
LwocScene
>
scenes
;
ArrayList
<
LwocScene
>
scenes
;
...
@@ -36,21 +37,43 @@ public class LwocLeaf {
...
@@ -36,21 +37,43 @@ public class LwocLeaf {
scenes
=
new
ArrayList
<
LwocScene
>();
// cameras located in this node
scenes
=
new
ArrayList
<
LwocScene
>();
// cameras located in this node
}
}
public
void
addScene
(
LwocScene
scene
,
public
void
initMeshes
()
{
meshes
=
new
ArrayList
<
LwocMesh
>();
// all meshes BB intersecting this node
}
public
synchronized
void
addScene
(
// IS synchronized needed?
LwocScene
scene
,
boolean
check_existed
)
{
boolean
check_existed
)
{
if
(!
check_existed
||
!
scenes
.
contains
(
scene
))
{
if
(!
check_existed
||
!
scenes
.
contains
(
scene
))
{
scenes
.
add
(
scene
);
scenes
.
add
(
scene
);
}
}
}
}
public
void
addMeshCenter
(
LwocMesh
mesh
,
public
synchronized
void
addMeshCenter
(
// IS synchronized needed?
LwocMesh
mesh
,
boolean
check_existed
)
{
boolean
check_existed
)
{
if
(!
check_existed
||
!
mesh_centers
.
contains
(
mesh
))
{
if
(!
check_existed
||
!
mesh_centers
.
contains
(
mesh
))
{
mesh_centers
.
add
(
mesh
);
mesh_centers
.
add
(
mesh
);
}
}
}
}
public
void
addMesh
(
LwocMesh
mesh
,
public
synchronized
void
removeScene
(
LwocScene
scene
)
{
while
(
scenes
.
remove
(
scene
));
// will remove all
}
public
synchronized
void
removeMeshCenter
(
LwocMesh
mesh
)
{
while
(
mesh_centers
.
remove
(
mesh
));
// will remove all
}
public
synchronized
void
removeMesh
(
LwocMesh
mesh
)
{
while
(
meshes
.
remove
(
mesh
));
// will remove all
}
public
synchronized
void
addMesh
(
// synchronized IS needed
LwocMesh
mesh
,
boolean
check_existed
)
{
boolean
check_existed
)
{
if
(!
check_existed
||
!
meshes
.
contains
(
mesh
))
{
if
(!
check_existed
||
!
meshes
.
contains
(
mesh
))
{
meshes
.
add
(
mesh
);
meshes
.
add
(
mesh
);
...
...
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocMesh.java
View file @
860cbc5f
...
@@ -28,6 +28,7 @@ import java.util.ArrayList;
...
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.AtomicInteger
;
public
class
LwocMesh
{
public
class
LwocMesh
{
private
static
final
long
serialVersionUID
=
1L
;
static
AtomicInteger
MESH_ID
=
new
AtomicInteger
();
static
AtomicInteger
MESH_ID
=
new
AtomicInteger
();
static
ArrayList
<
LwocMesh
>
LWOC_MESHES
;
static
ArrayList
<
LwocMesh
>
LWOC_MESHES
;
int
id
;
// assign unique ID
int
id
;
// assign unique ID
...
...
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocOctree.java
View file @
860cbc5f
...
@@ -29,6 +29,7 @@ import java.util.List;
...
@@ -29,6 +29,7 @@ import java.util.List;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
com.elphel.imagej.common.MultiThreading
;
import
com.elphel.imagej.common.MultiThreading
;
public
class
LwocOctree
{
public
class
LwocOctree
{
private
static
final
long
serialVersionUID
=
1L
;
public
static
final
int
NUM_CHILDREN
=
8
;
public
static
final
int
NUM_CHILDREN
=
8
;
public
static
double
MIN_HSIZE
=
0.3
;
// meter - do not subdivide more
public
static
double
MIN_HSIZE
=
0.3
;
// meter - do not subdivide more
// can not be used as intersecting meshes' bb will not decrease number after splitting
// can not be used as intersecting meshes' bb will not decrease number after splitting
...
@@ -37,14 +38,10 @@ public class LwocOctree {
...
@@ -37,14 +38,10 @@ public class LwocOctree {
public
static
LwocOctree
lwoc_root
=
null
;
public
static
LwocOctree
lwoc_root
=
null
;
static
ArrayList
<
LwocOctree
>
LWOK_OCTREE
=
new
ArrayList
<
LwocOctree
>();
static
ArrayList
<
LwocOctree
>
LWOK_OCTREE
=
new
ArrayList
<
LwocOctree
>();
static
AtomicInteger
OCTREE_ID
=
new
AtomicInteger
();
static
AtomicInteger
OCTREE_ID
=
new
AtomicInteger
();
// synchronized lists to handle thread-unsafe operations: growing world and splitting leaves
/// 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
AtomicInteger
numPendingScenes
;
static
List
<
LwocScene
>
pendingScenes
;
// synchronized - add not-yet-added scenes pending growing world
static
AtomicInteger
numPendingMeshes
;
static
List
<
LwocMesh
>
pendingMeshes
;
// synchronized - add not-yet-added meshes pending growing world
static
AtomicInteger
numPendingLeafNodes
;
static
List
<
LwocOctree
>
pendingLeafNodes
;
// synchronized - leaf nodes needed to be split
int
id
;
// assign unique ID
int
id
;
// assign unique ID
...
@@ -53,6 +50,26 @@ public class LwocOctree {
...
@@ -53,6 +50,26 @@ public class LwocOctree {
LwocLeaf
leaf
;
//
LwocLeaf
leaf
;
//
double
[]
center
;
// x-center, y-center, z-center
double
[]
center
;
// x-center, y-center, z-center
double
hsize
;
double
hsize
;
public
static
void
addPendingScene
(
LwocScene
scene
)
{
synchronized
(
pendingScenes
)
{
pendingScenes
.
add
(
scene
);
}
}
public
static
void
addPendingMesh
(
LwocMesh
mesh
)
{
synchronized
(
pendingMeshes
)
{
pendingMeshes
.
add
(
mesh
);
}
}
public
static
void
addPendingLeafNode
(
LwocOctree
node
)
{
synchronized
(
pendingLeafNodes
)
{
pendingLeafNodes
.
add
(
node
);
}
}
// just for testing
// just for testing
// List<List<LwocScene>> group = new ArrayList<List<LwocScene>>(4);
// List<List<LwocScene>> group = new ArrayList<List<LwocScene>>(4);
...
@@ -79,9 +96,9 @@ public class LwocOctree {
...
@@ -79,9 +96,9 @@ public class LwocOctree {
* processes by a single-thread method.
* processes by a single-thread method.
*/
*/
public
static
void
resetPending
()
{
public
static
void
resetPending
()
{
numPendingScenes
.
set
(
0
);
// = Collections.synchronizedList(new ArrayList<LwocScene>()
);
pendingScenes
=
new
ArrayList
<
LwocScene
>(
);
numPendingMeshes
.
set
(
0
);
// = Collections.synchronizedList(new ArrayList<LwocMesh>()
);
pendingMeshes
=
new
ArrayList
<
LwocMesh
>(
);
numPendingLeafNodes
.
set
(
0
);
// = Collections.synchronizedList(new ArrayList<LwocOctree>()
);
pendingLeafNodes
=
new
ArrayList
<
LwocOctree
>(
);
}
}
// use per-thread lists and then combine them avoiding synchronizations?
// use per-thread lists and then combine them avoiding synchronizations?
//Pass list to any function that may grow it
//Pass list to any function that may grow it
...
@@ -99,7 +116,7 @@ public class LwocOctree {
...
@@ -99,7 +116,7 @@ public class LwocOctree {
* @return if world needs growing.
* @return if world needs growing.
*/
*/
public
static
boolean
pendingGrow
()
{
public
static
boolean
pendingGrow
()
{
return
(
numPendingScenes
.
get
()
+
numPendingMeshes
.
get
())
>
0
;
return
(
pendingScenes
.
size
()
+
pendingMeshes
.
size
())
>
0
;
}
}
/**
/**
...
@@ -107,7 +124,7 @@ public class LwocOctree {
...
@@ -107,7 +124,7 @@ public class LwocOctree {
* @return if any leaf nodes require splitting
* @return if any leaf nodes require splitting
*/
*/
public
static
boolean
pendingSplit
()
{
public
static
boolean
pendingSplit
()
{
return
numPendingLeafNodes
.
get
()
>
0
;
return
pendingLeafNodes
.
size
()
>
0
;
}
}
/**
/**
...
@@ -152,23 +169,18 @@ public class LwocOctree {
...
@@ -152,23 +169,18 @@ public class LwocOctree {
* Add scene to the world in a thread-safe mode, or put it to pending list if the world
* Add scene to the world in a thread-safe mode, or put it to pending list if the world
* needs growing.
* needs growing.
* @param scene Scene to add.
* @param scene Scene to add.
* @param pendingScenes per thread list of scenes to be combined after merging threads
* @param pendingLeafNodes per thread list of nodes to be combined after merging threads
* @param check_existed - do not add duplicate scenes and nodes
* @param check_existed - do not add duplicate scenes and nodes
* @return An octree node where scene is added or null if the world needs growing
* @return An octree node where scene is added or null if the world needs growing
*/
*/
public
static
LwocOctree
addScene
(
public
static
LwocOctree
addScene
(
LwocScene
scene
,
LwocScene
scene
,
ArrayList
<
LwocScene
>
pendingScenes
,
ArrayList
<
LwocOctree
>
pendingLeafNodes
,
boolean
check_existed
boolean
check_existed
)
{
// returns null and adds to pendingScenes if needs growing
)
{
// returns null and adds to pendingScenes if needs growing
LwocOctree
node
=
getLeafNode
(
scene
.
getCameraXYZ
());
LwocOctree
node
=
getLeafNode
(
scene
.
getCameraXYZ
());
if
(
node
==
null
)
{
if
(
node
==
null
)
{
if
(
pendingScenes
!=
null
)
{
if
(
pendingScenes
!=
null
)
{
if
(!
check_existed
||
!
pendingScenes
.
contains
(
scene
))
{
if
(!
check_existed
||
!
pendingScenes
.
contains
(
scene
))
{
pendingScenes
.
add
(
scene
);
addPendingScene
(
scene
);
numPendingScenes
.
getAndIncrement
();
}
}
}
}
}
else
{
}
else
{
...
@@ -177,8 +189,7 @@ public class LwocOctree {
...
@@ -177,8 +189,7 @@ public class LwocOctree {
if
(
node
.
leaf
.
getScenes
().
size
()
>
MAX_CAMERAS
)
{
if
(
node
.
leaf
.
getScenes
().
size
()
>
MAX_CAMERAS
)
{
if
(
node
.
hsize
>
MIN_HSIZE
)
{
if
(
node
.
hsize
>
MIN_HSIZE
)
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
pendingLeafNodes
.
add
(
node
);
addPendingLeafNode
(
node
);
numPendingLeafNodes
.
getAndIncrement
();
}
}
}
}
}
}
...
@@ -188,13 +199,9 @@ public class LwocOctree {
...
@@ -188,13 +199,9 @@ public class LwocOctree {
/**
/**
* Tend to pending scenes list. Not thread-safe, should be run in a single-thread mode.
* Tend to pending scenes list. Not thread-safe, should be run in a single-thread mode.
* @param pendingScenes combined list of scenes to be added growing world (merged from per-thread ones)
* @param pendingLeafNodes a list of nodes that will need splitting (here in single-thread mode - single one)
* @param check_existed - do not add duplicate scenes and nodes
* @param check_existed - do not add duplicate scenes and nodes
*/
*/
public
static
void
tendPendingScenes
(
public
static
void
tendPendingScenes
(
ArrayList
<
LwocScene
>
pendingScenes
,
ArrayList
<
LwocOctree
>
pendingLeafNodes
,
boolean
check_existed
boolean
check_existed
)
{
)
{
if
(
pendingScenes
.
isEmpty
())
{
if
(
pendingScenes
.
isEmpty
())
{
...
@@ -204,8 +211,6 @@ public class LwocOctree {
...
@@ -204,8 +211,6 @@ public class LwocOctree {
growXYZ
(
scene
.
getCameraXYZ
());
growXYZ
(
scene
.
getCameraXYZ
());
LwocOctree
node
=
addScene
(
// should not be null
LwocOctree
node
=
addScene
(
// should not be null
scene
,
scene
,
pendingScenes
,
pendingLeafNodes
,
check_existed
);
check_existed
);
assert
node
!=
null
:
"addScene() should not fail after growing world"
;
assert
node
!=
null
:
"addScene() should not fail after growing world"
;
}
}
...
@@ -216,13 +221,9 @@ public class LwocOctree {
...
@@ -216,13 +221,9 @@ public class LwocOctree {
* Tend to pending meshes list. Not thread-safe, should be run in a single-thread mode.
* Tend to pending meshes list. Not thread-safe, should be run in a single-thread mode.
* Only adds mesh centers and grows the world if needed.
* Only adds mesh centers and grows the world if needed.
* @param check_existed do not add duplicate meshes
* @param check_existed do not add duplicate meshes
* @param pendingMeshes combined list of meshes to be added (merged from per-thread ones). Will only be read.
* @param pendingLeafNodes a list of nodes that will need splitting (here in single-thread mode - single one). May grow.
*/
*/
public
static
void
tendPendingMeshCentersOnly
(
public
static
void
tendPendingMeshCentersOnly
(
boolean
check_existed
,
boolean
check_existed
ArrayList
<
LwocMesh
>
pendingMeshes
,
// will read
ArrayList
<
LwocOctree
>
pendingLeafNodes
// may add to
)
{
)
{
if
(
pendingMeshes
.
isEmpty
())
{
if
(
pendingMeshes
.
isEmpty
())
{
return
;
// nothing to do
return
;
// nothing to do
...
@@ -240,9 +241,7 @@ public class LwocOctree {
...
@@ -240,9 +241,7 @@ public class LwocOctree {
}
}
boolean
ok
=
addMeshCenter
(
// should not be null
boolean
ok
=
addMeshCenter
(
// should not be null
mesh
,
mesh
,
check_existed
,
check_existed
);
null
,
// pendingMeshes,
pendingLeafNodes
);
assert
ok
:
"addMeshCenter() should not fail after growing world"
;
assert
ok
:
"addMeshCenter() should not fail after growing world"
;
}
}
}
}
...
@@ -253,13 +252,9 @@ public class LwocOctree {
...
@@ -253,13 +252,9 @@ public class LwocOctree {
* Only adds mesh themselves that do not trigger node splits.
* Only adds mesh themselves that do not trigger node splits.
* Should be run after tendPendingMeshCentersOnly().
* Should be run after tendPendingMeshCentersOnly().
* @param check_existed do not add duplicate meshes
* @param check_existed do not add duplicate meshes
* @param pendingMeshes combined list of meshes to be added (merged from per-thread ones).
* Will only be read.
*/
*/
public
static
void
tendPendingMeshes
(
public
static
void
tendPendingMeshes
(
boolean
check_existed
,
boolean
check_existed
)
{
ArrayList
<
LwocMesh
>
pendingMeshes
// will read
)
{
if
(
pendingMeshes
.
isEmpty
())
{
if
(
pendingMeshes
.
isEmpty
())
{
return
;
// nothing to do
return
;
// nothing to do
}
else
{
}
else
{
...
@@ -276,8 +271,6 @@ public class LwocOctree {
...
@@ -276,8 +271,6 @@ public class LwocOctree {
/**
/**
* Recursively (if needed) splits octree nodes to reduce number of scenes/cameras
* Recursively (if needed) splits octree nodes to reduce number of scenes/cameras
* and mesh centers below specified thresholds (limited by the minimal node size)
* and mesh centers below specified thresholds (limited by the minimal node size)
* @param pendingLeafNodesIn array list of nodes to be split. Will be filtered to
* remove any duplicates and non-leaf nodes
* @param min_hsize Minimal half-size of the node (in meters). Smaller nodes will not be split
* @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
* @param max_mesh_centers Maximal number of mesh centers in a node. Larger number
* triggers node split.
* triggers node split.
...
@@ -286,17 +279,15 @@ public class LwocOctree {
...
@@ -286,17 +279,15 @@ public class LwocOctree {
* @param check_existed
* @param check_existed
*/
*/
public
static
void
tendPendingLeafNodes
(
public
static
void
tendPendingLeafNodes
(
ArrayList
<
LwocOctree
>
pendingLeafNodesIn
,
final
double
min_hsize
,
final
double
min_hsize
,
final
int
max_mesh_centers
,
final
int
max_mesh_centers
,
final
int
max_cameras
,
// scenes
final
int
max_cameras
,
// scenes
final
boolean
check_existed
)
{
final
boolean
check_existed
)
{
// remove any possible duplicates
// remove any possible duplicates
final
ArrayList
<
LwocOctree
>
pendingLeafNodes
=
new
ArrayList
<
LwocOctree
>();
final
ArrayList
<
LwocOctree
>
pendingLeafNodesFiltered
=
new
ArrayList
<
LwocOctree
>();
for
(
LwocOctree
node:
pendingLeafNodesIn
)
{
for
(
LwocOctree
node:
pendingLeafNodes
)
{
if
(!
pendingLeafNodes
.
contains
(
node
)
&&
node
.
isLeaf
())
{
// filter already split nodes
if
(!
pendingLeafNodesFiltered
.
contains
(
node
)
&&
node
.
isLeaf
())
{
// filter already split nodes
pendingLeafNodes
.
add
(
node
);
pendingLeafNodesFiltered
.
add
(
node
);
numPendingLeafNodes
.
getAndIncrement
();
}
}
}
}
// run splitting multithreaded
// run splitting multithreaded
...
@@ -306,8 +297,8 @@ public class LwocOctree {
...
@@ -306,8 +297,8 @@ public class LwocOctree {
threads
[
ithread
]
=
new
Thread
()
{
threads
[
ithread
]
=
new
Thread
()
{
@Override
@Override
public
void
run
()
{
public
void
run
()
{
for
(
int
indx_node
=
ai
.
getAndIncrement
();
indx_node
<
pendingLeafNodes
.
size
();
indx_node
=
ai
.
getAndIncrement
())
{
for
(
int
indx_node
=
ai
.
getAndIncrement
();
indx_node
<
pendingLeafNodes
Filtered
.
size
();
indx_node
=
ai
.
getAndIncrement
())
{
LwocOctree
node
=
pendingLeafNodes
.
get
(
indx_node
);
LwocOctree
node
=
pendingLeafNodes
Filtered
.
get
(
indx_node
);
// Split recursively until satisfied conditions
// Split recursively until satisfied conditions
node
.
splitNode
(
node
.
splitNode
(
min_hsize
,
// double min_hsize,
min_hsize
,
// double min_hsize,
...
@@ -319,7 +310,6 @@ public class LwocOctree {
...
@@ -319,7 +310,6 @@ public class LwocOctree {
};
};
}
}
MultiThreading
.
startAndJoin
(
threads
);
MultiThreading
.
startAndJoin
(
threads
);
ai
.
set
(
0
);
}
}
// Split recursively until satisfied conditions
// Split recursively until satisfied conditions
...
@@ -517,15 +507,11 @@ public class LwocOctree {
...
@@ -517,15 +507,11 @@ public class LwocOctree {
* add to pending list if does not fit in a root node
* add to pending list if does not fit in a root node
* @param mesh new mesh to add
* @param mesh new mesh to add
* @param check_existed Add only if the same mesh did not exist
* @param check_existed Add only if the same mesh did not exist
* @param pendingMeshes per thread list of meshes to be combined after merging threads
* @param pendingLeafNodes per thread list of nodes to be combined after merging threads
* @return number of nodes it was added to (intersecting)
* @return number of nodes it was added to (intersecting)
*/
*/
public
static
boolean
addMeshCenter
(
// returns 0 and adds to pendingMeshes if needs growing
public
static
boolean
addMeshCenter
(
// returns 0 and adds to pendingMeshes if needs growing
LwocMesh
mesh
,
LwocMesh
mesh
,
boolean
check_existed
,
boolean
check_existed
ArrayList
<
LwocMesh
>
pendingMeshes
,
ArrayList
<
LwocOctree
>
pendingLeafNodes
)
{
)
{
// should in check before adding?
// should in check before adding?
// mesh.equals(mesh);
// mesh.equals(mesh);
...
@@ -538,8 +524,7 @@ public class LwocOctree {
...
@@ -538,8 +524,7 @@ public class LwocOctree {
if
(!
lwoc_root
.
contains
(
corner_xyz
)){
if
(!
lwoc_root
.
contains
(
corner_xyz
)){
if
(
pendingMeshes
!=
null
)
{
if
(
pendingMeshes
!=
null
)
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
pendingMeshes
.
add
(
mesh
);
addPendingMesh
(
mesh
);
numPendingMeshes
.
getAndIncrement
();
}
}
}
}
return
false
;
return
false
;
...
@@ -548,8 +533,7 @@ public class LwocOctree {
...
@@ -548,8 +533,7 @@ public class LwocOctree {
if
(!
lwoc_root
.
contains
(
corner_xyz
)){
if
(!
lwoc_root
.
contains
(
corner_xyz
)){
if
(
pendingMeshes
!=
null
)
{
if
(
pendingMeshes
!=
null
)
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
pendingMeshes
.
add
(
mesh
);
addPendingMesh
(
mesh
);
numPendingMeshes
.
getAndIncrement
();
}
}
}
}
return
false
;
return
false
;
...
@@ -563,8 +547,7 @@ public class LwocOctree {
...
@@ -563,8 +547,7 @@ public class LwocOctree {
if
(
node
.
leaf
.
getMeshCenters
().
size
()
>
MAX_MESH_CENTERS
)
{
if
(
node
.
leaf
.
getMeshCenters
().
size
()
>
MAX_MESH_CENTERS
)
{
if
(
node
.
hsize
>
MIN_HSIZE
)
{
if
(
node
.
hsize
>
MIN_HSIZE
)
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
pendingLeafNodes
.
add
(
node
);
addPendingLeafNode
(
node
);
numPendingLeafNodes
.
getAndIncrement
();
}
}
}
}
}
}
...
@@ -573,6 +556,13 @@ public class LwocOctree {
...
@@ -573,6 +556,13 @@ public class LwocOctree {
}
}
// recursive
// recursive
/**
* Recursively add mesh to all leaf nodes that intersect with its bounding box.
* Usually starts with lwoc_root.
* @param mesh Mesh instance to be added
* @param check_existed verify node lists does not already have this mesh if true
* @return number of nodes to which this mesh was added
*/
public
int
addMesh
(
public
int
addMesh
(
LwocMesh
mesh
,
LwocMesh
mesh
,
boolean
check_existed
)
{
boolean
check_existed
)
{
...
@@ -593,102 +583,82 @@ public class LwocOctree {
...
@@ -593,102 +583,82 @@ public class LwocOctree {
}
}
/**
/**
* Remove mesh
to from each node intersecting with the mesh bounding box
.
* Remove mesh
center from the world
.
* Should fit in a root node (as it was earlier added)
* Should fit in a root node (as it was earlier added)
* @param mesh new mesh to add
* @param mesh new mesh to add
* @param check_existed Add only if the same mesh did not exist
* @return The number of nodes it was removed from
*/
*/
public
static
int
removeMesh
(
public
static
void
removeMeshCenter
(
LwocMesh
mesh
,
LwocMesh
mesh
)
{
// check and remove duplicates
boolean
remove_all
)
{
// check and remove duplicates
LwocOctree
node
=
getLeafNode
(
mesh
.
getCenter
());
// should in check before adding?
node
.
leaf
.
removeMeshCenter
(
mesh
);
return
0
;
}
}
/**
/**
* Prepare list of lists to add scenes in multithreaded environment, one inner
* Remove mesh from each node intersecting with the mesh bounding box.
* list for each thread.
* Should fit in a root node (as it was earlier added)
* @param threads Array of threads, only length is used
* @param mesh mesh to remove
* @return list of lists to provide to threads
*/
*/
public
static
List
<
List
<
LwocScene
>>
getMultiPendingScenes
(
Thread
[]
threads
){
public
int
removeMesh
(
List
<
List
<
LwocScene
>>
multiPendingScenes
=
new
ArrayList
<
List
<
LwocScene
>>(
threads
.
length
);
LwocMesh
mesh
)
{
// check and remove duplicates
for
(
int
i
=
0
;
i
<
threads
.
length
;
i
++)
{
if
(!
intersects
(
multiPendingScenes
.
add
(
i
,
new
ArrayList
<
LwocScene
>());
mesh
.
getCenter
(),
mesh
.
getDims
()))
{
return
0
;
}
}
return
multiPendingScenes
;
if
(
isLeaf
())
{
leaf
.
removeMesh
(
mesh
);
return
1
;
}
}
int
removed
=
0
;
/**
for
(
LwocOctree
node:
children
)
{
* Combine a List of list of scenes (created in multithreaded method getMultiPendingScenes())
removed
+=
node
.
removeMesh
(
mesh
);
* into a single list.
* @param multiPendingScenes list of list of scenes
* @return flattened single list of scenes
*/
public
static
List
<
LwocScene
>
mergeMultiPendingScenes
(
List
<
List
<
LwocScene
>>
multiPendingScenes
){
List
<
LwocScene
>
pendingScenes
=
new
ArrayList
<
LwocScene
>();
for
(
List
<
LwocScene
>
scenes:
multiPendingScenes
)
{
pendingScenes
.
addAll
(
scenes
);
}
}
return
pendingScenes
;
return
removed
;
}
}
/**
/**
* Prepare list of lists to add meshes in multithreaded environment, one inner
* Recursively create a list of all leave nodes in the world.
* list for each thread.
* @return A list of all leaf nodes
* @param threads Array of threads, only length is used
* @return list of lists to provide to threads
*/
*/
public
static
List
<
List
<
LwocMesh
>>
getMultiPendingMeshes
(
Thread
[]
threads
){
public
List
<
LwocOctree
>
getAllLeafNodes
(){
List
<
List
<
LwocMesh
>>
multiPendingMeshes
=
new
ArrayList
<
List
<
LwocMesh
>>(
threads
.
length
);
List
<
LwocOctree
>
leaves
=
new
ArrayList
<
LwocOctree
>();
for
(
int
i
=
0
;
i
<
threads
.
length
;
i
++)
{
if
(
isLeaf
())
{
multiPendingMeshes
.
add
(
i
,
new
ArrayList
<
LwocMesh
>());
leaves
.
add
(
this
);
}
else
{
for
(
LwocOctree
child:
children
)
{
leaves
.
addAll
(
child
.
getAllLeafNodes
());
}
}
return
multiPendingMeshes
;
}
return
leaves
;
}
}
/**
/**
* Combine a List of list of meshes (created in multithreaded method getMultiPendingMeshes())
* Rebuild meshes lists from mesh_centers for all leaf nodes after restoring the world.
* into a single list.
* Used after restoring world from serialized form
* @param multiPendingMeshes list of list of meshes
* @return flattened single list of meshes
*/
*/
public
static
List
<
LwocMesh
>
mergeMultiPendingMeshes
(
List
<
List
<
LwocMesh
>>
multiPendingMeshes
){
public
static
void
rebuildMeshLists
(
List
<
LwocMesh
>
pendingMeshes
=
new
ArrayList
<
LwocMesh
>();
final
boolean
check_existed
)
{
for
(
List
<
LwocMesh
>
meshes:
multiPendingMeshes
)
{
final
List
<
LwocOctree
>
leaves
=
lwoc_root
.
getAllLeafNodes
();
pendingMeshes
.
addAll
(
meshes
);
final
List
<
LwocMesh
>
meshes
=
new
ArrayList
<
LwocMesh
>();
}
for
(
LwocOctree
node
:
leaves
)
{
return
pendingMeshes
;
node
.
leaf
.
initMeshes
();
meshes
.
addAll
(
node
.
leaf
.
getMeshCenters
());
}
}
/**
final
Thread
[]
threads
=
MultiThreading
.
newThreadArray
();
* Prepare list of lists to add scenes in multithreaded environment, one inner
final
AtomicInteger
ai
=
new
AtomicInteger
(
0
);
* list for each thread.
* @param threads Array of threads, only length is used
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
* @return list of lists to provide to threads
threads
[
ithread
]
=
new
Thread
()
{
*/
@Override
public
static
List
<
List
<
LwocOctree
>>
getMultiPendingLeafNodes
(
Thread
[]
threads
)
{
public
void
run
()
{
List
<
List
<
LwocOctree
>>
multiPendingLeafNodes
=
new
ArrayList
<
List
<
LwocOctree
>>(
threads
.
length
);
for
(
int
indx_mesh
=
ai
.
getAndIncrement
();
indx_mesh
<
meshes
.
size
();
indx_mesh
=
ai
.
getAndIncrement
())
{
for
(
int
i
=
0
;
i
<
threads
.
length
;
i
++)
{
LwocMesh
mesh
=
meshes
.
get
(
indx_mesh
);
multiPendingLeafNodes
.
add
(
i
,
new
ArrayList
<
LwocOctree
>()
);
lwoc_root
.
addMesh
(
mesh
,
check_existed
);
}
}
return
multiPendingLeafNodes
;
}
}
};
/**
* Combine a List of list of scenes (created in multithreaded method getMultiPendingScenes())
* into a single list.
* @param multiPendingLeafNodes list of list of scenes
* @return flattened single list of scenes
*/
public
static
List
<
LwocOctree
>
mergeMultiPendingLeafNodes
(
List
<
List
<
LwocOctree
>>
multiPendingLeafNodes
){
List
<
LwocOctree
>
pendingLeafNodes
=
new
ArrayList
<
LwocOctree
>();
for
(
List
<
LwocOctree
>
nodes:
multiPendingLeafNodes
)
{
pendingLeafNodes
.
addAll
(
nodes
);
}
}
return
pendingLeafNodes
;
MultiThreading
.
startAndJoin
(
threads
)
;
}
}
}
}
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocScene.java
View file @
860cbc5f
...
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import
com.elphel.imagej.tileprocessor.GeometryCorrection
;
import
com.elphel.imagej.tileprocessor.GeometryCorrection
;
public
class
LwocScene
{
public
class
LwocScene
{
private
static
final
long
serialVersionUID
=
1L
;
static
AtomicInteger
SCENE_ID
=
new
AtomicInteger
();
static
AtomicInteger
SCENE_ID
=
new
AtomicInteger
();
static
ArrayList
<
LwocScene
>
LWOC_SCENES
;
static
ArrayList
<
LwocScene
>
LWOC_SCENES
;
...
...
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