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 #include <sofa/helper/io/MassSpringLoader.h>
00028 #include <sofa/helper/system/FileRepository.h>
00029 #include <sofa/defaulttype/Vec.h>
00030
00031 #include <stdio.h>
00032 #include <iostream>
00033 #include <vector>
00034 #include <string.h>
00035
00036 namespace sofa
00037 {
00038
00039 namespace helper
00040 {
00041
00042 namespace io
00043 {
00044
00045 using namespace sofa::defaulttype;
00046
00047 static void skipToEOL(FILE* f)
00048 {
00049 int ch;
00050 while ((ch = fgetc(f)) != EOF && ch != '\n') ;
00051 }
00052
00053 bool MassSpringLoader::load(const char *filename)
00054 {
00055 std::string fname = filename;
00056 if (!sofa::helper::system::DataRepository.findFile(fname)) return false;
00057
00058 char cmd[64];
00059 FILE* file;
00060
00061 if ((file = fopen(fname.c_str(), "r")) == NULL)
00062 {
00063 std::cout << "ERROR: cannot read file '" << filename << "'. Exiting..." << std::endl;
00064 return false;
00065 }
00066
00067 int totalNumMasses=0;
00068 int totalNumSprings=0;
00069
00070
00071
00072 if (fgets(cmd, 7, file) == NULL)
00073 {
00074 fclose(file);
00075 return false;
00076 }
00077
00078
00079 float version = 0.0;
00080 sscanf(cmd, "Xsp %f", &version);
00081
00082 bool vector_spring = false;
00083 if (version == 3.0) vector_spring = false;
00084 else if (version == 4.0) vector_spring = true;
00085 else {
00086 fclose(file);
00087 return false;
00088 }
00089
00090
00091 skipToEOL(file);
00092
00093
00094 if (fscanf(file, "%s", cmd) != EOF && !strcmp(cmd,"numm"))
00095 {
00096 fscanf(file, "%d", &totalNumMasses);
00097 setNumMasses(totalNumMasses);
00098 }
00099 if (fscanf(file, "%s", cmd) != EOF && !strcmp(cmd,"nums"))
00100 {
00101 fscanf(file, "%d", &totalNumSprings);
00102 setNumSprings(totalNumSprings);
00103 }
00104
00105
00106
00107 std::vector<Vector3> masses;
00108 if (totalNumMasses>0)
00109 masses.reserve(totalNumMasses);
00110
00111 while (fscanf(file, "%s", cmd) != EOF)
00112 {
00113 if (!strcmp(cmd,"mass"))
00114 {
00115 int index;
00116 char location;
00117 double px,py,pz,vx,vy,vz,mass=0.0,elastic=0.0;
00118 bool fixed=false;
00119 fscanf(file, "%d %c %lf %lf %lf %lf %lf %lf %lf %lf\n",
00120 &index, &location,
00121 &px, &py, &pz, &vx, &vy, &vz,
00122 &mass, &elastic);
00123 bool surface = (location == 's');
00124
00125 if (mass < 0)
00126 {
00127
00128 mass = -mass;
00129 fixed = true;
00130 }
00131 addMass((SReal)px,(SReal)py,(SReal)pz,(SReal)vx,(SReal)vy,(SReal)vz,(SReal)mass,(SReal)elastic,fixed,surface);
00132 masses.push_back(Vector3(px,py,pz));
00133 }
00134 else if (!strcmp(cmd,"lspg"))
00135 {
00136 int index;
00137 int m1,m2;
00138 double ks=0.0,kd=0.0,initpos=-1;
00139
00140 double restx=0.0,resty=0.0,restz=0.0;
00141 if (vector_spring)
00142 fscanf(file, "%d %d %d %lf %lf %lf %lf %lf %lf\n",
00143 &index,&m1,&m2,&ks,&kd,&initpos, &restx,&resty,&restz);
00144 else
00145 fscanf(file, "%d %d %d %lf %lf %lf\n",
00146 &index,&m1,&m2,&ks,&kd,&initpos);
00147 --m1;
00148 --m2;
00149 if (!masses.empty() && ((unsigned int)m1>=masses.size() || (unsigned int)m2>=masses.size()))
00150 {
00151 std::cerr << "ERROR: incorrect mass indexes in spring "<<index<<" "<<m1+1<<" "<<m2+1<<std::endl;
00152 }
00153 else
00154 {
00155 if (initpos==-1 && !masses.empty())
00156 {
00157 initpos = (masses[m1]-masses[m2]).norm();
00158 ks/=initpos;
00159 kd/=initpos;
00160
00161 }
00162
00163
00164 if (vector_spring)
00165 addVectorSpring(m1,m2,(SReal)ks,(SReal)kd,(SReal)initpos,(SReal)restx,(SReal)resty,(SReal)restz);
00166 else
00167 addSpring(m1,m2,(SReal)ks,(SReal)kd,(SReal)initpos);
00168 }
00169 }
00170 else if (!strcmp(cmd,"grav"))
00171 {
00172 double gx,gy,gz;
00173 fscanf(file, "%lf %lf %lf\n", &gx, &gy, &gz);
00174 setGravity((SReal)gx,(SReal)gy,(SReal)gz);
00175 }
00176 else if (!strcmp(cmd,"visc"))
00177 {
00178 double viscosity;
00179 fscanf(file, "%lf\n", &viscosity);
00180 setViscosity((SReal)viscosity);
00181 }
00182 else if (!strcmp(cmd,"step"))
00183 {
00184
00185 skipToEOL(file);
00186 }
00187 else if (!strcmp(cmd,"frce"))
00188 {
00189 skipToEOL(file);
00190 }
00191 else if (cmd[0] == '#')
00192 {
00193 skipToEOL(file);
00194 }
00195 else
00196 {
00197 printf("%s: Unknown MassSpring keyword: %s\n", filename, cmd);
00198 skipToEOL(file);
00199 }
00200 }
00201 fclose(file);
00202 return true;
00203 }
00204
00205 }
00206
00207 }
00208
00209 }
00210