Commit 15b80649 authored by Andrey Filippov's avatar Andrey Filippov

added wavefront export

parent 0a050e16
......@@ -2131,6 +2131,8 @@ public class EyesisCorrectionParameters {
public int max_clusters = 500; // Maximal number of clusters to generate for one run
public boolean remove_scans = true; // Remove all unneeded scans when generating x3d output to save memory
public boolean output_x3d = true; // Generate x3d output
public boolean output_obj = true; // Generate Wavefront obj output
public boolean correct_distortions = false; // Correct lens geometric distortions in a model (will need backdrop to be corrected too)
......@@ -2749,6 +2751,8 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"max_clusters", this.max_clusters+"");
properties.setProperty(prefix+"remove_scans", this.remove_scans+"");
properties.setProperty(prefix+"output_x3d", this.output_x3d+"");
properties.setProperty(prefix+"output_obj", this.output_obj+"");
properties.setProperty(prefix+"correct_distortions",this.correct_distortions+"");
properties.setProperty(prefix+"show_triangles", this.show_triangles+"");
properties.setProperty(prefix+"avg_cluster_disp", this.avg_cluster_disp+"");
......@@ -3324,6 +3328,8 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"max_clusters")!=null) this.max_clusters=Integer.parseInt(properties.getProperty(prefix+"max_clusters"));
if (properties.getProperty(prefix+"remove_scans")!=null) this.remove_scans=Boolean.parseBoolean(properties.getProperty(prefix+"remove_scans"));
if (properties.getProperty(prefix+"output_x3d")!=null) this.output_x3d=Boolean.parseBoolean(properties.getProperty(prefix+"output_x3d"));
if (properties.getProperty(prefix+"output_obj")!=null) this.output_obj=Boolean.parseBoolean(properties.getProperty(prefix+"output_obj"));
if (properties.getProperty(prefix+"correct_distortions")!=null) this.correct_distortions=Boolean.parseBoolean(properties.getProperty(prefix+"correct_distortions"));
if (properties.getProperty(prefix+"show_triangles")!=null) this.show_triangles=Boolean.parseBoolean(properties.getProperty(prefix+"show_triangles"));
if (properties.getProperty(prefix+"avg_cluster_disp")!=null) this.avg_cluster_disp=Boolean.parseBoolean(properties.getProperty(prefix+"avg_cluster_disp"));
......@@ -3927,6 +3933,8 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Maximal number of clusters to generate for one run", this.max_clusters, 0);
gd.addCheckbox ("Remove all unneeded scans when generating x3d output to save memory", this.remove_scans);
gd.addCheckbox ("Generate x3d output", this.output_x3d);
gd.addCheckbox ("Generate Wavefront obj output", this.output_obj);
gd.addCheckbox ("Correct lens geometric distortions in a model (will need backdrop to be corrected too)", this.correct_distortions);
gd.addCheckbox ("Show generated triangles", this.show_triangles);
gd.addCheckbox ("Weight-average disparity for the whole cluster ", this.avg_cluster_disp);
......@@ -4534,6 +4542,8 @@ public class EyesisCorrectionParameters {
this.max_clusters= (int) gd.getNextNumber();
this.remove_scans= gd.getNextBoolean();
this.output_x3d= gd.getNextBoolean();
this.output_obj= gd.getNextBoolean();
this.correct_distortions= gd.getNextBoolean();
this.show_triangles= gd.getNextBoolean();
this.avg_cluster_disp= gd.getNextBoolean();
......
......@@ -24,6 +24,7 @@
//import java.awt.Polygon;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -6171,7 +6172,8 @@ public class QuadCLT {
if (this.image_data == null){
return false;
}
X3dOutput x3dOutput = null;
WavefrontExport wfOutput = 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");
......@@ -6199,18 +6201,37 @@ public class QuadCLT {
tp.showScan(
tp.clt_3d_passes.get(next_pass-1), // CLTPass3d scan,
"after_pass3-"+(next_pass-1)); //String title)
String x3d_path= correctionsParameters.selectX3dDirectory( // for x3d and obj
true, // smart,
true); //newAllowed, // save
// create x3d file
X3dOutput x3dOutput = new X3dOutput(
if (clt_parameters.output_x3d) {
x3dOutput = new X3dOutput(
clt_parameters,
correctionsParameters,
geometryCorrection,
tp.clt_3d_passes);
}
if (clt_parameters.output_obj && (x3d_path != null)) {
try {
wfOutput = new WavefrontExport(
x3d_path,
this.image_name,
clt_parameters,
correctionsParameters,
geometryCorrection,
tp.clt_3d_passes);
} catch (IOException e) {
System.out.println("Failed to open Wavefront files for writing");
// TODO Auto-generated catch block
e.printStackTrace();
// do nothing, just keep
}
}
if (x3dOutput != null) {
x3dOutput.generateBackground(clt_parameters.infinityDistance <= 0.0); // needs just first (background) scan
String x3d_path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
}
if (clt_parameters.infinityDistance > 0.0){ // generate background as a billboard
// tp.showScan(
......@@ -6272,8 +6293,10 @@ public class QuadCLT {
// "infinityDistance");
boolean showTri = false; // ((scanIndex < next_pass + 1) && clt_parameters.show_triangles) ||((scanIndex - next_pass) == 73);
try {
generateClusterX3d(
x3dOutput,
wfOutput, // output WSavefront if not null
texturePath,
"INFINITY", // id (scanIndex - next_pass), // id
"INFINITY", // class
......@@ -6286,6 +6309,11 @@ public class QuadCLT {
infinity_disparity, // 0.3
clt_parameters.grow_disp_max, // other_range, // 2.0 'other_range - difference from the specified (*_CM)
clt_parameters.maxDispTriangle);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
// maybe not needed
scan.setBorderTiles(bg_border_backup);
scan.setSelected(bg_sel_backup);
......@@ -6376,8 +6404,10 @@ public class QuadCLT {
boolean showTri = ((scanIndex < next_pass + 1) && clt_parameters.show_triangles) ||((scanIndex - next_pass) == 73);
// boolean showTri = ((scanIndex < next_pass + 1) && clt_parameters.show_triangles) ||(scanIndex == 49) || (scanIndex == 54);
try {
generateClusterX3d(
x3dOutput,
wfOutput, // output WSavefront if not null
texturePath,
"shape_id-"+(scanIndex - next_pass), // id
null, // class
......@@ -6390,17 +6420,23 @@ public class QuadCLT {
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);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
// now generate and save texture files (start with full, later use bounding rectangle?)
if (x3d_path != null){
x3d_path+=Prefs.getFileSeparator()+this.image_name+".x3d";
x3dOutput.generateX3D(x3d_path);
if ((x3d_path != null) && (x3dOutput != null)){
// x3d_path+=Prefs.getFileSeparator()+this.image_name+".x3d";
// x3dOutput.generateX3D(x3d_path);
x3dOutput.generateX3D(x3d_path+Prefs.getFileSeparator()+this.image_name+".x3d");
}
if (wfOutput != null){
wfOutput.close();
}
return true;
// return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name");
......@@ -6410,7 +6446,8 @@ public class QuadCLT {
public void generateClusterX3d(
X3dOutput x3dOutput,
X3dOutput x3dOutput, // output x3d if not null
WavefrontExport wfOutput, // output WSavefront if not null
String texturePath,
String id,
String class_name,
......@@ -6423,7 +6460,7 @@ public class QuadCLT {
double min_disparity,
double max_disparity,
double maxDispTriangle
)
) throws IOException
{
int [][] indices = tp.getCoordIndices( // starting with 0, -1 - not selected
bounds,
......@@ -6472,7 +6509,7 @@ public class QuadCLT {
indices,
triangles);
}
if (x3dOutput != null) {
x3dOutput.addCluster(
texturePath,
id,
......@@ -6481,6 +6518,16 @@ public class QuadCLT {
worldXYZ,
triangles);
}
if (wfOutput != null) {
wfOutput.addCluster(
texturePath,
id,
// class_name,
texCoord,
worldXYZ,
triangles);
}
}
public ImagePlus getBackgroundImage(
......
import java.io.FileWriter;
import java.io.IOException;
/**
**
** generate Wavefront representation of the model
**
** Copyright (C) 2017 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.util.ArrayList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ij.Prefs;
public class WavefrontExport {
static final String MTL_EXT=".mtl";
static final String OBJ_EXT=".obj";
GeometryCorrection geometry_correction;
public ArrayList <CLTPass3d> clt_3d_passes;
public EyesisCorrectionParameters.CLTParameters clt_parameters;
public EyesisCorrectionParameters.CorrectionParameters correctionsParameters;
public int debugLevel = 1;
FileWriter obj_writer; // f0 = new FileWriter("output.txt");
FileWriter mtl_writer; // f0 = new FileWriter("output.txt");
Document x3dDoc;
Element el_X3d;
Element el_Scene;
Element el_TopGroup;
public int max_line_length = 0; // 100; // 0 - no limit
public int v_index = 1; // first index is 1, not 0
public int vt_index = 1; // first index is 1, not 0
public int f_index = 1; // first index is 1, not 0
public WavefrontExport(
String out_dir,
String project_name,
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.CorrectionParameters correctionsParameters,
GeometryCorrection geometry_correction,
ArrayList <CLTPass3d> clt_3d_passes) throws IOException{
this.clt_parameters = clt_parameters;
this.correctionsParameters = correctionsParameters;
this.geometry_correction = geometry_correction;
this.clt_3d_passes = clt_3d_passes;
mtl_writer = new FileWriter(out_dir+Prefs.getFileSeparator()+project_name+MTL_EXT);
obj_writer = new FileWriter(out_dir+Prefs.getFileSeparator()+project_name+OBJ_EXT); // .close();
mtl_writer.write("#\n# Wavefront material file\n#\n");
obj_writer.write("#\n# Wavefront object file\n#\n");
obj_writer.write("mtllib ./"+project_name+MTL_EXT+"\n\n"); // add "./" to indicate relative path? // ./1488240527_408296.obj.mtl\n");
}
public void close()
{
try {
mtl_writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
obj_writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void addCluster(
String texture_path,
String material_id,
double [][] texCoord,
double [][] coordinate,
int [][] triangles) throws IOException
{
// Write to material file
/*
newmtl material_0
Ka 0.200000 0.200000 0.200000
Kd 1.000000 1.000000 1.000000
Ks 1.000000 1.000000 1.000000
Tr 1.000000
illum 2
Ns 0.000000
map_Kd 1488240527_408296-img2-texture.png
*/
mtl_writer.write("\nnewmtl "+material_id+"\n");
mtl_writer.write("Ka 0.200000 0.200000 0.200000\n");
mtl_writer.write("Kd 1.000000 1.000000 1.000000\n");
mtl_writer.write("Ks 1.000000 1.000000 1.000000\n");
mtl_writer.write("Tr 1.000000\n");
mtl_writer.write("illum 2\n");
// mtl_writer.write("illum 0\n"); // should it be 0 orf 2?
mtl_writer.write("Ns 0.000000\n");
mtl_writer.write("map_Kd "+texture_path+"\n");
// Write OBJ file
// start using new material
obj_writer.write("usemtl "+material_id+"\n");
// output all vertices
obj_writer.write("# start from vertex : "+ v_index+ "\n");
obj_writer.write("# start from texture vertex: "+ vt_index+"\n");
obj_writer.write("# start from face (triangle): "+ f_index+ "\n");
for (int i = 0; i < coordinate.length; i++){
obj_writer.write(String.format("v %.3f %.3f %.3f\n", coordinate[i][0], coordinate[i][1], coordinate[i][2]));
}
// output all texture vertices
for (int i = 0; i < texCoord.length; i++){
obj_writer.write(String.format("vt %.5f %.5f\n", texCoord[i][0], texCoord[i][1]));
}
// output all triangles (faces)
for (int i = 0; i < triangles.length; i++){
obj_writer.write(String.format("f %d/%d %d/%d %d/%d\n",
triangles[i][0]+v_index,triangles[i][0]+vt_index, // actually v_index and vt_index should =be the same
triangles[i][1]+v_index,triangles[i][1]+vt_index,
triangles[i][2]+v_index,triangles[i][2]+vt_index));
}
obj_writer.write("# end of material "+ material_id+"\n");
obj_writer.write("# vertices: "+ coordinate.length+"\n");
obj_writer.write("# texture vertices: "+ texCoord.length+"\n");
obj_writer.write("# faces (triangles): "+ triangles.length+"\n");
obj_writer.write("\n");
// increment indices
v_index += coordinate.length;
vt_index += texCoord.length;
f_index += triangles.length;
//f 27151/27139/27151 27141/27140/27141 27140/27141/27140 *
}
}
/**
**
** X3dOutput - generate x3d representation of the model
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment