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;
117 class CustomViewer3D:
public Viewer3D<>
124 Viewer3D<>::setKeyDescription ( Qt::Key_I,
"Display mesh informations about #faces, #vertices" );
125 Viewer3D<>::setGLDoubleRenderingMode(
false);
127 virtual void keyPressEvent(QKeyEvent *e){
128 bool handled =
false;
129 if( e->key() == Qt::Key_I)
132 myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
133 std::stringstream sstring;
134 Viewer3D<>::displayMessage(QString(myIsDisplayingInfoMode ?
135 myInfoDisplay.c_str() :
" "), 1000000);
136 Viewer3D<>::updateGL();
140 Viewer3D<>::keyPressEvent(e);
145 std::string myInfoDisplay =
"No information loaded...";
146 bool myIsDisplayingInfoMode =
false;
153 namespace po = boost::program_options;
155 int main(
int argc,
char** argv )
159 po::options_description general_opt(
"Allowed options are: ");
160 general_opt.add_options()
161 (
"help,h",
"display this message")
162 (
"input,i", po::value<std::vector<string> >()->multitoken(),
"off files (.off), or OFS file (.ofs) " )
163 (
"scaleX,x", po::value<float>()->default_value(1.0),
"set the scale value in the X direction (default 1.0)" )
164 (
"scaleY,y", po::value<float>()->default_value(1.0),
"set the scale value in the Y direction (default 1.0)" )
165 (
"scaleZ,z", po:: value<float>()->default_value(1.0),
"set the scale value in the Z direction (default 1.0)")
166 (
"minLineWidth,w", po:: value<float>()->default_value(1.5),
"set the min line width of the mesh faces (default 1.5)")
167 (
"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). " )
168 (
"customColorSDP",po::value<std::vector<unsigned int> >()->multitoken(),
"set the R, G, B, A components of the colors of the sdp view" )
169 (
"displayVectorField,f",po::value<std::string>(),
"display a vector field from a simple sdp file (two points per line)" )
170 (
"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)" )
171 (
"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). " )
172 (
"displaySDP,s", po::value<std::string>(),
"Add the display of a set of discrete points as ball of radius 0.5.")
173 (
"SDPradius", po::value<double>()->default_value(0.5),
"change the ball radius to display a set of discrete points (used with displaySDP option)")
174 (
"invertNormal,n",
"invert face normal vectors." )
175 (
"drawVertex,v",
"draw the vertex of the mesh" );
178 po::variables_map vm;
180 po::store(po::parse_command_line(argc, argv, general_opt), vm);
181 }
catch(
const std::exception& ex){
183 trace.info()<<
"Error checking program options: "<< ex.what()<< endl;
186 if( !parseOK || vm.count(
"help")||argc<=1)
188 std::cout <<
"Usage: " << argv[0] <<
" [input]\n" 189 <<
"Display OFF mesh file by using QGLviewer" 190 << general_opt <<
"\n";
194 if(! vm.count(
"input"))
196 trace.error() <<
" The file name was defined" << endl;
202 std::vector<std::string> inputFilenameVect = vm[
"input"].as<std::vector<std::string > >();
203 float sx = vm[
"scaleX"].as<
float>();
204 float sy = vm[
"scaleY"].as<
float>();
205 float sz = vm[
"scaleZ"].as<
float>();
207 unsigned int meshColorR = 240;
208 unsigned int meshColorG = 240;
209 unsigned int meshColorB = 240;
210 unsigned int meshColorA = 255;
212 unsigned int meshColorRLine = 0;
213 unsigned int meshColorGLine = 0;
214 unsigned int meshColorBLine = 0;
215 unsigned int meshColorALine = 255;
218 unsigned int sdpColorR = 240;
219 unsigned int sdpColorG = 240;
220 unsigned int sdpColorB = 240;
221 unsigned int sdpColorA = 255;
224 bool displayVectorField = vm.count(
"displayVectorField");
225 std::vector<unsigned int> vectFieldIndices = {0,1,2,3,4,5};
227 if (displayVectorField) {
228 if(vm.count(
"vectorFieldIndex")){
229 vectFieldIndices = vm[
"vectorFieldIndex"].as<std::vector<unsigned int> >();
230 if (vectFieldIndices.size() != 6) {
231 trace.warning() <<
"you should specify indices for each of the 6 fields of the two coordinates." << std::endl;
232 vectFieldIndices = {0,1,2,3,4,5};
237 float lineWidth = vm[
"minLineWidth"].as<
float>();
239 DGtal::Color vFieldLineColor = DGtal::Color::Red;
240 if(vm.count(
"customLineColor")){
241 std::vector<unsigned int > vectCol = vm[
"customLineColor"].as<std::vector<unsigned int> >();
242 if(vectCol.size()!=3 ){
243 trace.error() <<
"colors specification should contain R,G,B values (using default red)."<< std::endl;
245 vFieldLineColor.setRGBi(vectCol[0], vectCol[1], vectCol[2], 255);
248 if(vm.count(
"customColorMesh")){
249 std::vector<unsigned int > vectCol = vm[
"customColorMesh"].as<std::vector<unsigned int> >();
250 if(vectCol.size()!=4 && vectCol.size()!=8 ){
251 trace.error() <<
"colors specification should contain R,G,B and Alpha values"<< std::endl;
253 meshColorR = vectCol[0];
254 meshColorG = vectCol[1];
255 meshColorB = vectCol[2];
256 meshColorA = vectCol[3];
257 if(vectCol.size() == 8){
258 meshColorRLine = vectCol[4];
259 meshColorGLine = vectCol[5];
260 meshColorBLine = vectCol[6];
261 meshColorALine = vectCol[7];
266 if(vm.count(
"customColorSDP")){
267 std::vector<unsigned int > vectCol = vm[
"customColorSDP"].as<std::vector<unsigned int> >();
268 if(vectCol.size()!=4){
269 trace.error() <<
"colors specification should contain R,G,B and Alpha values"<< std::endl;
271 sdpColorR = vectCol[0];
272 sdpColorG = vectCol[1];
273 sdpColorB = vectCol[2];
274 sdpColorA = vectCol[3];
279 QApplication application(argc,argv);
280 CustomViewer3D viewer;
281 std::stringstream title;
282 title <<
"Simple Mesh Viewer: " << inputFilenameVect[0];
283 viewer.setWindowTitle(title.str().c_str());
285 viewer.myGLLineMinWidth = lineWidth;
286 viewer.setGLScale(sx, sy, sz);
287 bool invertNormal= vm.count(
"invertNormal");
290 double ballRadius = vm[
"SDPradius"].as<
double>();
292 trace.info() <<
"Importing mesh... ";
294 std::vector<Mesh<DGtal::Z3i::RealPoint> > vectMesh;
295 for(
unsigned int i = 0; i< inputFilenameVect.size(); i++){
296 Mesh<DGtal::Z3i::RealPoint> aMesh(!vm.count(
"customColorMesh"));
297 aMesh << inputFilenameVect[i];
298 vectMesh.push_back(aMesh);
302 bool import = vectMesh.size()==inputFilenameVect.size();
304 trace.info() <<
"File import failed. " << std::endl;
308 trace.info() <<
"[done]. "<< std::endl;
309 if(vm.count(
"displaySDP")){
310 std::string filenameSDP = vm[
"displaySDP"].as<std::string>();
311 vector<Z3i::RealPoint> vectPoints;
312 vectPoints = PointListReader<Z3i::RealPoint>::getPointsFromFile(filenameSDP);
313 viewer << CustomColors3D(Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA),
314 Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
315 for(
unsigned int i=0;i< vectPoints.size(); i++){
316 viewer.addBall(vectPoints.at(i), ballRadius);
320 for(
unsigned int i=0; i<vectMesh.size(); i++){
321 vectMesh[i].invertVertexFaceOrder();
325 viewer << CustomColors3D(Color(meshColorRLine, meshColorGLine, meshColorBLine, meshColorALine),
326 Color(meshColorR, meshColorG, meshColorB, meshColorA));
327 for(
unsigned int i=0; i<vectMesh.size(); i++){
328 viewer << vectMesh[i];
331 if(vm.count(
"drawVertex")){
332 for(
unsigned int i=0; i<vectMesh.size(); i++){
333 for( Mesh<DGtal::Z3i::RealPoint>::VertexStorage::const_iterator it = vectMesh[i].vertexBegin();
334 it!=vectMesh[i].vertexEnd(); ++it){
335 DGtal::Z3i::Point pt;
336 pt[0]=(*it)[0]; pt[1]=(*it)[1]; pt[2]=(*it)[2];
343 if (displayVectorField) {
344 std::vector<unsigned int > vectFieldIndices1 = {vectFieldIndices[0],vectFieldIndices[1], vectFieldIndices[2]};
345 std::vector<unsigned int > vectFieldIndices2 = {vectFieldIndices[3],vectFieldIndices[4], vectFieldIndices[5]};
347 std::vector<DGtal::Z3i::RealPoint> vectPt1 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(vm[
"displayVectorField"].as<std::string>(), vectFieldIndices1);
348 std::vector<DGtal::Z3i::RealPoint> vectPt2 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(vm[
"displayVectorField"].as<std::string>(), vectFieldIndices2);
349 viewer.createNewLineList();
350 for (
unsigned int i = 0; i < vectPt1.size(); i++) {
352 viewer.setLineColor(vFieldLineColor);
353 viewer.addLine(vectPt1[i], vectPt2[i]);
356 unsigned int nbVertex = 0;
357 unsigned int nbFaces = 0;
358 for(
auto const &m: vectMesh)
360 nbVertex += m.nbVertex();
361 nbFaces +=m.nbFaces();
364 ss <<
"# faces: " << std::fixed << nbFaces <<
" #vertex: " << nbVertex;
365 viewer.myInfoDisplay = ss.str();
366 viewer << CustomViewer3D::updateDisplay;
367 return application.exec();