PMLReader.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "PMLReader.h"
00036
00037 #include <MultiComponent.h>
00038
00039 #include "PMLRigidBody.h"
00040 #include "PMLFemForceField.h"
00041 #include "PMLStiffSpringForceField.h"
00042 #include "PMLInteractionForceField.h"
00043 #include "PMLMappedBody.h"
00044
00045 #include "sofa/component/collision/DefaultPipeline.h"
00046 #include "sofa/component/collision/DefaultContactManager.h"
00047 #include "sofa/component/collision/NewProximityIntersection.h"
00048 #include "sofa/component/collision/DefaultCollisionGroupManager.h"
00049 #include "sofa/component/collision/BruteForceDetection.h"
00050 #include "sofa/simulation/common/VisualVisitor.h"
00051 #include "sofa/simulation/tree/Simulation.h"
00052
00053 using namespace sofa::component::collision;
00054 using namespace sofa::simulation::tree;
00055 using namespace sofa::simulation;
00056
00057 namespace sofa
00058 {
00059
00060 namespace filemanager
00061 {
00062
00063 namespace pml
00064 {
00065
00066
00067 void PMLReader::BuildStructure(const char* filename, GNode* root){
00068
00069 if (!filename) return;
00070
00071 if(pm) {
00072 delete pm;
00073 pm = NULL;
00074 }
00075 pm = new PhysicalModel(filename);
00076
00077 if (!pm){
00078 cerr<<"PML reader error : failed to load PML file "<<filename<<endl;
00079 return;
00080 }
00081
00082 if (pm->getNumberOfAtoms()==0){
00083 cerr<<"PML reader error : PML file "<<filename<<" not valid"<<endl;
00084 return;
00085 }
00086
00087 this->BuildStructure(root);
00088 }
00089
00090
00091 void PMLReader::BuildStructure(PhysicalModel * model, GNode* root){
00092
00093 if(pm) delete pm;
00094 pm = model;
00095 this->BuildStructure(root);
00096 }
00097
00098
00099 void PMLReader::BuildStructure(GNode* root){
00100
00101 bodiesList.clear();
00102
00103
00104 MultiComponent * bodies = (MultiComponent*) (pm->getExclusiveComponents()->getComponentByName("Bodies"));
00105
00106 if(!bodies) return;
00107
00108 bool collisionsExist = false;
00109
00110
00111 PMLBody * body;
00112 for (unsigned int i=0 ; i<bodies->getNumberOfSubComponents() ; i++ )
00113 {
00114
00115 body = createBody( (StructuralComponent*) bodies->getSubComponent(i), root );
00116
00117
00118 if (body) {
00119 bodiesList.push_back(body);
00120 if (body->hasCollisions())
00121 collisionsExist = true;
00122 }
00123 }
00124
00125
00126 if (collisionsExist){
00127 DefaultPipeline * ps = new DefaultPipeline;
00128 BruteForceDetection * bfd = new BruteForceDetection;
00129 NewProximityIntersection * mpi = new NewProximityIntersection;
00130
00131 VisualComputeBBoxVisitor act;
00132 getSimulation()->init(root);
00133 root->execute(act);
00134 SReal dx=(act.maxBBox[0]-act.minBBox[0]);
00135 SReal dy=(act.maxBBox[1]-act.minBBox[1]);
00136 SReal dz=(act.maxBBox[2]-act.minBBox[2]);
00137 SReal dmax = sqrt(dx*dx + dy*dy + dz*dz);
00138
00139 mpi->setAlarmDistance(dmax/30);
00140 mpi->setContactDistance(dmax/40);
00141 DefaultContactManager * contactManager = new DefaultContactManager;
00142 DefaultCollisionGroupManager * cgm = new DefaultCollisionGroupManager;
00143
00144 root->addObject(ps);
00145 root->addObject(bfd);
00146 root->addObject(mpi);
00147 root->addObject(contactManager);
00148 root->addObject(cgm);
00149 }
00150
00151
00152 processFusions(root);
00153
00154 sofa::simulation::tree::getSimulation()->init(root);
00155 }
00156
00157
00158
00159 PMLBody* PMLReader::createBody(StructuralComponent* SC, GNode * root) {
00160
00161 string type = SC->getProperties()->getString("bodyType");
00162
00163 GNode * child = new GNode(SC->getProperties()->getName());
00164
00165 if (type == "rigid" ) {
00166 root->addChild(child);
00167 return new PMLRigidBody(SC, child);
00168 }
00169 if (type == "FEM" ){
00170 root->addChild(child);
00171 return new PMLFemForceField(SC, child);
00172 }
00173 if (type == "stiffSpring" ){
00174 root->addChild(child);
00175 return new PMLStiffSpringForceField(SC, child);
00176 }
00177 if (type == "interaction" ){
00178 delete child;
00179 std::string name1 = SC->getProperties()->getString("body1");
00180 std::string name2 = SC->getProperties()->getString("body2");
00181 PMLBody * body1=NULL;
00182 PMLBody * body2=NULL;
00183
00184 std::vector<PMLBody*>::iterator it = bodiesList.begin();
00185 while((!body1 || !body2) && it != bodiesList.end() )
00186 {
00187 if ( (*it)->getName() == name1)
00188 body1 = *it;
00189 if ( (*it)->getName() == name2)
00190 body2 = *it;
00191 it++;
00192 }
00193 if (body1 && body2)
00194 return new PMLInteractionForceField(SC, body1, body2, root);
00195 }
00196 if (type == "mapped"){
00197 std::string name1 = SC->getProperties()->getString("bodyRef");
00198 PMLBody * body1=NULL;
00199 std::vector<PMLBody*>::iterator it = bodiesList.begin();
00200 while( !body1 && it != bodiesList.end() )
00201 {
00202 if ( (*it)->getName() == name1)
00203 body1 = *it;
00204 it++;
00205 }
00206 if (body1){
00207 body1->parentNode->addChild(child);
00208 return new PMLMappedBody(SC, body1, child);
00209 }else
00210 cerr<<"mapped body : no body ref named "<<name1<<" found"<<endl;
00211 }
00212
00213 return NULL;
00214 }
00215
00216
00217 void PMLReader::processFusions(GNode * root)
00218 {
00219 std::vector<PMLBody *>::iterator it1 = bodiesList.begin();
00220 std::vector<PMLBody *>::iterator it2 = bodiesList.begin();
00221
00222 while (it1 != bodiesList.end()) {
00223 it2 = it1;
00224 it2++;
00225 while(it2 != bodiesList.end() ) {
00226 bool Fusion = false;
00227 if ((*it1)->isTypeOf() == (*it2)->isTypeOf() ) {
00228 map<unsigned int, unsigned int>::iterator ind = (*it1)->AtomsToDOFsIndexes.begin();
00229 while(ind != (*it1)->AtomsToDOFsIndexes.end() && !Fusion) {
00230 if((*it2)->AtomsToDOFsIndexes.find(ind->first) != (*it2)->AtomsToDOFsIndexes.end() ) {
00231 Fusion = (*it1)->FusionBody(*it2);
00232 if (Fusion) {
00233 std::vector<PMLBody *>::iterator tmp = it2;
00234 tmp--;
00235 (*it1)->parentNode->setName((*it1)->parentNode->getName() + " & "+ (*it2)->parentNode->getName() );
00236 root->removeChild( (*it2)->parentNode );
00237 bodiesList.erase(it2);
00238 it2 = tmp;
00239 }
00240 }
00241 ind++;
00242 }
00243 }
00244 it2++;
00245 }
00246 it1++;
00247 }
00248 }
00249
00250
00251
00252 void PMLReader::saveAsPML(const char * filename)
00253 {
00254 std::vector<PMLBody*>::iterator itb = bodiesList.begin();
00255 StructuralComponent * atoms = pm->getAtoms();
00256 Atom * atom;
00257
00258 while (itb != bodiesList.end())
00259 {
00260 std::map<unsigned int, unsigned int>::iterator itm = (*itb)->AtomsToDOFsIndexes.begin();
00261 while(itm != (*itb)->AtomsToDOFsIndexes.end() )
00262 {
00263 atom = (Atom*) atoms->getStructureByIndex( (*itm).first );
00264 Vector3 pos = (*itb)->getDOF((*itm).second);
00265 atom->setPosition(pos[0], pos[1], pos[2]);
00266
00267 itm++;
00268 }
00269 itb++;
00270 }
00271 std::ofstream outputFile(filename);
00272 pm->xmlPrint(outputFile);
00273 cout<<"fichier sauvegarde"<<endl;
00274 }
00275
00276
00277
00278 Vector3 PMLReader::getAtomPos(unsigned int atomindex)
00279 {
00280 Vector3 pos;
00281 std::vector<PMLBody*>::iterator itb = bodiesList.begin();
00282
00283 while (itb != bodiesList.end())
00284 {
00285 std::map<unsigned int, unsigned int>::iterator itm = (*itb)->AtomsToDOFsIndexes.begin();
00286 while(itm != (*itb)->AtomsToDOFsIndexes.end())
00287 {
00288 if ( (*itm).first == atomindex ) {
00289 pos = (*itb)->getDOF((*itm).second);
00290 return pos;
00291 }
00292 itm++;
00293 }
00294 itb++;
00295 }
00296 return Vector3();
00297 }
00298
00299
00300
00301 void PMLReader::updatePML()
00302 {
00303 std::vector<PMLBody*>::iterator itb = bodiesList.begin();
00304 StructuralComponent * atoms = pm->getAtoms();
00305 Atom * atom;
00306
00307 while (itb != bodiesList.end())
00308 {
00309 if( (*itb)->isTypeOf() != "interaction" )
00310 {
00311 if ((*itb)->isTypeOf() != "rigid" || ((PMLRigidBody*)*itb)->bodyFixed == false)
00312 {
00313 std::map<unsigned int, unsigned int>::iterator itm = (*itb)->AtomsToDOFsIndexes.begin();
00314 while(itm != (*itb)->AtomsToDOFsIndexes.end() )
00315 {
00316 atom = (Atom*) atoms->getStructureByIndex( (*itm).first );
00317 Vector3 pos = (*itb)->getDOF((*itm).second);
00318 atom->setPosition(pos[0], pos[1], pos[2]);
00319
00320 itm++;
00321 }
00322 }
00323 }
00324 itb++;
00325 }
00326 }
00327
00328
00329 }
00330 }
00331 }