meshconv.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This program is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU General Public License as published by the Free  *
00007 * Software Foundation; either version 2 of the License, or (at your option)   *
00008 * any later version.                                                          *
00009 *                                                                             *
00010 * This program is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
00013 * more details.                                                               *
00014 *                                                                             *
00015 * You should have received a copy of the GNU General Public License along     *
00016 * with this program; if not, write to the Free Software Foundation, Inc., 51  *
00017 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
00018 *******************************************************************************
00019 *                            SOFA :: Applications                             *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 /******* COPYRIGHT ************************************************
00028 *                                                                 *
00029 *                         FlowVR Render                           *
00030 *                   Parallel Rendering Modules                    *
00031 *                                                                 *
00032 *-----------------------------------------------------------------*
00033 * COPYRIGHT (C) 2005 by                                           *
00034 * Laboratoire Informatique et Distribution (UMR5132) and          *
00035 * INRIA Project MOVI. ALL RIGHTS RESERVED.                        *
00036 *                                                                 *
00037 * This source is covered by the GNU GPL, please refer to the      *
00038 * COPYING file for further information.                           *
00039 *                                                                 *
00040 *-----------------------------------------------------------------*
00041 *                                                                 *
00042 *  Original Contributors:                                         *
00043 *    Jeremie Allard,                                              *
00044 *    Clement Menier.                                              *
00045 *                                                                 * 
00046 *******************************************************************
00047 *                                                                 *
00048 * File: ./src/utils/meshconv.cpp                                  *
00049 *                                                                 *
00050 * Contacts:                                                       *
00051 *                                                                 *
00052 ******************************************************************/
00053 #include <math.h>
00054 #include <stdlib.h>
00055 #include <stdio.h>
00056 
00057 #include <ftl/cmdline.h>
00058 #include <flowvr/render/mesh.h>
00059 
00060 using namespace flowvr::render;
00061 
00062 extern void tesselateMesh(Mesh& obj, int rec=1, bool onSphere=false);
00063 
00064 int main(int argc, char** argv)
00065 {
00066   bool normalize = false;
00067   bool flip = false;
00068   bool wnormals = false;
00069   bool rnormals = false;
00070   bool rtexcoords = false;
00071   bool closemesh = false;
00072   Vec3f translation;
00073   Vec3f rotation;
00074   Vec3f scale(1,1,1);
00075   float dilate = 0.0f;
00076   int tesselate = 0;
00077   bool sphere = false;
00078   bool dist = false;
00079   int res = 16;
00080   int rx=0,ry=0,rz=0;
00081   float border = 0.25f;
00082   ftl::CmdLine cmd("Usage: meshconv [options] mesh.input [mesh.output]");
00083   cmd.opt("normalize",'n',"transform points so that the center is at <0,0,0> and the max coodinate is 1",&normalize);
00084   cmd.opt("flip",'f',"flip normals",&flip);
00085   cmd.opt("wnormals",'N',"force writing of normals",&wnormals);
00086   cmd.opt("rnormals",'O',"remove normals",&rnormals);
00087   cmd.opt("rtexcoords",'T',"remove texcoords",&rtexcoords);
00088   cmd.opt("close",'c',"close mesh",&closemesh);
00089   cmd.opt("translate",'t',"translate the mesh",&translation);
00090   cmd.opt("rotate",'r',"rotate the mesh using euler angles in degree",&rotation);
00091   cmd.opt("scale",'s',"scale the mesh using 3 coefficients",&scale);
00092   cmd.opt("dilate",'d',"dilate (i.e. displace vertices of the given distance along their normals)",&dilate);
00093   cmd.opt("tesselate",'a',"tesselate (split each edge in 2 resursivly n times)",&tesselate);
00094   cmd.opt("sphere",'S',"consider the mesh as a sphere for tesselation",&sphere);
00095   cmd.opt("dist",'D',"compute distance field",&dist);
00096   cmd.opt("res",'R',"resolution of distance field",&res);
00097   cmd.opt("rx",'X',"X resolution of distance field",&rx);
00098   cmd.opt("ry",'Y',"Y resolution of distance field",&ry);
00099   cmd.opt("rz",'Z',"Z resolution of distance field",&rz);
00100   cmd.opt("border",'B',"distance field border size relative to the object's BBox size (or negative for exact size)",&border);
00101   bool error=false;
00102   if (!cmd.parse(argc,argv,&error))
00103     return error?1:0;
00104 
00105   if (cmd.args.size()<1 || cmd.args.size()>2)
00106   {
00107     std::cerr << cmd.help() << std::endl;
00108     return 1;
00109   }
00110 
00111   std::string file_in = cmd.args[0];
00112   std::string file_out;
00113   if (cmd.args.size()>=2) file_out = cmd.args[1];
00114 
00115   Mesh obj;
00116 
00117   if (!obj.load(file_in.c_str()))
00118   {
00119     std::cerr << "Failed to read "<<file_in<<std::endl;
00120     return 1;
00121   }
00122 
00123   if (normalize)
00124   {
00125     BBox bb = obj.calcBBox();
00126     std::cout << "Mesh bbox="<<bb<<std::endl;
00127     std::cout << "Normalizing mesh..."<<std::endl;
00128     float size = 0;
00129     for (int i=0;i<3;i++)
00130     {
00131       float d = bb.b[i]-bb.a[i];
00132       if (d>size) size=d;
00133     }
00134     Vec3f center = (bb.a+bb.b)*0.5;
00135     float sc = 2/size;
00136     Mat4x4f m; m.identity();
00137     m(0,0)=sc; m(0,3) = -center[0]*sc;
00138     m(1,1)=sc; m(1,3) = -center[1]*sc;
00139     m(2,2)=sc; m(2,3) = -center[2]*sc;
00140     for (int i=0;i<obj.nbp();i++)
00141       obj.PP(i) = transform(m,obj.getPP(i));
00142   }
00143 
00144   if (scale != Vec3f(1,1,1))
00145   {
00146     std::cout << "Scaling mesh..."<<std::endl;
00147     for (int i=0;i<obj.nbp();i++)
00148     {
00149       Vec3f p = obj.getPP(i);
00150       p[0] *= scale[0];
00151       p[1] *= scale[1];
00152       p[2] *= scale[2];
00153       obj.PP(i) = p;
00154     }
00155   }
00156     
00157     Mat4x4f xform;
00158     bool hasXForm = false;
00159     xform.identity();
00160 
00161   if (rotation != Vec3f(0,0,0))
00162   {
00163     std::cout << "Rotating mesh..."<<std::endl;
00164     Mat3x3f mat;
00165     Quat qx,qy,qz;
00166     qx.fromDegreeAngAxis(rotation[0],Vec3f(1,0,0));
00167     qy.fromDegreeAngAxis(rotation[1],Vec3f(0,1,0));
00168     qz.fromDegreeAngAxis(rotation[2],Vec3f(0,0,1));
00169     Quat q = qx*qy*qz;
00170     q.toMatrix(&mat);
00171     std::cout << "mat = "<<mat<<std::endl;
00172     for (int i=0;i<obj.nbp();i++)
00173     {
00174       obj.PP(i) = mat*obj.getPP(i);
00175       obj.PN(i) = mat*obj.getPN(i);
00176     }
00177       hasXForm = true;
00178       xform = mat;
00179   }
00180 
00181   if (translation != Vec3f(0,0,0))
00182   {
00183     std::cout << "Translating mesh..."<<std::endl;
00184     for (int i=0;i<obj.nbp();i++)
00185     {
00186       obj.PP(i) = obj.getPP(i) + translation;
00187     }
00188       hasXForm = true;
00189       xform[0][3] = translation[0];
00190       xform[1][3] = translation[1];
00191       xform[2][3] = translation[2];
00192   }
00193     
00194   if (obj.distmap && hasXForm)
00195   {
00196       //Mat4x4f m; m.invert(xform);
00197       std::cout << "distmap mat = "<<xform <<" * " << obj.distmap->mat<<" = ";
00198     obj.distmap->mat = xform * obj.distmap->mat;
00199       std::cout << obj.distmap->mat<<std::endl;
00200   }
00201 
00202   std::cout << "Mesh bbox="<<obj.calcBBox()<<std::endl;
00203   if (flip)
00204   {
00205     std::cout << "Flipping mesh..."<<std::endl;
00206     obj.flipAll();
00207     //obj.calcFlip();
00208   }
00209   if (closemesh)
00210   {
00211     bool closed = obj.isClosed();
00212     std::cout << "Mesh is "<<(closed?"":"NOT ")<<"closed."<<std::endl;
00213     if (closemesh && !closed)
00214     {
00215       obj.calcFlip();
00216       std::cout << "Closing mesh..."<<std::endl;
00217       obj.close();
00218       std::cout << "Mesh is "<<(obj.isClosed()?"":"NOT ")<<"closed."<<std::endl;
00219     }
00220   }
00221 
00222   if (dilate != 0.0f)
00223     obj.dilate(dilate);
00224     
00225     if (tesselate > 0 || sphere)
00226     {
00227         std::cout << "Tesselating mesh..."<<std::endl;
00228         tesselateMesh(obj, tesselate, sphere);
00229     }
00230     
00231     if (dist)
00232     {
00233         if (!rx) rx = res;
00234         if (!ry) ry = res;
00235         if (!rz) rz = res;
00236         std::cout << "Flipping mesh..."<<std::endl;
00237         obj.calcFlip();
00238         obj.calcEdges();
00239         bool closed = obj.isClosed();
00240         std::cout << "Mesh is "<<(closed?"":"NOT ")<<"closed."<<std::endl;
00241         if (!closed)
00242         {
00243             std::cout << "Closing mesh..."<<std::endl;
00244             obj.close();
00245             std::cout << "Mesh is "<<(obj.isClosed()?"":"NOT ")<<"closed."<<std::endl;
00246         }
00247         std::cout << "Computing "<<rx<<'x'<<ry<<'x'<<rz<<" DistMap..."<<std::endl;
00248         obj.calcDistMap(rx,ry,rz,(border<0 ? -border : obj.calcBBox().size()*border));
00249     }
00250     
00251     
00252   if (wnormals)
00253     obj.setAttrib(Mesh::MESH_POINTS_NORMAL,true);
00254   if (rnormals)
00255     obj.setAttrib(Mesh::MESH_POINTS_NORMAL,false);
00256   if (rtexcoords)
00257     obj.setAttrib(Mesh::MESH_POINTS_TEXCOORD,false);
00258   if (!file_out.empty())
00259   {
00260     std::cout << "Saving result..."<<std::endl;
00261     obj.save(file_out.c_str());
00262   }
00263   return 0;
00264 }

Generated on Sun Nov 23 02:28:34 2008 for Sofa by  doxygen 1.5.7.1