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
4e6966e0
Commit
4e6966e0
authored
Sep 25, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Debugging gltf export
parent
82b27573
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1299 additions
and
425 deletions
+1299
-425
pom.xml
pom.xml
+12
-0
CLTParameters.java
src/main/java/com/elphel/imagej/cameras/CLTParameters.java
+118
-61
OpticalFlow.java
...ain/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
+1
-1
QuadCLTCPU.java
...main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
+122
-23
TexturedModel.java
...n/java/com/elphel/imagej/tileprocessor/TexturedModel.java
+121
-239
TileCluster.java
...ain/java/com/elphel/imagej/tileprocessor/TileCluster.java
+54
-46
TileProcessor.java
...n/java/com/elphel/imagej/tileprocessor/TileProcessor.java
+214
-55
GlTfExport.java
src/main/java/com/elphel/imagej/x3d/export/GlTfExport.java
+483
-0
TriMesh.java
src/main/java/com/elphel/imagej/x3d/export/TriMesh.java
+140
-0
WavefrontExport.java
...in/java/com/elphel/imagej/x3d/export/WavefrontExport.java
+24
-0
X3dOutput.java
src/main/java/com/elphel/imagej/x3d/export/X3dOutput.java
+10
-0
No files found.
pom.xml
View file @
4e6966e0
...
...
@@ -27,6 +27,18 @@
<description>
A Maven project implementing imagej-elphel plugin
</description>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>
com.google.code.gson
</groupId>
<artifactId>
gson
</artifactId>
<version>
2.9.1
</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
<dependency>
<groupId>
com.googlecode.json-simple
</groupId>
<artifactId>
json-simple
</artifactId>
<version>
1.1
</version>
</dependency>
<!-- ssh support - see https://www.baeldung.com/java-ssh-connection -->
<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-core -->
<dependency>
...
...
src/main/java/com/elphel/imagej/cameras/CLTParameters.java
View file @
4e6966e0
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
View file @
4e6966e0
...
...
@@ -903,7 +903,7 @@ public class OpticalFlow {
* @param debug_level if > 0; print number of tiles to correlate
* @return flowXY vectors only for tiles to be updated or null if no tiles left
*/
double
[][]
recalculateFlowXY
(
static
double
[][]
recalculateFlowXY
(
final
double
[][]
flowXY
,
// will update
final
double
[][]
flowXY_prev
,
// previous flowXY (may be null for tiles)
final
double
[][]
corr_vectorsXY
,
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
View file @
4e6966e0
...
...
@@ -65,6 +65,7 @@ import com.elphel.imagej.correction.EyesisCorrections;
import
com.elphel.imagej.gpu.GpuQuad
;
import
com.elphel.imagej.gpu.TpTask
;
import
com.elphel.imagej.readers.ImagejJp4Tiff
;
import
com.elphel.imagej.x3d.export.TriMesh
;
import
com.elphel.imagej.x3d.export.WavefrontExport
;
import
com.elphel.imagej.x3d.export.X3dOutput
;
...
...
@@ -7552,11 +7553,11 @@ public class QuadCLTCPU {
double
[]
rel_lim
=
{
getMarginFromHist
(
hist
,
// histogram
too_cold
,
// double cumul_val, // cum
m
ulative number of items to be ignored
too_cold
,
// double cumul_val, // cumulative number of items to be ignored
false
),
// boolean high_marg)
getMarginFromHist
(
hist
,
// histogram
too_hot
,
// double cumul_val, // cum
m
ulative number of items to be ignored
too_hot
,
// double cumul_val, // cumulative number of items to be ignored
true
)};
// boolean high_marg)
double
[]
abs_lim
=
{
rel_lim
[
0
]
*
(
hard_hot
-
hard_cold
)
+
hard_cold
,
...
...
@@ -12455,6 +12456,7 @@ public class QuadCLTCPU {
double
infinity_disparity
=
geometryCorrection
.
getDisparityFromZ
(
clt_parameters
.
infinityDistance
);
X3dOutput
x3dOutput
=
null
;
WavefrontExport
wfOutput
=
null
;
ArrayList
<
TriMesh
>
tri_meshes
=
null
;
if
(
clt_parameters
.
remove_scans
){
System
.
out
.
println
(
"Removing all scans but the first(background) and the last to save memory"
);
System
.
out
.
println
(
"Will need to re-start the program to be able to output differently"
);
...
...
@@ -12503,6 +12505,10 @@ public class QuadCLTCPU {
// do nothing, just keep
}
}
if
(
clt_parameters
.
output_glTF
&&
(
x3d_path
!=
null
))
{
tri_meshes
=
new
ArrayList
<
TriMesh
>();
}
if
(
x3dOutput
!=
null
)
{
x3dOutput
.
generateBackground
(
clt_parameters
.
infinityDistance
<=
0.0
);
// needs just first (background) scan
}
...
...
@@ -12579,6 +12585,7 @@ public class QuadCLTCPU {
generateClusterX3d
(
x3dOutput
,
wfOutput
,
// output WSavefront if not null
tri_meshes
,
// ArrayList<TriMesh> tri_meshes,
texturePath
,
"INFINITY"
,
// id (scanIndex - next_pass), // id
"INFINITY"
,
// class
...
...
@@ -12590,7 +12597,11 @@ public class QuadCLTCPU {
showTri
,
// (scanIndex < next_pass + 1) && clt_parameters.show_triangles,
infinity_disparity
,
// 0.3
clt_parameters
.
grow_disp_max
,
// other_range, // 2.0 'other_range - difference from the specified (*_CM)
clt_parameters
.
maxDispTriangle
);
clt_parameters
.
maxDispTriangle
,
clt_parameters
.
maxZtoXY
,
// double maxZtoXY, // 10.0. <=0 - do not use
clt_parameters
.
maxZ
,
clt_parameters
.
limitZ
,
debugLevel
+
1
);
// int debug_level) > 0
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
...
...
@@ -12668,11 +12679,11 @@ public class QuadCLTCPU {
}
}
boolean
showTri
=
!
batch_mode
&&
(
debugLevel
>
-
1
)
&&
(((
scanIndex
<
next_pass
+
1
)
&&
clt_parameters
.
show_triangles
)
||((
scanIndex
-
next_pass
)
==
73
));
try
{
generateClusterX3d
(
x3dOutput
,
wfOutput
,
// output WSavefront if not null
tri_meshes
,
// ArrayList<TriMesh> tri_meshes,
texturePath
,
"shape_id-"
+(
scanIndex
-
next_pass
),
// id
null
,
// class
...
...
@@ -12685,7 +12696,11 @@ public class QuadCLTCPU {
// FIXME: make a separate parameter:
infinity_disparity
,
// 0.25 * clt_parameters.bgnd_range, // 0.3
clt_parameters
.
grow_disp_max
,
// other_range, // 2.0 'other_range - difference from the specified (*_CM)
clt_parameters
.
maxDispTriangle
);
clt_parameters
.
maxDispTriangle
,
clt_parameters
.
maxZtoXY
,
// double maxZtoXY, // 10.0. <=0 - do not use
clt_parameters
.
maxZ
,
clt_parameters
.
limitZ
,
debugLevel
+
1
);
// int debug_level) > 0
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
false
;
...
...
@@ -12718,6 +12733,7 @@ public class QuadCLTCPU {
public
void
generateClusterX3d
(
// USED in lwir
X3dOutput
x3dOutput
,
// output x3d if not null
WavefrontExport
wfOutput
,
// output WSavefront if not null
ArrayList
<
TriMesh
>
tri_meshes
,
String
texturePath
,
String
id
,
String
class_name
,
...
...
@@ -12729,18 +12745,23 @@ public class QuadCLTCPU {
boolean
show_triangles
,
double
min_disparity
,
double
max_disparity
,
double
maxDispTriangle
double
maxDispTriangle
,
// relative <=0 - do not use
double
maxZtoXY
,
// 10.0. <=0 - do not use
double
maxZ
,
// far clip (0 - do not clip). Negative - limit by max
boolean
limitZ
,
int
debug_level
)
throws
IOException
{
// int debug_level = 1;
if
(
bounds
==
null
)
{
return
;
// not used in lwir
}
int
[][]
indices
=
tp
.
getCoordIndices
(
// starting with 0, -1 - not selected
int
[][]
indices
=
tp
.
getCoordIndices
(
// starting with 0, -1 - not selected
// updated 09.18.2022
bounds
,
selected
);
double
[][]
texCoord
=
TileProcessor
.
getTexCoords
(
// get texture coordinates for indices
indices
);
double
[][]
worldXYZ
=
tp
.
getCoords
(
// get world XYZ in meters for indices
double
[][]
worldXYZ
=
tp
.
getCoords
(
// get world XYZ in meters for indices
// updated 09.18.2022
disparity
,
min_disparity
,
max_disparity
,
...
...
@@ -12750,7 +12771,7 @@ public class QuadCLTCPU {
correctDistortions
,
// requires backdrop image to be corrected also
this
.
geometryCorrection
);
double
[]
indexedDisparity
=
tp
.
getIndexedDisparities
(
// get disparity for each index
double
[]
indexedDisparity
=
tp
.
getIndexedDisparities
(
// get disparity for each index
// updated 09.18.2022
disparity
,
min_disparity
,
max_disparity
,
...
...
@@ -12761,12 +12782,83 @@ public class QuadCLTCPU {
int
[][]
triangles
=
TileProcessor
.
triangulateCluster
(
indices
);
// double maxZtoXY = 10.0; // maximal delta_z to sqrt(dx^23 + dy^2)
int
num_removed
=
0
;
if
(
maxDispTriangle
>
0.0
)
{
int
pre_num
=
triangles
.
length
;
triangles
=
TileProcessor
.
filterTriangles
(
// remove crazy triangles with large disparity difference
triangles
,
indexedDisparity
,
// disparities per vertex index
maxDispTriangle
);
// maximal disparity difference in a triangle
maxDispTriangle
,
// maximal disparity difference in a triangle
debug_level
+
0
);
// int debug_level);
if
(
triangles
.
length
<
pre_num
)
{
num_removed
+=
pre_num
-
triangles
.
length
;
if
(
debug_level
>
0
)
{
System
.
out
.
println
(
"filterTriangles() removed "
+
(
pre_num
-
triangles
.
length
)+
" triangles"
);
}
}
}
if
((
maxZ
!=
0.0
)
&&
limitZ
)
{
for
(
int
i
=
0
;
i
<
worldXYZ
.
length
;
i
++)
{
if
(
worldXYZ
[
i
][
2
]
<
-
maxZ
)
{
double
k
=
-
maxZ
/
worldXYZ
[
i
][
2
];
worldXYZ
[
i
][
0
]
*=
k
;
worldXYZ
[
i
][
1
]
*=
k
;
worldXYZ
[
i
][
2
]
*=
k
;
}
}
}
if
((
maxZtoXY
>
0.0
)
||
((
maxZ
!=
0
)
&&
!
limitZ
)
)
{
int
pre_num
=
triangles
.
length
;
triangles
=
TileProcessor
.
filterTrianglesWorld
(
triangles
,
worldXYZ
,
// world per vertex index
maxZtoXY
,
maxZ
);
if
(
triangles
.
length
<
pre_num
)
{
num_removed
+=
pre_num
-
triangles
.
length
;
if
(
debug_level
>
0
)
{
System
.
out
.
println
(
"filterTrianglesWorld() removed "
+
(
pre_num
-
triangles
.
length
)+
" triangles"
);
}
}
}
if
(
triangles
.
length
==
0
)
{
if
(
debug_level
>
0
)
{
System
.
out
.
println
(
"generateClusterX3d() no triangles left in a cluster"
);
}
return
;
// all triangles removed
}
if
(
num_removed
>
0
)
{
int
[]
re_index
=
TileProcessor
.
reIndex
(
// Move to TriMesh?
indices
,
// will be modified if needed (if some indices are removed
triangles
);
if
(
re_index
!=
null
)
{
// need to update other arrays: texCoord, worldXYZ. indexedDisparity[] will not be used
int
num_indices_old
=
worldXYZ
.
length
;
int
[]
inv_index
=
new
int
[
num_indices_old
];
Arrays
.
fill
(
inv_index
,-
1
);
// just to get an error
for
(
int
i
=
0
;
i
<
re_index
.
length
;
i
++)
{
inv_index
[
re_index
[
i
]]
=
i
;
}
double
[][]
texCoord_new
=
new
double
[
re_index
.
length
][];
double
[][]
worldXYZ_new
=
new
double
[
re_index
.
length
][];
for
(
int
i
=
0
;
i
<
re_index
.
length
;
i
++)
{
texCoord_new
[
i
]
=
texCoord
[
re_index
[
i
]];
worldXYZ_new
[
i
]
=
worldXYZ
[
re_index
[
i
]];
}
texCoord
=
texCoord_new
;
worldXYZ
=
worldXYZ_new
;
for
(
int
i
=
0
;
i
<
triangles
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
triangles
[
i
].
length
;
j
++)
{
triangles
[
i
][
j
]
=
inv_index
[
triangles
[
i
][
j
]];
}
}
}
if
(
debug_level
>
0
)
{
show_triangles
=
true
;
// show after removed
}
}
if
(
show_triangles
)
{
double
[]
ddisp
=
(
disparity
==
null
)?(
new
double
[
1
]):
disparity
;
...
...
@@ -12800,6 +12892,13 @@ public class QuadCLTCPU {
worldXYZ
,
triangles
);
}
if
(
tri_meshes
!=
null
)
{
tri_meshes
.
add
(
new
TriMesh
(
texturePath
,
// String texture_image,
worldXYZ
,
// double [][] worldXYZ,
texCoord
,
// double [][] texCoord,
triangles
));
// int [][] triangles
}
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/TexturedModel.java
View file @
4e6966e0
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/tileprocessor/TileCluster.java
View file @
4e6966e0
...
...
@@ -76,6 +76,60 @@ class TileCluster{
public
Rectangle
getBounds
()
{
return
bounds
;}
public
boolean
[]
getBorder
()
{
return
border
;}
public
double
[]
getDisparity
()
{
return
disparity
;}
public
double
[]
getSubDisparity
(
int
indx
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
return
null
;
}
Rectangle
sub_bounds
=
clust_list
.
get
(
indx
).
bounds
;
double
[]
sub_disparity
=
new
double
[
sub_bounds
.
width
*
sub_bounds
.
height
];
int
src_x
=
sub_bounds
.
x
-
bounds
.
x
;
for
(
int
dst_y
=
0
;
dst_y
<
sub_bounds
.
height
;
dst_y
++)
{
int
src_y
=
dst_y
+
sub_bounds
.
y
-
bounds
.
y
;
System
.
arraycopy
(
disparity
,
src_y
*
bounds
.
width
+
src_x
,
sub_disparity
,
dst_y
*
sub_bounds
.
width
,
sub_bounds
.
width
);
}
return
sub_disparity
;
}
public
boolean
[]
getSubBorder
(
int
indx
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
return
null
;
}
Rectangle
sub_bounds
=
clust_list
.
get
(
indx
).
bounds
;
boolean
[]
sub_border
=
new
boolean
[
sub_bounds
.
width
*
sub_bounds
.
height
];
int
src_x
=
sub_bounds
.
x
-
bounds
.
x
;
for
(
int
dst_y
=
0
;
dst_y
<
sub_bounds
.
height
;
dst_y
++)
{
int
src_y
=
dst_y
+
sub_bounds
.
y
-
bounds
.
y
;
System
.
arraycopy
(
border
,
src_y
*
bounds
.
width
+
src_x
,
sub_border
,
dst_y
*
sub_bounds
.
width
,
sub_bounds
.
width
);
}
return
sub_border
;
}
public
boolean
[]
getSubSelected
(
int
indx
)
{
// disparity should be NaN for unused !
if
(
clust_list
==
null
)
{
return
null
;
}
double
[]
sub_disparity
=
getSubDisparity
(
indx
);
boolean
[]
sub_selection
=
new
boolean
[
sub_disparity
.
length
];
for
(
int
i
=
0
;
i
<
sub_disparity
.
length
;
i
++)
{
sub_selection
[
i
]
=
!
Double
.
isNaN
(
sub_disparity
[
i
]);
}
return
sub_selection
;
}
public
boolean
[]
getSelected
()
{
if
(
disparity
==
null
)
{
return
null
;
...
...
@@ -132,42 +186,6 @@ class TileCluster{
}
/*
public TileCluster combine (TileCluster tileCluster) {
TileCluster outer, inner;
if (bounds.contains(tileCluster.bounds)) {
outer = this;
inner = tileCluster;
} else if (tileCluster.bounds.contains(bounds)) {
outer = tileCluster;
inner = this;
} else {
Rectangle outer_bounds = bounds.union(tileCluster.bounds);
outer = new TileCluster(outer_bounds, null, null);
outer.combine(this); //
inner = tileCluster;
}
int dst_x = inner.bounds.x - outer.bounds.x;
for (int src_y = 0; src_y < bounds.height; src_y++) {
int dst_y = src_y + inner.bounds.y - outer.bounds.y;
System.arraycopy(
inner.border,
src_y * bounds.width,
outer.border,
dst_y * outer.bounds.width + dst_x,
bounds.width);
System.arraycopy(
inner.disparity,
src_y * bounds.width,
outer.disparity,
dst_y * outer.bounds.width + dst_x,
bounds.width);
}
return outer;
}
*/
public
void
add
(
TileCluster
tileCluster
)
{
if
(!
bounds
.
contains
(
tileCluster
.
bounds
))
{
throw
new
IllegalArgumentException
(
"TileCluster.add(): Added cluster should fit into this "
);
...
...
@@ -193,16 +211,6 @@ class TileCluster{
disparity
,
dst_y
*
bounds
.
width
+
dst_x
,
tileCluster
.
bounds
.
width
);
/**
if ((cluster_index != null) && (tileCluster.cluster_index != null)) {
System.arraycopy(
tileCluster.cluster_index,
src_y * tileCluster.bounds.width,
cluster_index,
dst_y * bounds.width + dst_x,
tileCluster.bounds.width);
}
*/
}
return
;
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/TileProcessor.java
View file @
4e6966e0
...
...
@@ -8626,6 +8626,7 @@ ImageDtt.startAndJoin(threads);
{
int
[][]
indices
=
new
int
[
bounds
.
height
][
bounds
.
width
];
int
indx
=
0
;
if
(
selected
.
length
>
(
bounds
.
height
*
bounds
.
width
))
{
// old version - selected is full size
for
(
int
y
=
0
;
y
<
bounds
.
height
;
y
++)
{
for
(
int
x
=
0
;
x
<
bounds
.
width
;
x
++){
if
(
selected
[
this
.
tilesX
*
(
bounds
.
y
+
y
)
+
(
bounds
.
x
+
x
)]){
...
...
@@ -8635,6 +8636,17 @@ ImageDtt.startAndJoin(threads);
}
}
}
}
else
{
// 09.18.2022
for
(
int
y
=
0
;
y
<
bounds
.
height
;
y
++)
{
for
(
int
x
=
0
;
x
<
bounds
.
width
;
x
++){
if
(
selected
[
bounds
.
width
*
y
+
x
]){
indices
[
y
][
x
]
=
indx
++;
}
else
{
indices
[
y
][
x
]
=
-
1
;
}
}
}
}
return
indices
;
}
...
...
@@ -8680,6 +8692,7 @@ ImageDtt.startAndJoin(threads);
int
maxIndex
=
getMaxIndex
(
indices
);
double
[]
indexedDisparity
=
new
double
[
maxIndex
+
1
];
int
indx
=
0
;
if
(
disparity
.
length
>
(
bounds
.
height
*
bounds
.
width
))
{
// old version - selected is full size
for
(
int
y
=
0
;
indx
<=
maxIndex
;
y
++)
{
for
(
int
x
=
0
;
(
x
<
width
)
&&
(
indx
<=
maxIndex
);
x
++){
if
(
indices
[
y
][
x
]
>=
0
){
...
...
@@ -8692,6 +8705,20 @@ ImageDtt.startAndJoin(threads);
}
}
}
}
else
{
// 09.18.2022
for
(
int
y
=
0
;
indx
<=
maxIndex
;
y
++)
{
for
(
int
x
=
0
;
(
x
<
width
)
&&
(
indx
<=
maxIndex
);
x
++){
if
(
indices
[
y
][
x
]
>=
0
){
// center coordinates for 8*8 tile is [3.5,3.5]
double
disp
=
(
disparity
==
null
)?
min_disparity:
(
disparity
[
bounds
.
width
*
y
+
x
]);
if
(
disp
<
min_disparity
)
disp
=
min_disparity
;
else
if
(
disp
>
max_disparity
)
disp
=
max_disparity
;
indexedDisparity
[
indx
]
=
disp
;
indx
++;
}
}
}
}
return
indexedDisparity
;
}
...
...
@@ -8711,6 +8738,7 @@ ImageDtt.startAndJoin(threads);
int
maxIndex
=
getMaxIndex
(
indices
);
double
[][]
coordinate
=
new
double
[
maxIndex
+
1
][];
int
indx
=
0
;
if
(
disparity
.
length
>
(
bounds
.
height
*
bounds
.
width
))
{
// old version - selected is full size
for
(
int
y
=
0
;
indx
<=
maxIndex
;
y
++)
{
for
(
int
x
=
0
;
(
x
<
width
)
&&
(
indx
<=
maxIndex
);
x
++){
if
(
indices
[
y
][
x
]
>=
0
){
...
...
@@ -8729,6 +8757,27 @@ ImageDtt.startAndJoin(threads);
}
}
}
}
else
{
// 09.18.2022
for
(
int
y
=
0
;
indx
<=
maxIndex
;
y
++)
{
for
(
int
x
=
0
;
(
x
<
width
)
&&
(
indx
<=
maxIndex
);
x
++){
if
(
indices
[
y
][
x
]
>=
0
){
// center coordinates for 8*8 tile is [3.5,3.5]
double
px
=
(
bounds
.
x
+
x
+
0.5
)
*
tile_size
-
0.5
;
double
py
=
(
bounds
.
y
+
y
+
0.5
)
*
tile_size
-
0.5
;
double
disp
=
(
disparity
==
null
)?
min_disparity:
(
disparity
[
bounds
.
width
*
y
+
x
]);
if
(
disp
<
min_disparity
)
disp
=
min_disparity
;
else
if
(
disp
>
max_disparity
)
disp
=
max_disparity
;
coordinate
[
indx
]
=
geometryCorrection
.
getWorldCoordinates
(
px
,
py
,
disp
,
correctDistortions
);
indx
++;
}
}
}
}
return
coordinate
;
}
...
...
@@ -8749,9 +8798,10 @@ ImageDtt.startAndJoin(threads);
public
static
int
[][]
filterTriangles
(
int
[][]
triangles
,
double
[]
disparity
,
// disparities per vertex index
double
maxDispDiff
)
// maximal disparity difference in a triangle
{
final
double
min_avg
=
0.5
;
// minimal average disparity to normalize triangle
double
maxDispDiff
,
// maximal relative disparity difference in a triangle
int
debug_level
)
{
final
double
min_avg
=
3.0
;
// 0.5; // minimal average disparity to normalize triangle
class
Triangle
{
int
[]
points
=
new
int
[
3
];
Triangle
(
int
i1
,
int
i2
,
int
i3
){
...
...
@@ -8762,12 +8812,19 @@ ImageDtt.startAndJoin(threads);
}
ArrayList
<
Triangle
>
triList
=
new
ArrayList
<
Triangle
>();
for
(
int
i
=
0
;
i
<
triangles
.
length
;
i
++){
double
disp_avg
=
(
triangles
[
i
][
0
]
+
triangles
[
i
][
1
]+
triangles
[
i
][
2
])/
3.0
;
double
disp_avg
=
(
disparity
[
triangles
[
i
][
0
]]
+
disparity
[
triangles
[
i
][
1
]]+
disparity
[
triangles
[
i
][
2
]])/
3.0
;
// fixed 09.18.2022!
if
(
disp_avg
<
min_avg
)
disp_avg
=
min_avg
;
loop:
{
for
(
int
j
=
0
;
j
<
3
;
j
++){
int
j1
=
(
j
+
1
)
%
3
;
if
(
Math
.
abs
(
disparity
[
triangles
[
i
][
j
]]
-
disparity
[
triangles
[
i
][
j1
]])
>
(
disp_avg
*
maxDispDiff
))
break
loop
;
if
(
Math
.
abs
(
disparity
[
triangles
[
i
][
j
]]
-
disparity
[
triangles
[
i
][
j1
]])
>
(
disp_avg
*
maxDispDiff
))
{
if
(
debug_level
>
1
)
{
System
.
out
.
println
(
"removed triangle "
+
i
+
": "
+
disparity
[
triangles
[
i
][
0
]]+
". "
+
disparity
[
triangles
[
i
][
1
]]+
". "
+
disparity
[
triangles
[
i
][
2
]]+
". Avg = "
+
disp_avg
);
}
break
loop
;
}
}
triList
.
add
(
new
Triangle
(
triangles
[
i
][
0
],
...
...
@@ -8780,7 +8837,100 @@ ImageDtt.startAndJoin(threads);
filteredTriangles
[
i
]
=
triList
.
get
(
i
).
points
;
}
return
filteredTriangles
;
}
}
public
static
int
[][]
filterTrianglesWorld
(
int
[][]
triangles
,
double
[][]
worldXYZ
,
// world per vertex index
double
maxZtoXY
,
double
maxZ
)
{
final
double
maxZtoXY2
=
maxZtoXY
*
maxZtoXY
;
class
Triangle
{
int
[]
points
=
new
int
[
3
];
Triangle
(
int
i1
,
int
i2
,
int
i3
){
points
[
0
]
=
i1
;
points
[
1
]
=
i2
;
points
[
2
]
=
i3
;
}
}
ArrayList
<
Triangle
>
triList
=
new
ArrayList
<
Triangle
>();
for
(
int
i
=
0
;
i
<
triangles
.
length
;
i
++){
double
[][]
min_max
=
new
double
[
3
][
2
];
boolean
not_too_far
=
true
;
for
(
int
di
=
0
;
di
<
3
;
di
++)
{
min_max
[
di
][
0
]
=
worldXYZ
[
triangles
[
i
][
0
]][
di
];
min_max
[
di
][
1
]
=
min_max
[
di
][
0
];
// both min and max to the same vertex 0
}
if
(
maxZ
!=
0
)
{
not_too_far
&=
worldXYZ
[
triangles
[
i
][
0
]][
2
]
>
-
maxZ
;
}
for
(
int
vi
=
1
;
vi
<
3
;
vi
++)
{
for
(
int
di
=
0
;
di
<
3
;
di
++)
{
min_max
[
di
][
0
]
=
Math
.
min
(
min_max
[
di
][
0
],
worldXYZ
[
triangles
[
i
][
vi
]][
di
]);
min_max
[
di
][
1
]
=
Math
.
max
(
min_max
[
di
][
1
],
worldXYZ
[
triangles
[
i
][
vi
]][
di
]);
}
}
double
dx
=
min_max
[
0
][
1
]-
min_max
[
0
][
0
];
double
dy
=
min_max
[
1
][
1
]-
min_max
[
1
][
0
];
double
dz
=
min_max
[
2
][
1
]-
min_max
[
2
][
0
];
double
ratio2
=
dz
*
dz
/(
dx
*
dx
+
dy
*
dy
+
0.001
);
if
(
not_too_far
&&
((
maxZtoXY
==
0
)
||
(
ratio2
<
maxZtoXY2
)))
{
triList
.
add
(
new
Triangle
(
triangles
[
i
][
0
],
triangles
[
i
][
1
],
triangles
[
i
][
2
]));
}
}
int
[][]
filteredTriangles
=
new
int
[
triList
.
size
()][
3
];
for
(
int
i
=
0
;
i
<
filteredTriangles
.
length
;
i
++){
filteredTriangles
[
i
]
=
triList
.
get
(
i
).
points
;
}
return
filteredTriangles
;
}
public
static
int
[]
reIndex
(
int
[][]
indices
,
int
[][]
triangles
)
{
int
last_index
=
-
1
;
for
(
int
i
=
0
;
i
<
indices
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
indices
[
i
].
length
;
j
++)
{
if
(
indices
[
i
][
j
]
>
last_index
)
{
last_index
=
indices
[
i
][
j
];
}
}
}
boolean
[]
used_indices
=
new
boolean
[
last_index
+
1
];
for
(
int
i
=
0
;
i
<
triangles
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
triangles
[
i
].
length
;
j
++)
{
// always 3
used_indices
[
triangles
[
i
][
j
]]
=
true
;
}
}
int
new_len
=
0
;
for
(
int
i
=
0
;
i
<
used_indices
.
length
;
i
++)
if
(
used_indices
[
i
])
{
new_len
++;
}
if
(
new_len
==
used_indices
.
length
)
{
return
null
;
// no re-indexing is needed
}
int
[]
re_index
=
new
int
[
new_len
];
int
indx
=
0
;
for
(
int
i
=
0
;
i
<
indices
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
indices
[
i
].
length
;
j
++)
{
int
old_index
=
indices
[
i
][
j
];
if
(
old_index
>=
0
)
{
if
(
used_indices
[
old_index
])
{
// keep
re_index
[
indx
]
=
old_index
;
indices
[
i
][
j
]
=
indx
++;
}
else
{
indices
[
i
][
j
]
=
-
1
;
}
}
}
}
return
re_index
;
}
public
static
int
[][]
triangulateCluster
(
...
...
@@ -8851,6 +9001,8 @@ ImageDtt.startAndJoin(threads);
{
String
[]
titles
=
{
"disparity"
,
"triangles"
};
double
[][]
dbg_img
=
new
double
[
titles
.
length
][
tilesX
*
tilesY
*
tile_size
*
tile_size
];
Arrays
.
fill
(
dbg_img
[
0
],
Double
.
NaN
);
if
(
selected
.
length
>
(
bounds
.
height
*
bounds
.
width
))
{
// old version - selected is full size
for
(
int
i
=
0
;
i
<
selected
.
length
;
i
++
){
double
d
=
selected
[
i
]?
((
disparity
.
length
>
1
)
?
disparity
[
i
]
:
disparity
[
0
]):
Double
.
NaN
;
int
y
=
i
/
tilesX
;
...
...
@@ -8861,6 +9013,18 @@ ImageDtt.startAndJoin(threads);
}
}
}
}
else
{
// 09.18.2022
for
(
int
i
=
0
;
i
<
selected
.
length
;
i
++
){
double
d
=
selected
[
i
]?
((
disparity
.
length
>
1
)
?
disparity
[
i
]
:
disparity
[
0
]):
Double
.
NaN
;
int
y
=
i
/
bounds
.
width
+
bounds
.
y
;
int
x
=
i
%
bounds
.
width
+
bounds
.
x
;
for
(
int
dy
=
0
;
dy
<
tile_size
;
dy
++){
for
(
int
dx
=
0
;
dx
<
tile_size
;
dx
++){
dbg_img
[
0
][(
y
*
tile_size
+
dy
)*(
tile_size
*
tilesX
)
+
(
x
*
tile_size
+
dx
)]
=
d
;
}
}
}
}
int
maxIndex
=
getMaxIndex
(
indices
);
int
[][]
pxy
=
new
int
[
maxIndex
+
1
][
2
];
int
height
=
indices
.
length
;
...
...
@@ -8885,12 +9049,7 @@ ImageDtt.startAndJoin(threads);
for
(
int
j
=
0
;
j
<
tile_size
;
j
++){
int
x
=
pxy
[
pntIndx
[
0
]][
0
]
+
dx
*
j
;
int
y
=
pxy
[
pntIndx
[
0
]][
1
]
+
dy
*
j
;
// int indx = y * tile_size * tilesX + x;
// if (indx < dbg_img[1].length) {
dbg_img
[
1
][
y
*
tile_size
*
tilesX
+
x
]
=
10.0
;
//1711748
// } else {
// indx += 0;
// }
}
}
}
...
...
src/main/java/com/elphel/imagej/x3d/export/GlTfExport.java
0 → 100644
View file @
4e6966e0
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/x3d/export/TriMesh.java
0 → 100644
View file @
4e6966e0
package
com
.
elphel
.
imagej
.
x3d
.
export
;
/**
**
** TriMesh - triangular mesh representation
**
** Copyright (C) 2022 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** TriMesh.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
TriMesh
{
public
String
texture_image
;
public
double
[][]
worldXYZ
;
public
double
[][]
texCoord
;
public
int
[][]
triangles
;
public
TriMesh
(
String
texture_image
,
double
[][]
worldXYZ
,
double
[][]
texCoord
,
int
[][]
triangles
)
{
this
.
texture_image
=
texture_image
;
this
.
worldXYZ
=
worldXYZ
;
this
.
texCoord
=
texCoord
;
this
.
triangles
=
triangles
;
}
public
String
getImage
()
{
return
texture_image
;}
int
[][]
getTriangles
()
{
return
triangles
;}
double
[][]
getTexCoord
()
{
return
texCoord
;
}
public
double
[][]
getTexCoord
(
boolean
inv_x
,
boolean
inv_y
,
boolean
swap_xy
)
{
if
(!
inv_x
&&
!
inv_y
&&
!
swap_xy
)
{
return
texCoord
;
}
double
[][]
inv_tex_coord
=
new
double
[
texCoord
.
length
][
2
];
double
scale_x
=
inv_x
?
-
1.0
:
1.0
;
double
scale_y
=
inv_y
?
-
1.0
:
1.0
;
if
(
swap_xy
)
{
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_tex_coord
[
i
][
0
]
=
scale_y
*
texCoord
[
i
][
1
];
inv_tex_coord
[
i
][
1
]
=
scale_x
*
texCoord
[
i
][
0
];
}
}
else
{
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_tex_coord
[
i
][
0
]
=
scale_x
*
texCoord
[
i
][
0
];
inv_tex_coord
[
i
][
1
]
=
scale_y
*
texCoord
[
i
][
1
];
}
}
return
inv_tex_coord
;
}
public
double
[][]
getCoordinates
(){
return
worldXYZ
;
}
/**
* 0: XYZ -> XYZ
* 1: XYZ -> YZX
* 2: XYZ -> ZXY
* 3: XYZ -> XZY
* 4: XYZ -> ZYX
* 5: XYZ -> YXZ
* @param inv_x
* @param inv_y
* @param inv_z
* @param swap3
* @return
*/
public
double
[][]
getCoordinates
(
boolean
inv_x
,
boolean
inv_y
,
boolean
inv_z
,
int
swap3
)
{
if
(!
inv_x
&&
!
inv_y
&&
!
inv_y
&&
(
swap3
==
0
))
{
return
worldXYZ
;
}
double
[][]
inv_worldXYZ
=
new
double
[
worldXYZ
.
length
][
3
];
double
scale_x
=
inv_x
?
-
1.0
:
1.0
;
double
scale_y
=
inv_y
?
-
1.0
:
1.0
;
double
scale_z
=
inv_z
?
-
1.0
:
1.0
;
switch
(
swap3
)
{
case
0
:
// XYZ -> XYZ
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_worldXYZ
[
i
][
0
]
=
scale_x
*
worldXYZ
[
i
][
0
];
inv_worldXYZ
[
i
][
1
]
=
scale_y
*
worldXYZ
[
i
][
1
];
inv_worldXYZ
[
i
][
2
]
=
scale_z
*
worldXYZ
[
i
][
2
];
}
break
;
case
1
:
// XYZ -> YZX
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_worldXYZ
[
i
][
1
]
=
scale_x
*
worldXYZ
[
i
][
0
];
inv_worldXYZ
[
i
][
2
]
=
scale_y
*
worldXYZ
[
i
][
1
];
inv_worldXYZ
[
i
][
0
]
=
scale_z
*
worldXYZ
[
i
][
2
];
}
break
;
case
2
:
// XYZ -> ZXY
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_worldXYZ
[
i
][
2
]
=
scale_x
*
worldXYZ
[
i
][
0
];
inv_worldXYZ
[
i
][
0
]
=
scale_y
*
worldXYZ
[
i
][
1
];
inv_worldXYZ
[
i
][
1
]
=
scale_z
*
worldXYZ
[
i
][
2
];
}
break
;
case
3
:
// XYZ -> XZY
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_worldXYZ
[
i
][
0
]
=
scale_x
*
worldXYZ
[
i
][
0
];
inv_worldXYZ
[
i
][
2
]
=
scale_y
*
worldXYZ
[
i
][
1
];
inv_worldXYZ
[
i
][
1
]
=
scale_z
*
worldXYZ
[
i
][
2
];
}
break
;
case
4
:
// XYZ -> ZYX
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_worldXYZ
[
i
][
2
]
=
scale_x
*
worldXYZ
[
i
][
0
];
inv_worldXYZ
[
i
][
1
]
=
scale_y
*
worldXYZ
[
i
][
1
];
inv_worldXYZ
[
i
][
0
]
=
scale_z
*
worldXYZ
[
i
][
2
];
}
break
;
case
5
:
// XYZ -> YXZ
for
(
int
i
=
0
;
i
<
texCoord
.
length
;
i
++)
{
inv_worldXYZ
[
i
][
1
]
=
scale_x
*
worldXYZ
[
i
][
0
];
inv_worldXYZ
[
i
][
0
]
=
scale_y
*
worldXYZ
[
i
][
1
];
inv_worldXYZ
[
i
][
2
]
=
scale_z
*
worldXYZ
[
i
][
2
];
}
break
;
default
:
return
null
;
}
return
inv_worldXYZ
;
}
}
src/main/java/com/elphel/imagej/x3d/export/WavefrontExport.java
View file @
4e6966e0
package
com
.
elphel
.
imagej
.
x3d
.
export
;
/**
**
** WavefrontExport - generate Wavefront OBJ representation of the model
**
** Copyright (C) 2018 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** WavefrontExport.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/>.
** -----------------------------------------------------------------------------**
**
*/
import
java.io.FileWriter
;
import
java.io.IOException
;
...
...
src/main/java/com/elphel/imagej/x3d/export/X3dOutput.java
View file @
4e6966e0
...
...
@@ -76,6 +76,7 @@ public class X3dOutput {
this
.
clt_3d_passes
=
clt_3d_passes
;
}
// init document, bounding box, backdrop
// 09.18.2022 - made work w/o background
public
void
generateBackground
(
boolean
use_backdrop
)
{
try
{
...
...
@@ -105,6 +106,11 @@ public class X3dOutput {
el_Scene
.
appendChild
(
el_TopGroup
);
if
(
clt_3d_passes
==
null
)
{
System
.
out
.
println
(
"Not using background without clt_3d_passes"
);
return
;
}
CLTPass3d
bgnd_pass
=
clt_3d_passes
.
get
(
0
);
Element
el_Bgnd
=
x3dDoc
.
createElement
(
"Background"
);
...
...
@@ -167,6 +173,10 @@ public class X3dOutput {
sb_tex_coords
.
append
(
String
.
format
(
"%.4f %.4f"
,
texCoord
[
i
][
0
],
texCoord
[
i
][
1
]));
}
String
sindex
=
sb_coord_index
.
toString
();
// for both coordIndex and texCoordIndex
if
(
sindex
.
length
()
==
0
)
{
System
.
out
.
println
(
"addCluster(): sindex.length() == 0"
);
System
.
out
.
println
(
"addCluster(): sindex.length() == 0"
);
}
String
scoord
=
sb_coords
.
toString
();
String
stcoord
=
sb_tex_coords
.
toString
();
...
...
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