TrianglePressureForceField.inl
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 #include <sofa/component/forcefield/TrianglePressureForceField.h>
00026 #include <sofa/component/topology/TriangleSubsetData.inl>
00027 #include <sofa/component/topology/TriangleSetGeometryAlgorithms.h>
00028 #include <sofa/helper/gl/template.h>
00029 #include <vector>
00030 #include <set>
00031
00032
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace forcefield
00041 {
00042
00043 using namespace sofa::defaulttype;
00044 using namespace core::componentmodel::topology;
00045
00046
00047 using std::cerr;
00048 using std::cout;
00049 using std::endl;
00050
00051 template <class DataTypes> TrianglePressureForceField<DataTypes>::~TrianglePressureForceField()
00052 {
00053 }
00054
00055 template <class DataTypes> void TrianglePressureForceField<DataTypes>::handleTopologyChange()
00056 {
00057 std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00058 std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00059
00060
00061 trianglePressureMap.handleTopologyEvents(itBegin,itEnd,_topology->getNbTriangles());
00062
00063 }
00064 template <class DataTypes> void TrianglePressureForceField<DataTypes>::init()
00065 {
00066
00067 this->core::componentmodel::behavior::ForceField<DataTypes>::init();
00068
00069 _topology = getContext()->getMeshTopology();
00070
00071 if (dmin.getValue()!=dmax.getValue()) {
00072 selectTrianglesAlongPlane();
00073 }
00074 if (triangleList.getValue().length()>0) {
00075 selectTrianglesFromString();
00076 }
00077
00078 initTriangleInformation();
00079
00080 }
00081
00082
00083 template <class DataTypes>
00084 void TrianglePressureForceField<DataTypes>::addForce(VecDeriv& f, const VecCoord& , const VecDeriv& )
00085 {
00086 Deriv force;
00087
00088 typename topology::TriangleSubsetData<TrianglePressureInformation>::iterator it;
00089
00090 for(it=trianglePressureMap.begin(); it!=trianglePressureMap.end(); it++ )
00091 {
00092 force=(*it).second.force/3;
00093 f[_topology->getTriangle((*it).first)[0]]+=force;
00094 f[_topology->getTriangle((*it).first)[1]]+=force;
00095 f[_topology->getTriangle((*it).first)[2]]+=force;
00096
00097 }
00098 }
00099
00100 template <class DataTypes>
00101 double TrianglePressureForceField<DataTypes>::getPotentialEnergy(const VecCoord& )
00102 {
00103 cerr<<"TrianglePressureForceField::getPotentialEnergy-not-implemented !!!"<<endl;
00104 return 0;
00105 }
00106
00107 template<class DataTypes>
00108 void TrianglePressureForceField<DataTypes>::initTriangleInformation()
00109 {
00110 sofa::component::topology::TriangleSetGeometryAlgorithms<DataTypes>* triangleGeo;
00111 this->getContext()->get(triangleGeo);
00112
00113 typename topology::TriangleSubsetData<TrianglePressureInformation>::iterator it;
00114
00115 for(it=trianglePressureMap.begin(); it!=trianglePressureMap.end(); it++ )
00116 {
00117 (*it).second.area=triangleGeo->computeRestTriangleArea((*it).first);
00118 (*it).second.force=pressure.getValue()*(*it).second.area;
00119 }
00120 }
00121
00122
00123 template<class DataTypes>
00124 void TrianglePressureForceField<DataTypes>::updateTriangleInformation()
00125 {
00126 typename topology::TriangleSubsetData<TrianglePressureInformation>::iterator it;
00127
00128 for(it=trianglePressureMap.begin(); it!=trianglePressureMap.end(); it++ )
00129 {
00130 (*it).second.force=((*it).second.area)*pressure.getValue();
00131 }
00132 }
00133
00134
00135 template <class DataTypes>
00136 void TrianglePressureForceField<DataTypes>::selectTrianglesAlongPlane()
00137 {
00138 const VecCoord& x = *this->mstate->getX0();
00139 std::vector<bool> vArray;
00140 unsigned int i;
00141
00142 vArray.resize(x.size());
00143
00144 for( i=0; i<x.size();++i)
00145 {
00146 vArray[i]=isPointInPlane(x[i]);
00147 }
00148
00149 for (int n=0;n<_topology->getNbTriangles();++n)
00150 {
00151 if ((vArray[_topology->getTriangle(n)[0]]) && (vArray[_topology->getTriangle(n)[1]])&& (vArray[_topology->getTriangle(n)[2]]) )
00152 {
00153
00154 TrianglePressureInformation t;
00155 trianglePressureMap[n]=t;
00156 }
00157 }
00158 }
00159
00160 template <class DataTypes>
00161 void TrianglePressureForceField<DataTypes>::selectTrianglesFromString()
00162 {
00163 std::string inputString=triangleList.getValue();
00164 unsigned int i;
00165 do {
00166 const char *str=inputString.c_str();
00167 for(i=0;(i<inputString.length())&&(str[i]!=',');++i) ;
00168 TrianglePressureInformation t;
00169
00170 if (i==inputString.length()) {
00171 trianglePressureMap[(unsigned int)atoi(str)]=t;
00172 inputString+=i;
00173 } else {
00174 inputString[i]='\0';
00175 trianglePressureMap[(unsigned int)atoi(str)]=t;
00176 inputString+=i+1;
00177 }
00178 } while (inputString.length()>0);
00179
00180 }
00181 template<class DataTypes>
00182 void TrianglePressureForceField<DataTypes>::draw()
00183 {
00184 if (!getContext()->getShowForceFields()) return;
00185 if (!this->mstate) return;
00186
00187 if (getContext()->getShowWireFrame())
00188 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00189
00190
00191 const VecCoord& x = *this->mstate->getX();
00192
00193 glDisable(GL_LIGHTING);
00194
00195 glBegin(GL_TRIANGLES);
00196 glColor4f(0,1,0,1);
00197
00198 typename topology::TriangleSubsetData<TrianglePressureInformation>::iterator it;
00199
00200 for(it=trianglePressureMap.begin(); it!=trianglePressureMap.end(); it++ )
00201 {
00202 helper::gl::glVertexT(x[_topology->getTriangle((*it).first)[0]]);
00203 helper::gl::glVertexT(x[_topology->getTriangle((*it).first)[1]]);
00204 helper::gl::glVertexT(x[_topology->getTriangle((*it).first)[2]]);
00205 }
00206 glEnd();
00207
00208
00209 if (getContext()->getShowWireFrame())
00210 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00211 }
00212
00213 }
00214
00215 }
00216
00217 }