32 #include "DGtal/base/Common.h"
34 #include "DGtal/io/Display3D.h"
35 #include "DGtal/io/viewers/Viewer3D.h"
36 #include "DGtal/io/readers/MeshReader.h"
37 #include "DGtal/helpers/StdDefs.h"
38 #include "DGtal/io/readers/PointListReader.h"
40 #include <boost/program_options/options_description.hpp>
41 #include <boost/program_options/parsers.hpp>
42 #include <boost/program_options/variables_map.hpp>
46 using namespace DGtal;
122 class CustomViewer3D:
public Viewer3D<>
132 QObject::connect(
this, SIGNAL(drawFinished(
bool)),
this, SLOT(saveSnapshot(
bool)));
135 virtual void keyPressEvent(QKeyEvent *e){
136 bool handled =
false;
137 if( e->key() == Qt::Key_I)
140 myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
142 qglviewer::Vec camPos = camera()->position();
144 ss << myInfoDisplay <<
" distance to camera: " << (c-centerMesh).norm();
146 ss.str().c_str() :
" "), 1000000);
158 std::string myInfoDisplay =
"No information loaded...";
159 bool myIsDisplayingInfoMode =
false;
160 bool mySaveSnap =
false;
168 namespace po = boost::program_options;
170 int main(
int argc,
char** argv )
174 po::options_description general_opt(
"Allowed options are: ");
175 general_opt.add_options()
176 (
"help,h",
"display this message")
177 (
"input,i", po::value<std::vector<string> >()->multitoken(),
"off files (.off), or OFS file (.ofs) " )
178 (
"scaleX,x", po::value<float>()->default_value(1.0),
"set the scale value in the X direction (default 1.0)" )
179 (
"scaleY,y", po::value<float>()->default_value(1.0),
"set the scale value in the Y direction (default 1.0)" )
180 (
"scaleZ,z", po:: value<float>()->default_value(1.0),
"set the scale value in the Z direction (default 1.0)")
181 (
"minLineWidth,w", po:: value<float>()->default_value(1.5),
"set the min line width of the mesh faces (default 1.5)")
182 (
"customColorMesh",po::value<std::vector<unsigned int> >()->multitoken(),
"set the R, G, B, A components of the colors of the mesh faces and eventually the color R, G, B, A of the mesh edge lines (set by default to black). " )
183 (
"customColorSDP",po::value<std::vector<unsigned int> >()->multitoken(),
"set the R, G, B, A components of the colors of the sdp view" )
184 (
"displayVectorField,f",po::value<std::string>(),
"display a vector field from a simple sdp file (two points per line)" )
185 (
"vectorFieldIndex",po::value<std::vector<unsigned int> >()->multitoken(),
"specify special indices for the two point coordinates (instead usinf the default indices: 0 1, 2, 3, 4, 5)" )
186 (
"customLineColor",po::value<std::vector<unsigned int> >()->multitoken(),
"set the R, G, B components of the colors of the lines displayed from the --displayVectorField option (red by default). " )
187 (
"displaySDP,s", po::value<std::string>(),
"add the display of a set of discrete points as ball of radius 0.5.")
188 (
"SDPradius", po::value<double>()->default_value(0.5),
"change the ball radius to display a set of discrete points (used with displaySDP option)")
189 (
"invertNormal,n",
"invert face normal vectors." )
190 (
"addAmbientLight,A",po:: value<float>()->default_value(0.0),
"add an ambient light for better display (between 0 and 1)." )
191 (
"drawVertex,v",
"draw the vertex of the mesh" )
192 (
"doSnapShotAndExit,d", po::value<std::string>(),
"save display snapshot into file. Notes that the camera setting is set by default according the last saved configuration (use SHIFT+Key_M to save current camera setting in the Viewer3D). If the camera setting was not saved it will use the default camera setting." );
195 po::variables_map vm;
197 po::store(po::parse_command_line(argc, argv, general_opt), vm);
198 }
catch(
const std::exception& ex){
200 trace.
info()<<
"Error checking program options: "<< ex.what()<< endl;
203 if( !parseOK || vm.count(
"help")||argc<=1)
205 std::cout <<
"Usage: " << argv[0] <<
" [input]\n"
206 <<
"Display OFF mesh file by using QGLviewer"
207 << general_opt <<
"\n";
211 if(! vm.count(
"input"))
213 trace.
error() <<
" The file name was defined" << endl;
219 std::vector<std::string> inputFilenameVect = vm[
"input"].as<std::vector<std::string > >();
220 float sx = vm[
"scaleX"].as<
float>();
221 float sy = vm[
"scaleY"].as<
float>();
222 float sz = vm[
"scaleZ"].as<
float>();
224 unsigned int meshColorR = 240;
225 unsigned int meshColorG = 240;
226 unsigned int meshColorB = 240;
227 unsigned int meshColorA = 255;
229 unsigned int meshColorRLine = 0;
230 unsigned int meshColorGLine = 0;
231 unsigned int meshColorBLine = 0;
232 unsigned int meshColorALine = 255;
235 unsigned int sdpColorR = 240;
236 unsigned int sdpColorG = 240;
237 unsigned int sdpColorB = 240;
238 unsigned int sdpColorA = 255;
241 bool displayVectorField = vm.count(
"displayVectorField");
242 std::vector<unsigned int> vectFieldIndices = {0,1,2,3,4,5};
244 if (displayVectorField) {
245 if(vm.count(
"vectorFieldIndex")){
246 vectFieldIndices = vm[
"vectorFieldIndex"].as<std::vector<unsigned int> >();
247 if (vectFieldIndices.size() != 6) {
248 trace.
warning() <<
"you should specify indices for each of the 6 fields of the two coordinates." << std::endl;
249 vectFieldIndices = {0,1,2,3,4,5};
254 float lineWidth = vm[
"minLineWidth"].as<
float>();
257 if(vm.count(
"customLineColor")){
258 std::vector<unsigned int > vectCol = vm[
"customLineColor"].as<std::vector<unsigned int> >();
259 if(vectCol.size()!=3 ){
260 trace.
error() <<
"colors specification should contain R,G,B values (using default red)."<< std::endl;
262 vFieldLineColor.setRGBi(vectCol[0], vectCol[1], vectCol[2], 255);
265 if(vm.count(
"customColorMesh")){
266 std::vector<unsigned int > vectCol = vm[
"customColorMesh"].as<std::vector<unsigned int> >();
267 if(vectCol.size()!=4 && vectCol.size()!=8 ){
268 trace.
error() <<
"colors specification should contain R,G,B and Alpha values"<< std::endl;
270 meshColorR = vectCol[0];
271 meshColorG = vectCol[1];
272 meshColorB = vectCol[2];
273 meshColorA = vectCol[3];
274 if(vectCol.size() == 8){
275 meshColorRLine = vectCol[4];
276 meshColorGLine = vectCol[5];
277 meshColorBLine = vectCol[6];
278 meshColorALine = vectCol[7];
283 if(vm.count(
"customColorSDP")){
284 std::vector<unsigned int > vectCol = vm[
"customColorSDP"].as<std::vector<unsigned int> >();
285 if(vectCol.size()!=4){
286 trace.
error() <<
"colors specification should contain R,G,B and Alpha values"<< std::endl;
288 sdpColorR = vectCol[0];
289 sdpColorG = vectCol[1];
290 sdpColorB = vectCol[2];
291 sdpColorA = vectCol[3];
296 QApplication application(argc,argv);
297 CustomViewer3D viewer;
298 viewer.mySaveSnap = vm.count(
"doSnapShotAndExit");
299 if(vm.count(
"doSnapShotAndExit")){
300 viewer.setSnapshotFileName(QString(vm[
"doSnapShotAndExit"].as<std::string>().c_str()));
303 std::stringstream title;
304 title <<
"Simple Mesh Viewer: " << inputFilenameVect[0];
305 viewer.setWindowTitle(title.str().c_str());
307 viewer.myGLLineMinWidth = lineWidth;
308 viewer.setGLScale(sx, sy, sz);
309 bool invertNormal= vm.count(
"invertNormal");
310 double ballRadius = vm[
"SDPradius"].as<
double>();
311 if(vm.count(
"addAmbientLight"))
313 float val = vm[
"addAmbientLight"].as<
float>();
314 GLfloat lightAmbientCoeffs [4] = {val,val, val, 1.0f};
315 viewer.setGLLightAmbientCoefficients(lightAmbientCoeffs);
320 std::vector<Mesh<DGtal::Z3i::RealPoint> > vectMesh;
321 for(
unsigned int i = 0; i< inputFilenameVect.size(); i++){
323 aMesh << inputFilenameVect[i];
324 vectMesh.push_back(aMesh);
328 for(
const auto & m: vectMesh)
330 for(
auto p = m.vertexBegin(); p!=m.vertexEnd(); ++p)
335 viewer.centerMesh = centerMeshes;
336 bool import = vectMesh.
size()==inputFilenameVect.size();
338 trace.
info() <<
"File import failed. " << std::endl;
343 if(vm.count(
"displaySDP")){
344 std::string filenameSDP = vm[
"displaySDP"].as<std::string>();
345 vector<Z3i::RealPoint> vectPoints;
348 Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
349 for(
unsigned int i=0;i< vectPoints.size(); i++){
350 viewer.addBall(vectPoints.at(i), ballRadius);
354 for(
unsigned int i=0; i<vectMesh.size(); i++){
355 vectMesh[i].invertVertexFaceOrder();
359 viewer <<
CustomColors3D(
Color(meshColorRLine, meshColorGLine, meshColorBLine, meshColorALine),
360 Color(meshColorR, meshColorG, meshColorB, meshColorA));
361 for(
unsigned int i=0; i<vectMesh.size(); i++){
362 viewer << vectMesh[i];
365 if(vm.count(
"drawVertex")){
366 for(
unsigned int i=0; i<vectMesh.size(); i++){
370 pt[0]=(*it)[0]; pt[1]=(*it)[1]; pt[2]=(*it)[2];
377 if (displayVectorField) {
378 std::vector<unsigned int > vectFieldIndices1 = {vectFieldIndices[0],vectFieldIndices[1], vectFieldIndices[2]};
379 std::vector<unsigned int > vectFieldIndices2 = {vectFieldIndices[3],vectFieldIndices[4], vectFieldIndices[5]};
383 viewer.createNewLineList();
384 for (
unsigned int i = 0; i < vectPt1.size(); i++) {
386 viewer.setLineColor(vFieldLineColor);
387 viewer.addLine(vectPt1[i], vectPt2[i]);
390 unsigned int nbVertex = 0;
391 unsigned int nbFaces = 0;
392 for(
auto const &m: vectMesh)
394 nbVertex += m.nbVertex();
395 nbFaces +=m.nbFaces();
398 ss <<
"# faces: " << std::fixed << nbFaces <<
" #vertex: " << nbVertex ;
399 viewer.myInfoDisplay = ss.str();
401 if(vm.count(
"doSnapShotAndExit")){
403 if(!viewer.restoreStateFromFile())
407 std::string name = vm[
"doSnapShotAndExit"].as<std::string>();
408 std::string extension = name.substr(name.find_last_of(
".") + 1);
409 std::string basename = name.substr(0, name.find_last_of(
"."));
410 for(
int i=0; i< viewer.snapshotCounter()-1; i++){
412 s << basename <<
"-"<< setfill(
'0') << setw(4)<< i <<
"." << extension;
413 trace.
info() <<
"erase temp file: " << s.str() << std::endl;
414 remove(s.str().c_str());
418 s << basename <<
"-"<< setfill(
'0') << setw(4)<< viewer.snapshotCounter()-1 <<
"." << extension;
419 rename(s.str().c_str(), name.c_str());
423 return application.exec();
ConstIterator vertexEnd() const
Trace trace(traceWriterTerm)