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
8176593d
Commit
8176593d
authored
Oct 25, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored to have multiple world (needed when scenes can not be
matched)
parent
7e53b24d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
274 additions
and
151 deletions
+274
-151
LwocMesh.java
...n/java/com/elphel/imagej/tileprocessor/lwoc/LwocMesh.java
+4
-4
LwocOctree.java
...java/com/elphel/imagej/tileprocessor/lwoc/LwocOctree.java
+83
-147
LwocWorld.java
.../java/com/elphel/imagej/tileprocessor/lwoc/LwocWorld.java
+187
-0
No files found.
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocMesh.java
View file @
8176593d
...
@@ -25,11 +25,11 @@
...
@@ -25,11 +25,11 @@
package
com
.
elphel
.
imagej
.
tileprocessor
.
lwoc
;
package
com
.
elphel
.
imagej
.
tileprocessor
.
lwoc
;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.concurrent.atomic.AtomicInteger
;
///
import java.util.concurrent.atomic.AtomicInteger;
public
class
LwocMesh
implements
Serializable
{
public
class
LwocMesh
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
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
String
stimestamp
;
// mesh is always referenced to a single scene
String
stimestamp
;
// mesh is always referenced to a single scene
...
@@ -37,7 +37,7 @@ public class LwocMesh implements Serializable {
...
@@ -37,7 +37,7 @@ public class LwocMesh implements Serializable {
double
[]
hdims_xyz
;
// world bounding box half-dimensions along x,y,z
double
[]
hdims_xyz
;
// world bounding box half-dimensions along x,y,z
public
static
void
resetMeshes
()
{
public
static
void
resetMeshes
()
{
MESH_ID
.
set
(
0
);
///
MESH_ID.set(0);
// LWOC_MESHES = new ArrayList<LwocMesh>();
// LWOC_MESHES = new ArrayList<LwocMesh>();
}
}
// maybe use mesh properties instead of id?
// maybe use mesh properties instead of id?
...
@@ -48,7 +48,7 @@ public class LwocMesh implements Serializable {
...
@@ -48,7 +48,7 @@ public class LwocMesh implements Serializable {
String
stimestamp
String
stimestamp
)
{
)
{
this
.
stimestamp
=
stimestamp
;
this
.
stimestamp
=
stimestamp
;
id
=
MESH_ID
.
getAndIncrement
();
///
id = MESH_ID.getAndIncrement();
// LWOC_MESHES.add(this);
// LWOC_MESHES.add(this);
}
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocOctree.java
View file @
8176593d
...
@@ -24,11 +24,11 @@
...
@@ -24,11 +24,11 @@
package
com
.
elphel
.
imagej
.
tileprocessor
.
lwoc
;
package
com
.
elphel
.
imagej
.
tileprocessor
.
lwoc
;
import
java.io.FileInputStream
;
//
import java.io.FileInputStream;
import
java.io.FileOutputStream
;
//
import java.io.FileOutputStream;
import
java.io.IOException
;
//
import java.io.IOException;
import
java.io.ObjectInputStream
;
//
import java.io.ObjectInputStream;
import
java.io.ObjectOutputStream
;
//
import java.io.ObjectOutputStream;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -37,99 +37,21 @@ import com.elphel.imagej.common.MultiThreading;
...
@@ -37,99 +37,21 @@ import com.elphel.imagej.common.MultiThreading;
public
class
LwocOctree
implements
Serializable
{
public
class
LwocOctree
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
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
// static AtomicInteger OCTREE_ID = new AtomicInteger();
// can not be used as intersecting meshes' bb will not decrease number after splitting
public
static
int
MAX_MESH_CENTERS
=
10
;
// maximal number of meshes in a leaf;
public
static
int
MAX_CAMERAS
=
10
;
// maximal number of cameras in a leaf;
public
static
LwocOctree
lwoc_root
=
null
;
// static ArrayList<LwocOctree> LWOK_OCTREE = new ArrayList<LwocOctree>();
static
AtomicInteger
OCTREE_ID
=
new
AtomicInteger
();
static
List
<
LwocScene
>
pendingScenes
;
// synchronized - add not-yet-added scenes pending growing world
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
<
LwocMesh
>
pendingMeshes
;
// synchronized - add not-yet-added meshes pending growing world
static
List
<
LwocOctree
>
pendingLeafNodes
;
// synchronized - leaf nodes needed to be split
static
List
<
LwocOctree
>
pendingLeafNodes
;
// synchronized - leaf nodes needed to be split
// static List<LwocWorld> lwoc_worlds; //
int
id
;
// assign unique ID
int
id
;
// assign unique ID
LwocOctree
parent
;
transient
LwocWorld
world
;
transient
LwocOctree
parent
;
LwocOctree
[]
children
;
LwocOctree
[]
children
;
LwocLeaf
leaf
;
//
LwocLeaf
leaf
;
//
double
[]
center
;
// x-center, y-center, z-center
double
[]
center
;
// x-center, y-center, z-center
double
hsize
;
double
hsize
;
/**
* Serialize and write world to an output stream
* @param oos ObjectOutputStream to write to.
* @throws IOException
*/
private
void
writeObject
(
ObjectOutputStream
oos
)
throws
IOException
{
oos
.
defaultWriteObject
();
if
(
parent
==
null
)
{
// write static members
oos
.
writeObject
(
MIN_HSIZE
);
oos
.
writeObject
(
MAX_MESH_CENTERS
);
oos
.
writeObject
(
MAX_CAMERAS
);
oos
.
writeObject
(
OCTREE_ID
.
get
());
oos
.
writeObject
(
LwocMesh
.
MESH_ID
.
get
());
}
}
/**
* Read input stream and deserialize it to world octree structure.
* @param ois ObjectInputStream to read from
* @throws ClassNotFoundException
* @throws IOException
*/
private
void
readObject
(
ObjectInputStream
ois
)
throws
ClassNotFoundException
,
IOException
{
ois
.
defaultReadObject
();
if
(
parent
==
null
)
{
// read static members
MIN_HSIZE
=
(
Double
)
ois
.
readObject
();
MAX_MESH_CENTERS
=
(
Integer
)
ois
.
readObject
();
MAX_CAMERAS
=
(
Integer
)
ois
.
readObject
();
OCTREE_ID
.
set
(
(
Integer
)
ois
.
readObject
());
LwocMesh
.
MESH_ID
.
set
((
Integer
)
ois
.
readObject
());
}
}
/**
*
* @param path
*/
public
static
void
saveWorld
(
String
path
)
{
try
{
FileOutputStream
fileOut
=
new
FileOutputStream
(
path
);
ObjectOutputStream
out
=
new
ObjectOutputStream
(
fileOut
);
out
.
writeObject
(
lwoc_root
);
// will cause all world to be saved
out
.
close
();
fileOut
.
close
();
System
.
out
.
printf
(
"Serialized data is saved in "
+
path
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
public
static
void
restoreWorld
(
String
path
)
{
try
{
FileInputStream
fileIn
=
new
FileInputStream
(
path
);
ObjectInputStream
in
=
new
ObjectInputStream
(
fileIn
);
lwoc_root
=
(
LwocOctree
)
in
.
readObject
();
in
.
close
();
fileIn
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
;
}
catch
(
ClassNotFoundException
c
)
{
System
.
out
.
println
(
path
+
" not found"
);
c
.
printStackTrace
();
return
;
}
}
public
static
void
addPendingScene
(
LwocScene
scene
)
{
public
static
void
addPendingScene
(
LwocScene
scene
)
{
synchronized
(
pendingScenes
)
{
synchronized
(
pendingScenes
)
{
pendingScenes
.
add
(
scene
);
pendingScenes
.
add
(
scene
);
...
@@ -148,22 +70,6 @@ public class LwocOctree implements Serializable {
...
@@ -148,22 +70,6 @@ public class LwocOctree implements Serializable {
}
}
}
}
/**
* Initialize Octree data and set initial world node. It is possible to grow
* world as needed later.
* @param center world center: x,y,z in meters. Usually {0,0,0}
* @param world_hsize Half linear dimension of the world
*/
public
static
void
initOctree
(
double
[]
center
,
double
world_hsize
)
{
LwocMesh
.
resetMeshes
();
LwocScene
.
resetScenes
();
resetPending
();
// LWOK_OCTREE = new ArrayList<LwocOctree>();
// Add a single leaf node
lwoc_root
=
new
LwocOctree
(
null
,
center
,
world_hsize
);
lwoc_root
.
leaf
=
new
LwocLeaf
();
}
/**
/**
* Synchronized lists of pending scenes, meshes and nodes are used to delay modification of
* Synchronized lists of pending scenes, meshes and nodes are used to delay modification of
* the world octree and its elements from the multithreaded environment. These lists should
* the world octree and its elements from the multithreaded environment. These lists should
...
@@ -202,18 +108,19 @@ public class LwocOctree implements Serializable {
...
@@ -202,18 +108,19 @@ public class LwocOctree implements Serializable {
/**
/**
* LwocOctree constructor
* LwocOctree constructor
* @param lwocWorld World global parameters
* @param parent Parent node
* @param parent Parent node
* @param xyz
p
osition of the node center in meters
* @param xyz
P
osition of the node center in meters
* @param hsize Node half size - each of the X,Y,Z coordinates of the internal
* @param hsize Node half size - each of the X,Y,Z coordinates of the internal
* points are limited within +/-hsize from the node center
* points are limited within +/-hsize from the node center
*/
*/
public
LwocOctree
(
LwocOctree
parent
,
public
LwocOctree
(
LwocWorld
lwocWorld
,
LwocOctree
parent
,
double
[]
xyz
,
double
[]
xyz
,
double
hsize
)
{
double
hsize
)
{
id
=
OCTREE_ID
.
getAndIncrement
();
this
.
parent
=
parent
;
this
.
parent
=
parent
;
this
.
hsize
=
hsize
;
this
.
hsize
=
hsize
;
// LWOK_OCTREE.add(this);
}
}
/**
/**
...
@@ -222,14 +129,15 @@ public class LwocOctree implements Serializable {
...
@@ -222,14 +129,15 @@ public class LwocOctree implements Serializable {
* @return Octree node that includes the point or null if the point
* @return Octree node that includes the point or null if the point
* is outside the root node (the whole world)
* is outside the root node (the whole world)
*/
*/
public
static
LwocOctree
getLeafNode
(
// if null - needs growing 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
double
[]
xyz
)
{
// thread safe
if
(!
lwoc_root
.
contains
(
xyz
))
return
null
;
// needs growing world
if
(!
world
.
getLwocRoot
()
.
contains
(
xyz
))
return
null
;
// needs growing world
LwocOctree
node
=
lwoc_root
;
LwocOctree
node
=
world
.
getLwocRoot
()
;
while
(
lwoc_root
.
children
!=
null
)
{
while
(
world
.
getLwocRoot
()
.
children
!=
null
)
{
int
indx
=
0
;
int
indx
=
0
;
for
(
int
dm
=
0
;
dm
<
3
;
dm
++)
{
for
(
int
dm
=
0
;
dm
<
3
;
dm
++)
{
if
(
xyz
[
dm
]
>=
lwoc_root
.
center
[
dm
]
)
{
if
(
xyz
[
dm
]
>=
world
.
getLwocRoot
()
.
center
[
dm
]
)
{
indx
+=
1
<<
dm
;
indx
+=
1
<<
dm
;
}
}
}
}
...
@@ -245,7 +153,7 @@ public class LwocOctree implements Serializable {
...
@@ -245,7 +153,7 @@ public class LwocOctree implements Serializable {
* @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
LwocOctree
addScene
(
LwocScene
scene
,
LwocScene
scene
,
boolean
check_existed
boolean
check_existed
)
{
// returns null and adds to pendingScenes if needs growing
)
{
// returns null and adds to pendingScenes if needs growing
...
@@ -259,8 +167,8 @@ public class LwocOctree implements Serializable {
...
@@ -259,8 +167,8 @@ public class LwocOctree implements Serializable {
}
else
{
}
else
{
node
.
leaf
.
addScene
(
scene
,
check_existed
);
node
.
leaf
.
addScene
(
scene
,
check_existed
);
// Check if leaf node requires splitting
// Check if leaf node requires splitting
if
(
node
.
leaf
.
getScenes
().
size
()
>
MAX_CAMERAS
)
{
if
(
node
.
leaf
.
getScenes
().
size
()
>
world
.
getMaxCameras
()
)
{
if
(
node
.
hsize
>
MIN_HSIZE
)
{
if
(
node
.
hsize
>
world
.
getMinHsize
()
)
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
addPendingLeafNode
(
node
);
addPendingLeafNode
(
node
);
}
}
...
@@ -274,7 +182,7 @@ public class LwocOctree implements Serializable {
...
@@ -274,7 +182,7 @@ public class LwocOctree implements Serializable {
* 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 check_existed - do not add duplicate scenes and nodes
* @param check_existed - do not add duplicate scenes and nodes
*/
*/
public
static
void
tendPendingScenes
(
public
void
tendPendingScenes
(
boolean
check_existed
boolean
check_existed
)
{
)
{
if
(
pendingScenes
.
isEmpty
())
{
if
(
pendingScenes
.
isEmpty
())
{
...
@@ -295,7 +203,7 @@ public class LwocOctree implements Serializable {
...
@@ -295,7 +203,7 @@ public class LwocOctree implements Serializable {
* 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
*/
*/
public
static
void
tendPendingMeshCentersOnly
(
public
void
tendPendingMeshCentersOnly
(
boolean
check_existed
boolean
check_existed
)
{
)
{
if
(
pendingMeshes
.
isEmpty
())
{
if
(
pendingMeshes
.
isEmpty
())
{
...
@@ -326,14 +234,14 @@ public class LwocOctree implements Serializable {
...
@@ -326,14 +234,14 @@ public class LwocOctree implements Serializable {
* 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
*/
*/
public
static
void
tendPendingMeshes
(
public
void
tendPendingMeshes
(
boolean
check_existed
)
{
boolean
check_existed
)
{
if
(
pendingMeshes
.
isEmpty
())
{
if
(
pendingMeshes
.
isEmpty
())
{
return
;
// nothing to do
return
;
// nothing to do
}
else
{
}
else
{
for
(
LwocMesh
mesh:
pendingMeshes
)
{
for
(
LwocMesh
mesh:
pendingMeshes
)
{
// int num_added =
// int num_added =
lwoc_root
.
addMesh
(
world
.
lwoc_root
.
addMesh
(
mesh
,
mesh
,
check_existed
);
check_existed
);
}
}
...
@@ -417,6 +325,7 @@ public class LwocOctree implements Serializable {
...
@@ -417,6 +325,7 @@ public class LwocOctree implements Serializable {
xyz
[
dm
]
+=
new_hsize
*
((((
nchild
>>
dm
)
&
1
)
>
0
)?
1
:
-
1
);
xyz
[
dm
]
+=
new_hsize
*
((((
nchild
>>
dm
)
&
1
)
>
0
)?
1
:
-
1
);
}
}
children
[
nchild
]
=
new
LwocOctree
(
children
[
nchild
]
=
new
LwocOctree
(
world
,
this
,
this
,
xyz
,
xyz
,
new_hsize
);
new_hsize
);
...
@@ -481,41 +390,44 @@ public class LwocOctree implements Serializable {
...
@@ -481,41 +390,44 @@ public class LwocOctree implements Serializable {
* until the specified point gets inside. Not thread safe, should run in single-thread mode
* until the specified point gets inside. Not thread safe, should run in single-thread mode
* @param xyz The point to be included in the world.
* @param xyz The point to be included in the world.
*/
*/
public
static
void
growXYZ
(
double
[]
xyz
)
{
public
void
growXYZ
(
double
[]
xyz
)
{
while
(!
lwoc_root
.
contains
(
xyz
))
{
// already fits, do not grow
while
(!
world
.
lwoc_root
.
contains
(
xyz
))
{
// already fits, do not grow
// grow once
// grow once
int
indx
=
0
;
//direction to grow
int
indx
=
0
;
//direction to grow
double
[]
new_center
=
new
double
[
3
];
double
[]
new_center
=
new
double
[
3
];
double
[]
root_center
=
world
.
lwoc_root
.
center
;
double
root_hsize
=
world
.
lwoc_root
.
hsize
;
for
(
int
dm
=
0
;
dm
<
new_center
.
length
;
dm
++)
{
for
(
int
dm
=
0
;
dm
<
new_center
.
length
;
dm
++)
{
if
(
xyz
[
dm
]
>=
lwoc_root
.
center
[
dm
]
)
{
if
(
xyz
[
dm
]
>=
root_
center
[
dm
]
)
{
indx
+=
1
<<
dm
;
indx
+=
1
<<
dm
;
new_center
[
dm
]=
lwoc_root
.
center
[
dm
]
+
lwoc_root
.
hsize
;
new_center
[
dm
]=
root_center
[
dm
]
+
root_
hsize
;
}
else
{
}
else
{
new_center
[
dm
]=
lwoc_root
.
center
[
dm
]
-
lwoc_root
.
hsize
;
new_center
[
dm
]=
root_center
[
dm
]
-
root_
hsize
;
}
}
}
}
LwocOctree
new_root
=
new
LwocOctree
(
null
,
new_center
,
lwoc_root
.
hsize
*
2
);
LwocOctree
new_root
=
new
LwocOctree
(
world
,
null
,
new_center
,
world
.
lwoc_root
.
hsize
*
2
);
new_root
.
children
=
new
LwocOctree
[
NUM_CHILDREN
];
new_root
.
children
=
new
LwocOctree
[
NUM_CHILDREN
];
int
child
=
(~
indx
)
&
(
NUM_CHILDREN
-
1
);
// opposite direction, from new root to old root
int
child
=
(~
indx
)
&
(
NUM_CHILDREN
-
1
);
// opposite direction, from new root to old root
for
(
int
ichild
=
0
;
ichild
<
NUM_CHILDREN
;
ichild
++)
{
for
(
int
ichild
=
0
;
ichild
<
NUM_CHILDREN
;
ichild
++)
{
if
(
ichild
==
child
)
{
if
(
ichild
==
child
)
{
lwoc_root
.
parent
=
new_root
;
world
.
lwoc_root
.
parent
=
new_root
;
new_root
.
children
[
ichild
]
=
lwoc_root
;
new_root
.
children
[
ichild
]
=
world
.
lwoc_root
;
}
else
{
// create empty leaf nodes
}
else
{
// create empty leaf nodes
new_root
.
children
[
ichild
]
=
new
LwocOctree
(
new_root
.
children
[
ichild
]
=
new
LwocOctree
(
world
,
new_root
,
new_root
,
new
double
[]
{
new
double
[]
{
new_center
[
0
]
+
lwoc_root
.
hsize
*
((((
child
>>
0
)
&
1
)
>
0
)?
1
:
-
1
),
new_center
[
0
]
+
root_
hsize
*
((((
child
>>
0
)
&
1
)
>
0
)?
1
:
-
1
),
new_center
[
1
]
+
lwoc_root
.
hsize
*
((((
child
>>
1
)
&
1
)
>
0
)?
1
:
-
1
),
new_center
[
1
]
+
root_
hsize
*
((((
child
>>
1
)
&
1
)
>
0
)?
1
:
-
1
),
new_center
[
2
]
+
lwoc_root
.
hsize
*
((((
child
>>
2
)
&
1
)
>
0
)?
1
:
-
1
)
new_center
[
2
]
+
root_
hsize
*
((((
child
>>
2
)
&
1
)
>
0
)?
1
:
-
1
)
},
},
lwoc_root
.
hsize
);
root_
hsize
);
// add leaf
// add leaf
new_root
.
children
[
ichild
].
leaf
=
new
LwocLeaf
();
new_root
.
children
[
ichild
].
leaf
=
new
LwocLeaf
();
}
}
}
}
lwoc_root
=
new_root
;
world
.
lwoc_root
=
new_root
;
}
}
}
}
...
@@ -525,6 +437,7 @@ public class LwocOctree implements Serializable {
...
@@ -525,6 +437,7 @@ public class LwocOctree implements Serializable {
* @param half_whd half width(x), height(y) and depth(z)
* @param half_whd half width(x), height(y) and depth(z)
* @return True if it intersects
* @return True if it intersects
*/
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
boolean
intersects
(
public
boolean
intersects
(
double
[]
xyz
,
double
[]
xyz
,
double
[]
half_whd
)
{
double
[]
half_whd
)
{
...
@@ -544,6 +457,7 @@ public class LwocOctree implements Serializable {
...
@@ -544,6 +457,7 @@ public class LwocOctree implements Serializable {
* @param xyz point
* @param xyz point
* @return True if it intersects
* @return True if it intersects
*/
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
boolean
contains
(
public
boolean
contains
(
double
[]
xyz
)
{
double
[]
xyz
)
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
...
@@ -563,6 +477,8 @@ public class LwocOctree implements Serializable {
...
@@ -563,6 +477,8 @@ public class LwocOctree implements Serializable {
* @param half_whd half width(x), height(y) and depth(z)
* @param half_whd half width(x), height(y) and depth(z)
* @return True if it intersects
* @return True if it intersects
*/
*/
//FIXME: obey border (on the edges of max hsize of the root) nodes
public
boolean
contains
(
public
boolean
contains
(
double
[]
xyz
,
double
[]
xyz
,
double
[]
half_whd
)
{
double
[]
half_whd
)
{
...
@@ -584,7 +500,7 @@ public class LwocOctree implements Serializable {
...
@@ -584,7 +500,7 @@ public class LwocOctree implements Serializable {
* @param check_existed Add only if the same mesh did not exist
* @param check_existed Add only if the same mesh did not exist
* @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
boolean
addMeshCenter
(
// returns 0 and adds to pendingMeshes if needs growing
LwocMesh
mesh
,
LwocMesh
mesh
,
boolean
check_existed
boolean
check_existed
)
{
)
{
...
@@ -594,7 +510,7 @@ public class LwocOctree implements Serializable {
...
@@ -594,7 +510,7 @@ public class LwocOctree implements Serializable {
double
[]
corner_xyz
=
center
.
clone
();
double
[]
corner_xyz
=
center
.
clone
();
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
for
(
int
dm
=
0
;
dm
<
center
.
length
;
dm
++)
{
corner_xyz
[
dm
]
+=
dims
[
dm
];
corner_xyz
[
dm
]
+=
dims
[
dm
];
if
(!
lwoc_root
.
contains
(
corner_xyz
)){
if
(!
world
.
lwoc_root
.
contains
(
corner_xyz
)){
if
(
pendingMeshes
!=
null
)
{
if
(
pendingMeshes
!=
null
)
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
addPendingMesh
(
mesh
);
addPendingMesh
(
mesh
);
...
@@ -603,7 +519,7 @@ public class LwocOctree implements Serializable {
...
@@ -603,7 +519,7 @@ public class LwocOctree implements Serializable {
return
false
;
return
false
;
}
}
corner_xyz
[
dm
]
-=
2
*
dims
[
dm
];
corner_xyz
[
dm
]
-=
2
*
dims
[
dm
];
if
(!
lwoc_root
.
contains
(
corner_xyz
)){
if
(!
world
.
lwoc_root
.
contains
(
corner_xyz
)){
if
(
pendingMeshes
!=
null
)
{
if
(
pendingMeshes
!=
null
)
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
if
(!
check_existed
||
!
pendingMeshes
.
contains
(
mesh
))
{
addPendingMesh
(
mesh
);
addPendingMesh
(
mesh
);
...
@@ -617,8 +533,8 @@ public class LwocOctree implements Serializable {
...
@@ -617,8 +533,8 @@ public class LwocOctree implements Serializable {
LwocOctree
node
=
getLeafNode
(
center
);
LwocOctree
node
=
getLeafNode
(
center
);
node
.
leaf
.
addMeshCenter
(
mesh
,
check_existed
);
node
.
leaf
.
addMeshCenter
(
mesh
,
check_existed
);
// Check if leaf node requires splitting
// Check if leaf node requires splitting
if
(
node
.
leaf
.
getMeshCenters
().
size
()
>
MAX_MESH_CENTERS
)
{
if
(
node
.
leaf
.
getMeshCenters
().
size
()
>
world
.
getMaxMeshCenters
()
)
{
if
(
node
.
hsize
>
MIN_HSIZE
)
{
if
(
node
.
hsize
>
world
.
getMinHsize
()
)
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
if
(!
check_existed
||
!
pendingLeafNodes
.
contains
(
node
))
{
addPendingLeafNode
(
node
);
addPendingLeafNode
(
node
);
}
}
...
@@ -659,7 +575,7 @@ public class LwocOctree implements Serializable {
...
@@ -659,7 +575,7 @@ public class LwocOctree implements Serializable {
* 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
*/
*/
public
static
void
removeMeshCenter
(
public
void
removeMeshCenter
(
LwocMesh
mesh
)
{
// check and remove duplicates
LwocMesh
mesh
)
{
// check and remove duplicates
LwocOctree
node
=
getLeafNode
(
mesh
.
getCenter
());
LwocOctree
node
=
getLeafNode
(
mesh
.
getCenter
());
node
.
leaf
.
removeMeshCenter
(
mesh
);
node
.
leaf
.
removeMeshCenter
(
mesh
);
...
@@ -688,6 +604,26 @@ public class LwocOctree implements Serializable {
...
@@ -688,6 +604,26 @@ public class LwocOctree implements Serializable {
return
removed
;
return
removed
;
}
}
/**
* Restore pointers to .parent and .world
* @param world
* @param parent
*/
public
void
restoreWorldParent
(
LwocWorld
world
,
LwocOctree
parent
)
{
this
.
parent
=
parent
;
this
.
world
=
world
;
if
(!
isLeaf
())
{
for
(
LwocOctree
child:
children
)
{
child
.
restoreWorldParent
(
world
,
// LwocWorld world,
this
);
// LwocOctree parent)
}
}
}
/**
/**
* Recursively create a list of all leave nodes in the world.
* Recursively create a list of all leave nodes in the world.
* @return A list of all leaf nodes
* @return A list of all leaf nodes
...
@@ -708,9 +644,9 @@ public class LwocOctree implements Serializable {
...
@@ -708,9 +644,9 @@ public class LwocOctree implements Serializable {
* Rebuild meshes lists from mesh_centers for all leaf nodes after restoring the world.
* Rebuild meshes lists from mesh_centers for all leaf nodes after restoring the world.
* Used after restoring world from serialized form
* Used after restoring world from serialized form
*/
*/
public
static
void
rebuildMeshLists
(
public
void
rebuildMeshLists
(
final
boolean
check_existed
)
{
final
boolean
check_existed
)
{
final
List
<
LwocOctree
>
leaves
=
lwoc_root
.
getAllLeafNodes
();
final
List
<
LwocOctree
>
leaves
=
world
.
lwoc_root
.
getAllLeafNodes
();
final
List
<
LwocMesh
>
meshes
=
new
ArrayList
<
LwocMesh
>();
final
List
<
LwocMesh
>
meshes
=
new
ArrayList
<
LwocMesh
>();
for
(
LwocOctree
node
:
leaves
)
{
for
(
LwocOctree
node
:
leaves
)
{
node
.
leaf
.
initMeshes
();
node
.
leaf
.
initMeshes
();
...
@@ -726,7 +662,7 @@ public class LwocOctree implements Serializable {
...
@@ -726,7 +662,7 @@ public class LwocOctree implements Serializable {
public
void
run
()
{
public
void
run
()
{
for
(
int
indx_mesh
=
ai
.
getAndIncrement
();
indx_mesh
<
meshes
.
size
();
indx_mesh
=
ai
.
getAndIncrement
())
{
for
(
int
indx_mesh
=
ai
.
getAndIncrement
();
indx_mesh
<
meshes
.
size
();
indx_mesh
=
ai
.
getAndIncrement
())
{
LwocMesh
mesh
=
meshes
.
get
(
indx_mesh
);
LwocMesh
mesh
=
meshes
.
get
(
indx_mesh
);
lwoc_root
.
addMesh
(
mesh
,
check_existed
);
world
.
lwoc_root
.
addMesh
(
mesh
,
check_existed
);
}
}
}
}
};
};
...
...
src/main/java/com/elphel/imagej/tileprocessor/lwoc/LwocWorld.java
0 → 100644
View file @
8176593d
/**
**
** LwocWorld.java - Octree world parameters (previous static)
**
** Copyright (C) 2022 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** LwocWorld.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/>.
** -----------------------------------------------------------------------------**
**
*/
package
com
.
elphel
.
imagej
.
tileprocessor
.
lwoc
;
import
java.io.IOException
;
import
java.io.ObjectInputStream
;
import
java.io.ObjectOutputStream
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
LwocWorld
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
static
List
<
LwocWorld
>
lwoc_worlds
;
//
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
// null if not known.
public
LwocWorld
(
double
min_hsize
,
double
max_hsize
,
int
max_mesh_centers
,
int
max_cameras
,
LwocOctree
lwoc_root
,
double
[]
atr
,
double
[]
xyz
)
{
setMinHsize
(
min_hsize
);
setMaxHsize
(
max_hsize
);
setMaxMeshCenters
(
max_mesh_centers
);
setMaxCameras
(
max_cameras
);
setLwocRoot
(
lwoc_root
);
setATR
(
atr
);
setXYZ
(
xyz
);
}
public
double
getMinHsize
()
{
return
min_hsize
;}
public
double
getMaxHsize
()
{
return
max_hsize
;}
public
int
getMaxMeshCenters
()
{
return
max_mesh_centers
;}
public
int
getMaxCameras
()
{
return
max_cameras
;}
public
LwocOctree
getLwocRoot
()
{
return
lwoc_root
;}
public
double
[]
getATR
()
{
return
atr
;}
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
;}
public
void
setATR
(
double
[]
atr
)
{
this
.
atr
=
atr
;}
public
void
setXYZ
(
double
[]
xyz
)
{
this
.
xyz
=
xyz
;}
/**
* Serialize and write world to an output stream
* @param oos ObjectOutputStream to write to.
* @throws IOException
*/
private
void
writeObject
(
ObjectOutputStream
oos
)
throws
IOException
{
oos
.
defaultWriteObject
();
// as of now - nothing else, custom for reads only
// if (parent == null) { // write world members
/*
oos.writeObject(world.getMinHsize());
oos.writeObject(world.getMaxHsize());
oos.writeObject(world.getMaxMeshCenters());
oos.writeObject(world.getMaxCameras());
oos.writeObject(world.getATR());
oos.writeObject(world.getXYZ());
*/
// oos.writeObject(world);
// Remove those
// oos.writeObject(OCTREE_ID.get());
// oos.writeObject(LwocMesh.MESH_ID.get());
// }
}
/**
* Read input stream and deserialize it to world octree structure.
* @param ois ObjectInputStream to read from
* @throws ClassNotFoundException
* @throws IOException
*/
private
void
readObject
(
ObjectInputStream
ois
)
throws
ClassNotFoundException
,
IOException
{
ois
.
defaultReadObject
();
// now rebuild transient .parent and .world field for the whole tree
lwoc_root
.
restoreWorldParent
(
this
,
// LwocWorld world,
null
);
//LwocOctree parent)
lwoc_root
.
rebuildMeshLists
(
true
);
// final boolean check_existed)
}
/**
* Init worlds and their list. Multiple worlds may be needed if some world initially can not
* be matched. They will grow independently and possibly merged later
*/
public
static
void
initWorlds
()
{
LwocMesh
.
resetMeshes
();
LwocScene
.
resetScenes
();
LwocOctree
.
resetPending
();
lwoc_worlds
=
new
ArrayList
<
LwocWorld
>();
}
/**
* Create a new empty world and add it to the list of worlds in the universe.
* @param center X,Y,Z of the new world
* @param world_hsize new world half-size
* @param min_hsize do not subdivide nodes if half-size is smaller than this
* @param max_hsize do not grow world if its half-size it >= this
* @param max_mesh_centers maximal number of mesh centers in a node to trigger subdivision
* @param max_cameras maximal number of scenes (cameras) in a node to trigger subdivision
* @param atr world rotation relative to the universe (non-null when defined)
* @param xyz world offset in the universe (non-null when defined)
* @return new world instance
*/
public
static
LwocWorld
newWorld
(
double
[]
center
,
double
world_hsize
,
double
min_hsize
,
double
max_hsize
,
int
max_mesh_centers
,
int
max_cameras
,
double
[]
atr
,
double
[]
xyz
)
{
LwocWorld
new_world
=
new
LwocWorld
(
min_hsize
,
// double min_hsize,
max_hsize
,
// double max_hsize,
max_mesh_centers
,
// int max_mesh_centers,
max_cameras
,
// int max_cameras,
null
,
// LwocOctree lwoc_root,
null
,
//double [] atr,
null
);
//double [] xyz);
LwocOctree
root_node
=
new
LwocOctree
(
new_world
,
// LwocWorld lwocWorld,
null
,
// LwocOctree parent,
center
,
// double [] xyz,
world_hsize
);
//double hsize)
root_node
.
leaf
=
new
LwocLeaf
();
new_world
.
setLwocRoot
(
root_node
);
lwoc_worlds
.
add
(
new_world
);
return
new_world
;
}
/**
* Delete world from the universe (if existed)
* @param world world instance to remove
* @return True if removed, false if did not exist.
*/
public
static
boolean
deleteWorld
(
LwocWorld
world
)
{
return
lwoc_worlds
.
remove
(
world
);
}
}
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