PMLRigidBody.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 library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library 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 Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 
00026 /***************************************************************************
00027  *                                                                         *
00028  *   This program is free software; you can redistribute it and/or modify  *
00029  *   it under the terms of the GNU General Public License as published by  *
00030  *   the Free Software Foundation; either version 2 of the License, or     *
00031  *   (at your option) any later version.                                   *
00032  *                                                                         *
00033  ***************************************************************************/
00034 
00035 #include "PMLRigidBody.h"
00036 
00037 #include <PhysicalModel.h>
00038 #include <CellProperties.h>
00039 
00040 #include <sofa/defaulttype/Vec3Types.h>
00041 #include <sofa/component/mapping/RigidMapping.h>
00042 #include <sofa/component/mapping/IdentityMapping.h>
00043 //#include "sofa/componentCore/MappedModel.h"
00044 #include <sofa/component/mass/UniformMass.h>
00045 #include <sofa/component/mass/DiagonalMass.h>
00046 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00047 #include <sofa/component/topology/MeshTopology.h>
00048 #include <sofa/component/collision/TriangleModel.h>
00049 //#include "sofa/component/collision/LineModel.h"
00050 //#include "sofa/component/collision/PointModel.h"
00051 //using namespace sofa::component::GL;
00052 using namespace sofa::component;
00053 using namespace sofa::component::mapping;
00054 using namespace sofa::component::collision;
00055 using namespace sofa::component::mass;
00056 using namespace sofa::component::topology;
00057 //using namespace sofa::Core;
00058 
00059 
00060 namespace sofa
00061 {
00062 
00063 namespace filemanager
00064 {
00065 
00066 namespace pml
00067 {
00068 
00069 PMLRigidBody::PMLRigidBody(StructuralComponent* body, GNode * parent)
00070 {
00071     parentNode = parent;
00072     bodyFixed = false;
00073     //get the parameters
00074     collisionsON = body->getProperties()->getBool("collision");
00075     name = body->getProperties()->getName();
00076 
00077     if(body->getProperties()->getString("mass") != "")
00078         initMass(body->getProperties()->getString("mass"));
00079 
00080     if(body->getProperties()->getString("inertiaMatrix") != "")
00081         initInertiaMatrix(body->getProperties()->getString("inertiaMatrix"));
00082 
00083     initPosition(body->getProperties()->getString("position"));
00084     initVelocity(body->getProperties()->getString("velocity"));
00085     solverName = body->getProperties()->getString("solver");
00086 
00087     //create the structure
00088     createMass(body);
00089     createMechanicalState(body);
00090     createVisualModel(body);
00091     createCollisionModel();
00092     createSolver();
00093 }
00094 
00095 
00096 PMLRigidBody::~PMLRigidBody()
00097 { 
00098     if(mmodel){ delete mmodel; mmodel=NULL;}
00099     if (mapping){ delete mapping; mapping = NULL;}
00100     if (VisualNode){ delete VisualNode; VisualNode = NULL;}
00101     if (CollisionNode){ delete CollisionNode; CollisionNode = NULL;}
00102 }
00103 
00104 
00105 void PMLRigidBody::initMass(string m)
00106 {
00107     int pos;
00108     while(!m.empty()) {
00109         pos = m.find(' ', 0);
00110         if(pos != 0) {
00111             string s=m.substr(0,pos);
00112             SReal d=atof(s.c_str());
00113             massList.push_back(d);
00114             m.erase(0,pos);
00115         }else
00116             m.erase(0,1);
00117     }
00118 }
00119 
00120 void PMLRigidBody::initInertiaMatrix(string m)
00121 {
00122     int pos;
00123     while(!m.empty()) {
00124         pos = m.find(' ', 0);
00125         if(pos != 0) {
00126             string s=m.substr(0,pos);
00127             SReal d=atof(s.c_str());
00128             inertiaMatrix.push_back(d);
00129             m.erase(0,pos);
00130         }else
00131             m.erase(0,1);
00132     }
00133 }
00134 
00135 void PMLRigidBody::initPosition(string m)
00136 {
00137     int pos;
00138     std::vector<SReal> vec;
00139     while(!m.empty()) {
00140         pos = m.find(' ', 0);
00141         if(pos != 0) {
00142             string s=m.substr(0,pos);
00143             SReal d=atof(s.c_str());
00144             vec.push_back(d);
00145             m.erase(0,pos);
00146         }else
00147             m.erase(0,1);
00148     }
00149     if (vec.size() >= 3)
00150       transPos = Vector3(vec[0],vec[1],vec[2]);
00151     else 
00152       transPos = Vector3(0,0,0);
00153 
00154     if (vec.size() == 6){
00155       rotPos = Quat(Vector3(1,0,0),vec[3]);
00156       rotPos += Quat(Vector3(0,1,0),vec[4]);
00157       rotPos += Quat(Vector3(0,0,1),vec[5]);
00158     }
00159     else if (vec.size() == 7)
00160         rotPos = Quat(vec[3], vec[4], vec[5], vec[6]);
00161     else {
00162       rotPos = Quat(Vector3(1,0,0),0);
00163       rotPos += Quat(Vector3(0,1,0),0);
00164       rotPos += Quat(Vector3(0,0,1),0);
00165     }
00166 }
00167 
00168 void PMLRigidBody::initVelocity(string m)
00169 {
00170     int pos;
00171     std::vector<SReal> vec;
00172     while(!m.empty()) {
00173         pos = m.find(' ', 0);
00174         if(pos != 0) {
00175             string s=m.substr(0,pos);
00176             SReal d=atof(s.c_str());
00177             vec.push_back(d);
00178             m.erase(0,pos);
00179         }else
00180             m.erase(0,1);
00181     }
00182     if (vec.size() >= 3)
00183       transVel = Vector3(vec[0],vec[1],vec[2]);
00184     else
00185       transVel = Vector3(0,0,0);
00186 
00187     if (vec.size() == 6)
00188       rotVel += Vector3(vec[3],vec[4],vec[5]);
00189     else
00190       rotVel = Vector3(0,0,0);
00191 }
00192 
00193 
00194 Vector3 PMLRigidBody::getDOF(unsigned int index)
00195 {
00196     return (*((MechanicalState<Vec3Types>*)mmodel)->getX())[index];
00197 }
00198 
00199 
00200 void PMLRigidBody::createMechanicalState(StructuralComponent* )
00201 {
00202     refDOF = new MechanicalObject<RigidTypes>;
00203     refDOF->resize(1);
00204 
00205     //initial position and orientation of model
00206     (*((MechanicalState<RigidTypes>*)refDOF)->getX())[0] = RigidTypes::Coord(transPos+bary, rotPos);
00207 
00208     //initial velocity (translation and rotation)
00209     (*((MechanicalState<RigidTypes>*)refDOF)->getV())[0] = RigidTypes::Deriv(transVel, rotVel);
00210 
00211     parentNode->addObject(refDOF);
00212 }
00213 
00214 
00215 void PMLRigidBody::createTopology(StructuralComponent* body)
00216 {
00217 
00218     unsigned int nbCells = body->getNumberOfCells();
00219 
00220     //if there is only the list of atoms in the body (no surface representation),
00221     //then no topology is created
00222     if (nbCells == 1 && body->getCell(0)->getProperties()->getType() == StructureProperties::POLY_VERTEX )
00223         return;
00224 
00225     topology = new MeshTopology();
00226     ((BaseMeshTopology*)topology)->clear();
00227 
00228     BaseMeshTopology::Triangle * tri;
00229     BaseMeshTopology::Quad * quad;
00230     Cell * pCell;
00231     Atom * pAtom;
00232 
00233     //for each pml cell, build a new Triangle or quads switch the type
00234     for (unsigned int cid(0) ; cid<nbCells ; cid++) {
00235         pCell = body->getCell(cid);
00236         switch(pCell->getProperties()->getType()) {
00237 
00238             case StructureProperties::TRIANGLE :
00239                 tri = new BaseMeshTopology::Triangle;
00240                 for (unsigned int p(0) ; p<3 ; p++) {
00241                     pAtom = (Atom*)(pCell->getStructure(p));
00242                     (*tri)[p] = AtomsToDOFsIndexes[pAtom->getIndex()];
00243                 }
00244                 ((BaseMeshTopology::SeqTriangles&)((BaseMeshTopology*)topology)->getTriangles()).push_back(*tri);
00245                 break;
00246 
00247             case StructureProperties::QUAD :
00248                 quad = new BaseMeshTopology::Quad;
00249                 for (unsigned int p(0) ; p<4 ; p++) {
00250                     pAtom = (Atom*)(pCell->getStructure(p));
00251                     (*quad)[p] = AtomsToDOFsIndexes[pAtom->getIndex()];
00252                 }
00253                 ((BaseMeshTopology::SeqQuads&)((BaseMeshTopology*)topology)->getQuads()).push_back(*quad);
00254                 break;
00255 
00256             default : break;
00257         }
00258     }
00259 }
00260 
00261 
00262 void PMLRigidBody::createVisualModel(StructuralComponent* body)
00263 {
00264     VisualNode = new GNode("points");
00265     parentNode->addChild(VisualNode);
00266     //create mechanical object
00267     mmodel = new MechanicalObject<Vec3Types>;
00268     //create visual model
00269     OglModel * vmodel = new OglModel;
00270     StructuralComponent* atoms = body->getAtoms();
00271     mmodel->resize(atoms->getNumberOfStructures());
00272     Atom* pAtom;
00273 
00274     SReal pos[3];
00275     for (unsigned int i(0) ; i<atoms->getNumberOfStructures() ; i++) {
00276         pAtom = (Atom*) (atoms->getStructure(i));
00277         pAtom->getPosition(pos);
00278         AtomsToDOFsIndexes.insert(std::pair <unsigned int, unsigned int>(pAtom->getIndex(),i));
00279         (*((MechanicalState<Vec3Types>*)mmodel)->getX())[i] = Vector3(pos[0]-bary[0],pos[1]-bary[1],pos[2]-bary[2]);
00280     }
00281 
00282     VisualNode->addObject(mmodel);
00283 
00284     createTopology(body);
00285     VisualNode->addObject(topology);
00286 
00287     double * color = body->getColor();
00288     vmodel->setColor((float)color[0], (float)color[1], (float)color[2], (float)color[3]);
00289     vmodel->load("","","");
00290 
00291     //create mappings
00292     mapping = new RigidMapping< MechanicalMapping<MechanicalState<RigidTypes>, MechanicalState<Vec3Types> > >( (MechanicalState<RigidTypes>*)refDOF, (MechanicalState<Vec3Types>*)mmodel);
00293     BaseMapping * Vmapping = new IdentityMapping< Mapping< State<Vec3Types>, MappedModel< ExtVectorTypes< Vec<3,GLfloat>, Vec<3,GLfloat> > > > >((MechanicalState<Vec3Types>*)mmodel, vmodel);
00294 
00295     VisualNode->addObject(mapping);
00296     VisualNode->addObject(Vmapping);
00297     VisualNode->addObject(vmodel);
00298 
00299 }
00300 
00301 
00302 void PMLRigidBody::createMass(StructuralComponent* body)
00303 {
00304     if (! massList.empty()) // CASE MASS SPECIFIED --> Compute Inertia Matrix
00305     {
00306         StructuralComponent* atoms = body->getAtoms();
00307         Atom * pAtom;
00308         SReal masse = massList[0], totalMass=0.0;
00309         SReal pos[3];
00310         unsigned int nbPoints = atoms->getNumberOfStructures();
00311         SReal A,B,C,D,E,F;
00312         A = B = C = D = E = F = 0.0;
00313         bary[0] = bary[1] = bary[2] = 0.0;
00314 
00315         //calcul matrice d'inertie
00316         for (unsigned int i=0; i<nbPoints; i++) 
00317         {
00318             if (massList.size() == nbPoints)
00319                 masse = massList[i];
00320             pAtom = (Atom*)(atoms->getStructure(i));
00321             pAtom->getPosition(pos);
00322 
00323             // contribution of i in the inertia matrix
00324             A += masse * ( pos[1]*pos[1] + pos[2]*pos[2] );
00325             B += masse * ( pos[0]*pos[0] + pos[2]*pos[2] );
00326             C += masse * ( pos[0]*pos[0] + pos[1]*pos[1] );
00327             D += masse * pos[1] * pos[2]; //E[i]->mass*E[i]->X(2)*E[i]->X(3);
00328             E += masse * pos[2] * pos[0];
00329             F += masse * pos[0] * pos[1];
00330             bary[0]+=pos[0]*masse; bary[1]+=pos[1]*masse; bary[2]+=pos[2]*masse;
00331             totalMass += masse;
00332         }
00333 
00334         // Translate the matrix to be the inertia matrix / G
00335         bary[0]/=totalMass; bary[1]/=totalMass; bary[2]/=totalMass;
00336 
00337         A += totalMass*(bary[1]*bary[1] + bary[2]*bary[2] );
00338         B += totalMass*(bary[2]*bary[2] + bary[0]*bary[0] );
00339         C += totalMass*(bary[0]*bary[0] + bary[1]*bary[1] );
00340         D -= totalMass* bary[1]*bary[2];
00341         E -= totalMass* bary[2]*bary[0];
00342         F -= totalMass* bary[0]*bary[1];
00343         
00344         SReal coefs[9] = {A,-F, -E, -F, B, -D, -E, -D, C };
00345 
00346         Mat3x3d iMatrix(coefs);
00347 
00348         //add uniform or diagonal mass to model
00349         if (massList.size() ==1) {
00350             mass = new UniformMass<Rigid3Types,Rigid3Mass>;
00351             Rigid3Mass m(masse);
00352             m.inertiaMatrix = iMatrix;
00353             ((UniformMass<Rigid3Types,Rigid3Mass>*)mass)->setMass( m );
00354         }else {
00355             mass = new DiagonalMass<Rigid3Types,Rigid3Mass>;
00356             for (unsigned int j=0 ; j<massList.size(); j++) {
00357                 Rigid3Mass m(massList[j]);
00358                 m.inertiaMatrix = iMatrix;
00359                 ((DiagonalMass<Rigid3Types,Rigid3Mass>*)mass)->addMass( m );
00360             }
00361         }
00362     }
00363     else    // CASE INERTIA MATRIX SPECIFIED
00364     {
00365         Mat3x3d iMatrix;
00366         switch (inertiaMatrix.size())
00367         {
00368             case 0 : //zero value --> Nothing...
00369                 return;
00370             case 1 : //one value --> isotropic matrix
00371             {
00372                 SReal val1 = inertiaMatrix[0];
00373                 SReal coefs1[9] = {val1,0,0, 0,val1,0, 0,0,val1 };
00374                 iMatrix = Mat3x3d(coefs1);
00375                 break;
00376             }
00377             case 3 : // 3 values --> diagonal matrix
00378             {
00379                 SReal coefs3[9] = {inertiaMatrix[0],0,0, 0,inertiaMatrix[1],0, 0,0,inertiaMatrix[2] };
00380                 iMatrix = Mat3x3d(coefs3);
00381                 break;
00382             }
00383             case 6 : // 6 values --> symetric matrix
00384             {
00385                 SReal coefs9[9] = {inertiaMatrix[0],inertiaMatrix[1],inertiaMatrix[2], \
00386                                     inertiaMatrix[1],inertiaMatrix[3],inertiaMatrix[4], \
00387                                     inertiaMatrix[2],inertiaMatrix[4],inertiaMatrix[5] };
00388                 iMatrix = Mat3x3d(coefs9);
00389                 break;
00390             }
00391             default : // else --> houston, we've got a problem!
00392                 cerr<<"WARNING building "<<name<<" object : inertia matrix not properly defined."<<endl;
00393                 return;
00394         }
00395         mass = new UniformMass<Rigid3Types,Rigid3Mass>;
00396         Rigid3Mass m(1.0);
00397         m.inertiaMatrix = iMatrix;
00398         ((UniformMass<Rigid3Types,Rigid3Mass>*)mass)->setMass( m );
00399     }
00400 
00401     if (mass)
00402         parentNode->addObject(mass);
00403 }
00404 
00405 void PMLRigidBody::createCollisionModel()
00406 {
00407     if (collisionsON) 
00408     {
00409         //CollisionNode = new GNode("Collision");
00410         //parentNode->addChild(CollisionNode);
00411 
00412         /*CollisionNode->addObject(mmodel);
00413         CollisionNode->addObject(topology);
00414         CollisionNode->addObject(mapping);*/
00415 
00416         TriangleModel * cmodel = new TriangleModel;
00417         //LineModel *lmodel = new LineModel;
00418         //PointModel *pmodel = new PointModel;
00419         VisualNode->addObject(cmodel);
00420         //VisualNode->addObject(lmodel);
00421         //VisualNode->addObject(pmodel);
00422 
00423         cmodel->init();
00424         //lmodel->init();
00425         //pmodel->init();
00426     }
00427 }
00428 
00429 
00430 bool PMLRigidBody::FusionBody(PMLBody* )
00431 {
00432     return false;
00433 }
00434 
00435 
00436 }
00437 }
00438 }

Generated on Sun Nov 23 03:56:16 2008 for Sofa by  doxygen 1.5.7.1