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"
45 using namespace DGtal;
104 class CustomViewer3D:
public Viewer3D<>
111 Viewer3D<>::setKeyDescription ( Qt::Key_I,
"Display mesh informations about #faces, #vertices" );
112 Viewer3D<>::setGLDoubleRenderingMode(
false);
114 QObject::connect(
this, SIGNAL(drawFinished(
bool)),
this, SLOT(saveSnapshot(
bool)));
117 virtual void keyPressEvent(QKeyEvent *e){
118 bool handled =
false;
119 if( e->key() == Qt::Key_I)
122 myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
124 qglviewer::Vec camPos = camera()->position();
125 DGtal::Z3i::RealPoint c (camPos[0], camPos[1], camPos[2]);
126 ss << myInfoDisplay <<
" distance to camera: " << (c-centerMesh).norm();
127 Viewer3D<>::displayMessage(QString(myIsDisplayingInfoMode ?
128 ss.str().c_str() :
" "), 1000000);
130 Viewer3D<>::update();
135 Viewer3D<>::keyPressEvent(e);
140 std::string myInfoDisplay =
"No information loaded...";
141 bool myIsDisplayingInfoMode =
false;
142 bool mySaveSnap =
false;
143 DGtal::Z3i::RealPoint centerMesh;
147 int main(
int argc,
char** argv )
153 unsigned int meshColorR {240};
154 unsigned int meshColorG {240};
155 unsigned int meshColorB {240};
156 unsigned int meshColorA {255};
158 unsigned int meshColorRLine {0};
159 unsigned int meshColorGLine {0};
160 unsigned int meshColorBLine {0};
161 unsigned int meshColorALine {255};
163 unsigned int sdpColorR {240};
164 unsigned int sdpColorG {240};
165 unsigned int sdpColorB {240};
166 unsigned int sdpColorA {255};
168 float lineWidth {1.5};
170 std::vector<unsigned int > customColorMesh;
171 std::vector<unsigned int > customColorSDP;
172 std::vector<unsigned int > customLineColor;
173 std::vector<unsigned int > vectFieldIndices = {0,1,2,3,4,5};
174 std::string displayVectorField;
176 std::string snapshotFile;
177 std::string filenameSDP;
178 double ballRadius {0.5};
179 bool invertNormal {
false};
180 bool drawVertex {
false};
181 float ambiantLight {0.0};
186 std::vector<std::string> inputFileNames;
187 std::string outputFileName {
"result.raw"};
188 app.description(
"Display OFF mesh file by using QGLviewer");
189 app.add_option(
"-i,--input,1", inputFileNames,
"inputFileNames.off files (.off), or OFS file (.ofs)" )
190 ->check(CLI::ExistingFile)
192 app.add_option(
"-x,--scaleX", sx,
"set the scale value in the X direction (default 1.0)");
193 app.add_option(
"-y,--scaleY", sy,
"set the scale value in the y direction (default 1.0)");
194 app.add_option(
"-z,--scaleZ", sz,
"set the scale value in the z direction (default 1.0)");
195 app.add_option(
"--minLineWidth", lineWidth,
"set the min line width of the mesh faces (default 1.5)",
true);
196 app.add_option(
"--customColorMesh", customColorMesh,
"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).");
198 app.add_option(
"--customColorSDP", customColorSDP,
"set the R, G, B, A components of the colors of the sdp view")
200 app.add_option(
"--displayVectorField,-f", displayVectorField,
"display a vector field from a simple sdp file (two points per line)");
201 app.add_option(
"--vectorFieldIndex", vectFieldIndices,
"specify special indices for the two point coordinates (instead usinf the default indices: 0 1, 2, 3, 4, 5)" )
203 app.add_option(
"--customLineColor", customLineColor,
"set the R, G, B components of the colors of the lines displayed from the --displayVectorField option (red by default).")
205 app.add_option(
"--SDPradius", ballRadius,
"change the ball radius to display a set of discrete points (used with displaySDP option)",
true);
206 app.add_option(
"--displaySDP,-s", filenameSDP,
"add the display of a set of discrete points as ball of radius 0.5.");
207 app.add_option(
"--addAmbientLight,-A", ambiantLight,
"add an ambient light for better display (between 0 and 1)." );
208 app.add_option(
"--doSnapShotAndExit,-d", snapshotFile,
"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.");
209 app.add_flag(
"--invertNormal,-n", invertNormal,
"invert face normal vectors.");
210 app.add_flag(
"--drawVertex,-v", drawVertex,
"draw the vertex of the mesh");
213 app.get_formatter()->column_width(40);
214 CLI11_PARSE(app, argc, argv);
219 DGtal::Color vFieldLineColor = DGtal::Color::Red;
220 if( customLineColor.size() == 4)
222 vFieldLineColor.setRGBi(customLineColor[0], customLineColor[1], customLineColor[2], 255);
225 if( customColorMesh.size() != 0 )
227 if(customColorMesh.size()!=4 && customColorMesh.size()!=8 )
229 trace.error() <<
"colors specification should contain R,G,B and Alpha values"<< std::endl;
231 if( customColorMesh.size() >= 4)
233 meshColorR = customColorMesh[0];
234 meshColorG = customColorMesh[1];
235 meshColorB = customColorMesh[2];
236 meshColorA = customColorMesh[3];
238 if(customColorMesh.size() == 8)
240 meshColorRLine = customColorMesh[4];
241 meshColorGLine = customColorMesh[5];
242 meshColorBLine = customColorMesh[6];
243 meshColorALine = customColorMesh[7];
247 if(customColorSDP.size() == 4)
249 sdpColorR = customColorSDP[0];
250 sdpColorG = customColorSDP[1];
251 sdpColorB = customColorSDP[2];
252 sdpColorA = customColorSDP[3];
255 QApplication application(argc,argv);
256 CustomViewer3D viewer;
257 viewer.mySaveSnap = snapshotFile !=
"";
258 if(snapshotFile !=
"")
260 viewer.setSnapshotFileName(QString(snapshotFile.c_str()));
263 std::stringstream title;
264 title <<
"Simple Mesh Viewer: " << inputFileNames[0];
265 viewer.setWindowTitle(title.str().c_str());
267 viewer.myGLLineMinWidth = lineWidth;
268 viewer.setGLScale(sx, sy, sz);
270 if(ambiantLight != 0.0)
272 GLfloat lightAmbientCoeffs [4] = {ambiantLight,ambiantLight, ambiantLight, 1.0f};
273 viewer.setGLLightAmbientCoefficients(lightAmbientCoeffs);
276 trace.info() <<
"Importing mesh... ";
278 std::vector<Mesh<DGtal::Z3i::RealPoint> > vectMesh;
279 for(
unsigned int i = 0; i< inputFileNames.size(); i++)
281 Mesh<DGtal::Z3i::RealPoint> aMesh(customColorMesh.size() != 4 && customColorMesh.size() != 8);
282 aMesh << inputFileNames[i];
283 vectMesh.push_back(aMesh);
285 DGtal::Z3i::RealPoint centerMeshes;
287 for(
const auto & m: vectMesh)
289 for(
auto p = m.vertexBegin(); p!=m.vertexEnd(); ++p)
294 viewer.centerMesh = centerMeshes;
295 bool import = vectMesh.size()==inputFileNames.size();
298 trace.info() <<
"File import failed. " << std::endl;
302 trace.info() <<
"[done]. "<< std::endl;
303 if(filenameSDP !=
"")
305 vector<Z3i::RealPoint> vectPoints;
306 vectPoints = PointListReader<Z3i::RealPoint>::getPointsFromFile(filenameSDP);
307 viewer << CustomColors3D(Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA),
308 Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
309 for(
unsigned int i=0;i< vectPoints.size(); i++){
310 viewer.addBall(vectPoints.at(i), ballRadius);
315 for(
unsigned int i=0; i<vectMesh.size(); i++){
316 vectMesh[i].invertVertexFaceOrder();
320 viewer << CustomColors3D(Color(meshColorRLine, meshColorGLine, meshColorBLine, meshColorALine),
321 Color(meshColorR, meshColorG, meshColorB, meshColorA));
322 for(
unsigned int i=0; i<vectMesh.size(); i++){
323 viewer << vectMesh[i];
327 for(
unsigned int i=0; i<vectMesh.size(); i++){
328 for( Mesh<DGtal::Z3i::RealPoint>::VertexStorage::const_iterator it = vectMesh[i].vertexBegin();
329 it!=vectMesh[i].vertexEnd(); ++it){
330 DGtal::Z3i::Point pt;
331 pt[0]=(*it)[0]; pt[1]=(*it)[1]; pt[2]=(*it)[2];
337 if (displayVectorField !=
"")
339 std::vector<unsigned int > vectFieldIndices1 = {vectFieldIndices[0],vectFieldIndices[1], vectFieldIndices[2]};
340 std::vector<unsigned int > vectFieldIndices2 = {vectFieldIndices[3],vectFieldIndices[4], vectFieldIndices[5]};
341 std::vector<DGtal::Z3i::RealPoint> vectPt1 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(displayVectorField, vectFieldIndices1);
342 std::vector<DGtal::Z3i::RealPoint> vectPt2 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(displayVectorField, vectFieldIndices2);
343 viewer.createNewLineList();
344 for (
unsigned int i = 0; i < vectPt1.size(); i++)
346 viewer.setLineColor(vFieldLineColor);
347 viewer.addLine(vectPt1[i], vectPt2[i]);
350 unsigned int nbVertex = 0;
351 unsigned int nbFaces = 0;
352 for(
auto const &m: vectMesh)
354 nbVertex += m.nbVertex();
355 nbFaces +=m.nbFaces();
358 ss <<
"# faces: " << std::fixed << nbFaces <<
" #vertex: " << nbVertex ;
359 viewer.myInfoDisplay = ss.str();
360 viewer << CustomViewer3D::updateDisplay;
361 if(snapshotFile !=
"" )
364 if(!viewer.restoreStateFromFile())
368 std::string extension = snapshotFile.substr(snapshotFile.find_last_of(
".") + 1);
369 std::string basename = snapshotFile.substr(0, snapshotFile.find_last_of(
"."));
370 for(
int i=0; i< viewer.snapshotCounter()-1; i++){
372 s << basename <<
"-"<< setfill(
'0') << setw(4)<< i <<
"." << extension;
373 trace.info() <<
"erase temp file: " << s.str() << std::endl;
374 remove(s.str().c_str());
378 s << basename <<
"-"<< setfill(
'0') << setw(4)<< viewer.snapshotCounter()-1 <<
"." << extension;
379 rename(s.str().c_str(), snapshotFile.c_str());
383 return application.exec();