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 #ifndef SOFA_COMPONENT_MAPPING_BARYCENTRICMAPPING_INL
00026 #define SOFA_COMPONENT_MAPPING_BARYCENTRICMAPPING_INL
00027
00028 #include <sofa/helper/system/config.h>
00029 #include <sofa/defaulttype/Mat.h>
00030 #include <sofa/component/mapping/BarycentricMapping.h>
00031 #include <sofa/core/componentmodel/behavior/MechanicalMapping.inl>
00032 #include <sofa/helper/gl/template.h>
00033 #include <algorithm>
00034 #include <iostream>
00035
00036 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00037 #include <sofa/component/topology/RegularGridTopology.h>
00038 #include <sofa/component/topology/SparseGridTopology.h>
00039
00040 #include <sofa/component/topology/EdgeSetTopologyContainer.h>
00041 #include <sofa/component/topology/TriangleSetTopologyContainer.h>
00042 #include <sofa/component/topology/QuadSetTopologyContainer.h>
00043 #include <sofa/component/topology/TetrahedronSetTopologyContainer.h>
00044 #include <sofa/component/topology/HexahedronSetTopologyContainer.h>
00045
00046 #include <sofa/component/topology/PointData.h>
00047 #include <sofa/component/topology/PointData.inl>
00048
00049 #include <sofa/component/topology/HexahedronData.h>
00050 #include <sofa/component/topology/HexahedronData.inl>
00051
00052 using std::cerr;
00053 using std::endl;
00054
00055 namespace sofa
00056 {
00057
00058 namespace component
00059 {
00060
00061 namespace mapping
00062 {
00063
00064 using namespace sofa::defaulttype;
00065
00066 template <class BasicMapping>
00067 BarycentricMapping<BasicMapping>::BarycentricMapping(In* from, Out* to, BaseMeshTopology * topology )
00068 : Inherit(from, to), mapper(NULL)
00069 {
00070 createMapperFromTopology(topology);
00071 }
00072
00073 template <class In, class Out>
00074 void BarycentricMapperRegularGridTopology<In,Out>::clear(int reserve)
00075 {
00076 map.clear();
00077 if (reserve>0) map.reserve(reserve);
00078 }
00079
00080 template <class In, class Out>
00081 int BarycentricMapperRegularGridTopology<In,Out>::addPointInCube(int cubeIndex, const SReal* baryCoords)
00082 {
00083 map.resize(map.size()+1);
00084 CubeData& data = *map.rbegin();
00085 data.in_index = cubeIndex;
00086 data.baryCoords[0] = (Real)baryCoords[0];
00087 data.baryCoords[1] = (Real)baryCoords[1];
00088 data.baryCoords[2] = (Real)baryCoords[2];
00089 return map.size()-1;
00090 }
00091
00092 template <class In, class Out>
00093 void BarycentricMapperRegularGridTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& )
00094 {
00095 if (map.size() != 0) return;
00096 int outside = 0;
00097 clear(out.size());
00098 for (unsigned int i=0;i<out.size();i++)
00099 {
00100 Vector3 coefs;
00101 int cube = topology->findCube(Vector3(out[i]), coefs[0], coefs[1], coefs[2]);
00102 if (cube==-1)
00103 {
00104 ++outside;
00105 cube = topology->findNearestCube(Vector3(out[i]), coefs[0], coefs[1], coefs[2]);
00106 }
00107 Vector3 baryCoords = coefs;
00108 addPointInCube(cube, baryCoords.ptr());
00109 }
00110 }
00111
00112 template <class In, class Out>
00113 void BarycentricMapperSparseGridTopology<In,Out>::clear(int reserve)
00114 {
00115 map.clear();
00116 if (reserve>0) map.reserve(reserve);
00117 }
00118
00119 template <class In, class Out>
00120 int BarycentricMapperSparseGridTopology<In,Out>::addPointInCube(int cubeIndex, const SReal* baryCoords)
00121 {
00122 map.resize(map.size()+1);
00123 CubeData& data = *map.rbegin();
00124 data.in_index = cubeIndex;
00125 data.baryCoords[0] = (Real)baryCoords[0];
00126 data.baryCoords[1] = (Real)baryCoords[1];
00127 data.baryCoords[2] = (Real)baryCoords[2];
00128 return map.size()-1;
00129 }
00130
00131 template <class In, class Out>
00132 void BarycentricMapperSparseGridTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& )
00133 {
00134 int outside = 0;
00135
00136 clear(out.size());
00137 for (unsigned int i=0;i<out.size();i++)
00138 {
00139 Vector3 coefs;
00140 int cube = topology->findCube(Vector3(out[i]), coefs[0], coefs[1], coefs[2]);
00141 if (cube==-1)
00142 {
00143 ++outside;
00144 cube = topology->findNearestCube(Vector3(out[i]), coefs[0], coefs[1], coefs[2]);
00145 }
00146 Vector3 baryCoords = coefs;
00147 addPointInCube(cube, baryCoords.ptr());
00148 }
00149 }
00150
00151 template <class In, class Out>
00152 void BarycentricMapperMeshTopology<In,Out>::clear1d(int reserve)
00153 {
00154 map1d.clear(); if (reserve>0) map1d.reserve(reserve);
00155 }
00156
00157 template <class In, class Out>
00158 void BarycentricMapperMeshTopology<In,Out>::clear2d(int reserve)
00159 {
00160 map2d.clear(); if (reserve>0) map2d.reserve(reserve);
00161 }
00162
00163 template <class In, class Out>
00164 void BarycentricMapperMeshTopology<In,Out>::clear3d(int reserve)
00165 {
00166 map3d.clear(); if (reserve>0) map3d.reserve(reserve);
00167 }
00168
00169 template <class In, class Out>
00170 void BarycentricMapperMeshTopology<In,Out>::clear(int reserve)
00171 {
00172 map1d.clear(); if (reserve>0) map1d.reserve(reserve);
00173 map2d.clear(); if (reserve>0) map2d.reserve(reserve);
00174 map3d.clear(); if (reserve>0) map3d.reserve(reserve);
00175 }
00176
00177 template <class In, class Out>
00178 int BarycentricMapperMeshTopology<In,Out>::addPointInLine(int lineIndex, const SReal* baryCoords)
00179 {
00180 map1d.resize(map1d.size()+1);
00181 MappingData1D& data = *map1d.rbegin();
00182 data.in_index = lineIndex;
00183 data.baryCoords[0] = (Real)baryCoords[0];
00184 return map1d.size()-1;
00185 }
00186
00187 template <class In, class Out>
00188 int BarycentricMapperMeshTopology<In,Out>::addPointInTriangle(int triangleIndex, const SReal* baryCoords)
00189 {
00190 map2d.resize(map2d.size()+1);
00191 MappingData2D& data = *map2d.rbegin();
00192 data.in_index = triangleIndex;
00193 data.baryCoords[0] = (Real)baryCoords[0];
00194 data.baryCoords[1] = (Real)baryCoords[1];
00195 return map2d.size()-1;
00196 }
00197
00198 template <class In, class Out>
00199 int BarycentricMapperMeshTopology<In,Out>::addPointInQuad(int quadIndex, const SReal* baryCoords)
00200 {
00201 map2d.resize(map2d.size()+1);
00202 MappingData2D& data = *map2d.rbegin();
00203 data.in_index = quadIndex + topology->getNbTriangles();
00204 data.baryCoords[0] = (Real)baryCoords[0];
00205 data.baryCoords[1] = (Real)baryCoords[1];
00206 return map2d.size()-1;
00207 }
00208
00209 template <class In, class Out>
00210 int BarycentricMapperMeshTopology<In,Out>::addPointInTetra(int tetraIndex, const SReal* baryCoords)
00211 {
00212 map3d.resize(map3d.size()+1);
00213 MappingData3D& data = *map3d.rbegin();
00214 data.in_index = tetraIndex;
00215 data.baryCoords[0] = (Real)baryCoords[0];
00216 data.baryCoords[1] = (Real)baryCoords[1];
00217 data.baryCoords[2] = (Real)baryCoords[2];
00218 return map3d.size()-1;
00219 }
00220
00221 template <class In, class Out>
00222 int BarycentricMapperMeshTopology<In,Out>::addPointInCube(int cubeIndex, const SReal* baryCoords)
00223 {
00224 map3d.resize(map3d.size()+1);
00225 MappingData3D& data = *map3d.rbegin();
00226 data.in_index = cubeIndex + topology->getNbTetras();
00227 data.baryCoords[0] = (Real)baryCoords[0];
00228 data.baryCoords[1] = (Real)baryCoords[1];
00229 data.baryCoords[2] = (Real)baryCoords[2];
00230 return map3d.size()-1;
00231 }
00232
00233 template <class In, class Out>
00234 int BarycentricMapperMeshTopology<In,Out>::createPointInLine(const typename Out::Coord& p, int lineIndex, const typename In::VecCoord* points)
00235 {
00236 SReal baryCoords[1];
00237 const sofa::core::componentmodel::topology::BaseMeshTopology::Line& elem = topology->getLine(lineIndex);
00238 const typename In::Coord p0 = (*points)[elem[0]];
00239 const typename In::Coord pA = (*points)[elem[1]] - p0;
00240 typename In::Coord pos = p - p0;
00241 baryCoords[0] = ((pos*pA)/pA.norm2());
00242 return this->addPointInLine(lineIndex, baryCoords);
00243 }
00244
00245 template <class In, class Out>
00246 int BarycentricMapperMeshTopology<In,Out>::createPointInTriangle(const typename Out::Coord& p, int triangleIndex, const typename In::VecCoord* points)
00247 {
00248 SReal baryCoords[2];
00249 const sofa::core::componentmodel::topology::BaseMeshTopology::Triangle& elem = topology->getTriangle(triangleIndex);
00250 const typename In::Coord p0 = (*points)[elem[0]];
00251 const typename In::Coord pA = (*points)[elem[1]] - p0;
00252 const typename In::Coord pB = (*points)[elem[2]] - p0;
00253 typename In::Coord pos = p - p0;
00254
00255 typename In::Coord normal = cross(pA, pB);
00256 Real norm2 = normal.norm2();
00257 pos -= normal*((pos*normal)/norm2);
00258 baryCoords[0] = (Real)sqrt(cross(pB, pos).norm2() / norm2);
00259 baryCoords[1] = (Real)sqrt(cross(pA, pos).norm2() / norm2);
00260 return this->addPointInTriangle(triangleIndex, baryCoords);
00261 }
00262
00263 template <class In, class Out>
00264 int BarycentricMapperMeshTopology<In,Out>::createPointInQuad(const typename Out::Coord& p, int quadIndex, const typename In::VecCoord* points)
00265 {
00266 SReal baryCoords[2];
00267 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& elem = topology->getQuad(quadIndex);
00268 const typename In::Coord p0 = (*points)[elem[0]];
00269 const typename In::Coord pA = (*points)[elem[1]] - p0;
00270 const typename In::Coord pB = (*points)[elem[3]] - p0;
00271 typename In::Coord pos = p - p0;
00272 Mat<3,3,typename In::Real> m,mt,base;
00273 m[0] = pA;
00274 m[1] = pB;
00275 m[2] = cross(pA, pB);
00276 mt.transpose(m);
00277 base.invert(mt);
00278 const typename In::Coord base0 = base[0];
00279 const typename In::Coord base1 = base[1];
00280 baryCoords[0] = base0 * pos;
00281 baryCoords[1] = base1 * pos;
00282 return this->addPointInQuad(quadIndex, baryCoords);
00283 }
00284
00285 template <class In, class Out>
00286 void BarycentricMapperMeshTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& in)
00287 {
00288 int outside = 0;
00289
00290 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTetras& tetras = topology->getTetras();
00291 #ifdef SOFA_NEW_HEXA
00292 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqHexas& cubes = topology->getHexas();
00293 #else
00294 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqCubes& cubes = topology->getCubes();
00295 #endif
00296 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles& triangles = topology->getTriangles();
00297 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqQuads& quads = topology->getQuads();
00298 sofa::helper::vector<Matrix3> bases;
00299 sofa::helper::vector<Vector3> centers;
00300 if (tetras.empty() && cubes.empty())
00301 {
00302 clear2d(out.size());
00303 int c0 = triangles.size();
00304 bases.resize(triangles.size()+quads.size());
00305 centers.resize(triangles.size()+quads.size());
00306 for (unsigned int t = 0; t < triangles.size(); t++)
00307 {
00308 Mat3x3d m,mt;
00309 m[0] = in[triangles[t][1]]-in[triangles[t][0]];
00310 m[1] = in[triangles[t][2]]-in[triangles[t][0]];
00311 m[2] = cross(m[0],m[1]);
00312 mt.transpose(m);
00313 bases[t].invert(mt);
00314 centers[t] = (in[triangles[t][0]]+in[triangles[t][1]]+in[triangles[t][2]])/3;
00315 }
00316 for (unsigned int c = 0; c < quads.size(); c++)
00317 {
00318 Mat3x3d m,mt;
00319 m[0] = in[quads[c][1]]-in[quads[c][0]];
00320 m[1] = in[quads[c][3]]-in[quads[c][0]];
00321 m[2] = cross(m[0],m[1]);
00322 mt.transpose(m);
00323 bases[c0+c].invert(mt);
00324 centers[c0+c] = (in[quads[c][0]]+in[quads[c][1]]+in[quads[c][2]]+in[quads[c][3]])*0.25;
00325 }
00326 for (unsigned int i=0;i<out.size();i++)
00327 {
00328 Vector3 pos = out[i];
00329 Vector3 coefs;
00330 int index = -1;
00331 double distance = 1e10;
00332 for (unsigned int t = 0; t < triangles.size(); t++)
00333 {
00334 Vec3d v = bases[t] * (pos - in[triangles[t][0]]);
00335 double d = std::max(std::max(-v[0],-v[1]),std::max((v[2]<0?-v[2]:v[2])-0.01,v[0]+v[1]-1));
00336 if (d>0) d = (pos-centers[t]).norm2();
00337 if (d<distance) { coefs = v; distance = d; index = t; }
00338 }
00339 for (unsigned int c = 0; c < quads.size(); c++)
00340 {
00341 Vec3d v = bases[c0+c] * (pos - in[quads[c][0]]);
00342 double d = std::max(std::max(-v[0],-v[1]),std::max(std::max(v[1]-1,v[0]-1),std::max(v[2]-0.01,-v[2]-0.01)));
00343 if (d>0) d = (pos-centers[c0+c]).norm2();
00344 if (d<distance) { coefs = v; distance = d; index = c0+c; }
00345 }
00346 if (distance>0)
00347 {
00348 ++outside;
00349 }
00350 if (index < c0)
00351 addPointInTriangle(index, coefs.ptr());
00352 else
00353 addPointInQuad(index-c0, coefs.ptr());
00354 }
00355 }
00356 else
00357 {
00358 clear3d(out.size());
00359 int c0 = tetras.size();
00360 bases.resize(tetras.size()+cubes.size());
00361 centers.resize(tetras.size()+cubes.size());
00362 for (unsigned int t = 0; t < tetras.size(); t++)
00363 {
00364 Mat3x3d m,mt;
00365 m[0] = in[tetras[t][1]]-in[tetras[t][0]];
00366 m[1] = in[tetras[t][2]]-in[tetras[t][0]];
00367 m[2] = in[tetras[t][3]]-in[tetras[t][0]];
00368 mt.transpose(m);
00369 bases[t].invert(mt);
00370 centers[t] = (in[tetras[t][0]]+in[tetras[t][1]]+in[tetras[t][2]]+in[tetras[t][3]])*0.25;
00371
00372 }
00373 for (unsigned int c = 0; c < cubes.size(); c++)
00374 {
00375 Mat3x3d m,mt;
00376 m[0] = in[cubes[c][1]]-in[cubes[c][0]];
00377 #ifdef SOFA_NEW_HEXA
00378 m[1] = in[cubes[c][3]]-in[cubes[c][0]];
00379 #else
00380 m[1] = in[cubes[c][2]]-in[cubes[c][0]];
00381 #endif
00382 m[2] = in[cubes[c][4]]-in[cubes[c][0]];
00383 mt.transpose(m);
00384 bases[c0+c].invert(mt);
00385 centers[c0+c] = (in[cubes[c][0]]+in[cubes[c][1]]+in[cubes[c][2]]+in[cubes[c][3]]+in[cubes[c][4]]+in[cubes[c][5]]+in[cubes[c][6]]+in[cubes[c][7]])*0.125;
00386 }
00387 for (unsigned int i=0;i<out.size();i++)
00388 {
00389 Vector3 pos = out[i];
00390 Vector3 coefs;
00391 int index = -1;
00392 double distance = 1e10;
00393 for (unsigned int t = 0; t < tetras.size(); t++)
00394 {
00395 Vector3 v = bases[t] * (pos - in[tetras[t][0]]);
00396 double d = std::max(std::max(-v[0],-v[1]),std::max(-v[2],v[0]+v[1]+v[2]-1));
00397 if (d>0) d = (pos-centers[t]).norm2();
00398 if (d<distance) { coefs = v; distance = d; index = t; }
00399 }
00400 for (unsigned int c = 0; c < cubes.size(); c++)
00401 {
00402 Vector3 v = bases[c0+c] * (pos - in[cubes[c][0]]);
00403 double d = std::max(std::max(-v[0],-v[1]),std::max(std::max(-v[2],v[0]-1),std::max(v[1]-1,v[2]-1)));
00404 if (d>0) d = (pos-centers[c0+c]).norm2();
00405 if (d<distance) { coefs = v; distance = d; index = c0+c; }
00406 }
00407 if (distance>0)
00408 {
00409 ++outside;
00410 }
00411 if (index < c0)
00412 addPointInTetra(index, coefs.ptr());
00413 else
00414 addPointInCube(index-c0, coefs.ptr());
00415 }
00416 }
00417 }
00418
00419
00420 template <class In, class Out>
00421 void BarycentricMapperEdgeSetTopology<In,Out>::clear(int reserve)
00422 {
00423 map.clear(); if (reserve>0) map.reserve(reserve);
00424 }
00425
00426
00427 template <class In, class Out>
00428 int BarycentricMapperEdgeSetTopology<In,Out>::addPointInLine(int edgeIndex, const SReal* baryCoords)
00429 {
00430 map.resize(map.size()+1);
00431 MappingData& data = *map.rbegin();
00432 data.in_index = edgeIndex;
00433 data.baryCoords[0] = (Real)baryCoords[0];
00434 return map.size()-1;
00435 }
00436
00437 template <class In, class Out>
00438 int BarycentricMapperEdgeSetTopology<In,Out>::createPointInLine(const typename Out::Coord& p, int edgeIndex, const typename In::VecCoord* points)
00439 {
00440 SReal baryCoords[1];
00441 const topology::Edge& elem = this->topology->getEdge(edgeIndex);
00442 const typename In::Coord p0 = (*points)[elem[0]];
00443 const typename In::Coord pA = (*points)[elem[1]] - p0;
00444 typename In::Coord pos = p - p0;
00445 baryCoords[0] = dot(pA,pos)/dot(pA,pA);
00446 return this->addPointInLine(edgeIndex, baryCoords);
00447 }
00448
00449 template <class In, class Out>
00450 void BarycentricMapperEdgeSetTopology<In,Out>::init(const typename Out::VecCoord& , const typename In::VecCoord& )
00451 {
00452
00453
00454
00455 }
00456
00457 template <class In, class Out>
00458 void BarycentricMapperTriangleSetTopology<In,Out>::clear(int reserve)
00459 {
00460 map.clear(); if (reserve>0) map.reserve(reserve);
00461 }
00462
00463 template <class In, class Out>
00464 int BarycentricMapperTriangleSetTopology<In,Out>::addPointInTriangle(int triangleIndex, const SReal* baryCoords)
00465 {
00466 map.resize(map.size()+1);
00467 MappingData& data = *map.rbegin();
00468 data.in_index = triangleIndex;
00469 data.baryCoords[0] = (Real)baryCoords[0];
00470 data.baryCoords[1] = (Real)baryCoords[1];
00471 return map.size()-1;
00472 }
00473
00474 template <class In, class Out>
00475 int BarycentricMapperTriangleSetTopology<In,Out>::createPointInTriangle(const typename Out::Coord& p, int triangleIndex, const typename In::VecCoord* points)
00476 {
00477 SReal baryCoords[2];
00478 const topology::Triangle& elem = this->topology->getTriangle(triangleIndex);
00479 const typename In::Coord p0 = (*points)[elem[0]];
00480 const typename In::Coord pA = (*points)[elem[1]] - p0;
00481 const typename In::Coord pB = (*points)[elem[2]] - p0;
00482 typename In::Coord pos = p - p0;
00483
00484 typename In::Coord normal = cross(pA, pB);
00485 Real norm2 = normal.norm2();
00486 pos -= normal*((pos*normal)/norm2);
00487 baryCoords[0] = (Real)sqrt(cross(pB, pos).norm2() / norm2);
00488 baryCoords[1] = (Real)sqrt(cross(pA, pos).norm2() / norm2);
00489 return this->addPointInTriangle(triangleIndex, baryCoords);
00490 }
00491
00492 template <class In, class Out>
00493 void BarycentricMapperTriangleSetTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& in)
00494 {
00495 int outside = 0;
00496
00497 const sofa::helper::vector<topology::Triangle>& triangles = this->topology->getTriangles();
00498 sofa::helper::vector<Mat3x3d> bases;
00499 sofa::helper::vector<Vector3> centers;
00500
00501
00502 clear(out.size());
00503 bases.resize(triangles.size());
00504 centers.resize(triangles.size());
00505
00506 for (unsigned int t = 0; t < triangles.size(); t++)
00507 {
00508 Mat3x3d m,mt;
00509 m[0] = in[triangles[t][1]]-in[triangles[t][0]];
00510 m[1] = in[triangles[t][2]]-in[triangles[t][0]];
00511 m[2] = cross(m[0],m[1]);
00512 mt.transpose(m);
00513 bases[t].invert(mt);
00514 centers[t] = (in[triangles[t][0]]+in[triangles[t][1]]+in[triangles[t][2]])/3;
00515 }
00516
00517 for (unsigned int i=0;i<out.size();i++)
00518 {
00519 Vec3d pos = out[i];
00520 Vector3 coefs;
00521 int index = -1;
00522 double distance = 1e10;
00523 for (unsigned int t = 0; t < triangles.size(); t++)
00524 {
00525 Vec3d v = bases[t] * (pos - in[triangles[t][0]]);
00526 double d = std::max(std::max(-v[0],-v[1]),std::max((v[2]<0?-v[2]:v[2])-0.01,v[0]+v[1]-1));
00527 if (d>0) d = (pos-centers[t]).norm2();
00528 if (d<distance) { coefs = v; distance = d; index = t; }
00529 }
00530 if (distance>0)
00531 {
00532 ++outside;
00533 }
00534 addPointInTriangle(index, coefs.ptr());
00535 }
00536 }
00537
00538 template <class In, class Out>
00539 void BarycentricMapperQuadSetTopology<In,Out>::clear(int reserve)
00540 {
00541 map.clear(); if (reserve>0) map.reserve(reserve);
00542 }
00543
00544 template <class In, class Out>
00545 int BarycentricMapperQuadSetTopology<In,Out>::addPointInQuad(int quadIndex, const SReal* baryCoords)
00546 {
00547 map.resize(map.size()+1);
00548 MappingData& data = *map.rbegin();
00549 data.in_index = quadIndex + topology->getNbTriangles();
00550 data.baryCoords[0] = (Real)baryCoords[0];
00551 data.baryCoords[1] = (Real)baryCoords[1];
00552 return map.size()-1;
00553 }
00554
00555 template <class In, class Out>
00556 int BarycentricMapperQuadSetTopology<In,Out>::createPointInQuad(const typename Out::Coord& p, int quadIndex, const typename In::VecCoord* points)
00557 {
00558 SReal baryCoords[2];
00559 const topology::Quad& elem = this->topology->getQuad(quadIndex);
00560 const typename In::Coord p0 = (*points)[elem[0]];
00561 const typename In::Coord pA = (*points)[elem[1]] - p0;
00562 const typename In::Coord pB = (*points)[elem[3]] - p0;
00563 typename In::Coord pos = p - p0;
00564 Mat<3,3,typename In::Real> m,mt,base;
00565 m[0] = pA;
00566 m[1] = pB;
00567 m[2] = cross(pA, pB);
00568 mt.transpose(m);
00569 base.invert(mt);
00570 const typename In::Coord base0 = base[0];
00571 const typename In::Coord base1 = base[1];
00572 baryCoords[0] = base0 * pos;
00573 baryCoords[1] = base1 * pos;
00574 return this->addPointInQuad(quadIndex, baryCoords);
00575 }
00576
00577 template <class In, class Out>
00578 void BarycentricMapperQuadSetTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& in)
00579 {
00580 int outside = 0;
00581 const sofa::helper::vector<topology::Quad>& quads = this->topology->getQuads();
00582
00583 sofa::helper::vector<Matrix3> bases;
00584 sofa::helper::vector<Vector3> centers;
00585
00586 clear(out.size());
00587 bases.resize(quads.size());
00588 centers.resize(quads.size());
00589
00590 for (unsigned int c = 0; c < quads.size(); c++)
00591 {
00592 Mat3x3d m,mt;
00593 m[0] = in[quads[c][1]]-in[quads[c][0]];
00594 m[1] = in[quads[c][3]]-in[quads[c][0]];
00595 m[2] = cross(m[0],m[1]);
00596 mt.transpose(m);
00597 bases[c].invert(mt);
00598 centers[c] = (in[quads[c][0]]+in[quads[c][1]]+in[quads[c][2]]+in[quads[c][3]])*0.25;
00599 }
00600
00601 for (unsigned int i=0;i<out.size();i++)
00602 {
00603 Vec3d pos = out[i];
00604 Vector3 coefs;
00605 int index = -1;
00606 double distance = 1e10;
00607 for (unsigned int c = 0; c < quads.size(); c++)
00608 {
00609 Vec3d v = bases[c] * (pos - in[quads[c][0]]);
00610 double d = std::max(std::max(-v[0],-v[1]),std::max(std::max(v[1]-1,v[0]-1),std::max(v[2]-0.01,-v[2]-0.01)));
00611 if (d>0) d = (pos-centers[c]).norm2();
00612 if (d<distance) { coefs = v; distance = d; index = c; }
00613 }
00614 if (distance>0)
00615 {
00616 ++outside;
00617 }
00618 addPointInQuad(index, coefs.ptr());
00619 }
00620 }
00621
00622 template <class In, class Out>
00623 void BarycentricMapperTetrahedronSetTopology<In,Out>::clear(int reserve)
00624 {
00625 map.clear(); if (reserve>0) map.reserve(reserve);
00626 }
00627
00628 template <class In, class Out>
00629 int BarycentricMapperTetrahedronSetTopology<In,Out>::addPointInTetra(int tetraIndex, const SReal* baryCoords)
00630 {
00631 map.resize(map.size()+1);
00632 MappingData& data = *map.rbegin();
00633 data.in_index = tetraIndex;
00634 data.baryCoords[0] = (Real)baryCoords[0];
00635 data.baryCoords[1] = (Real)baryCoords[1];
00636 data.baryCoords[2] = (Real)baryCoords[2];
00637 return map.size()-1;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646 template <class In, class Out>
00647 void BarycentricMapperTetrahedronSetTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& in)
00648 {
00649 int outside = 0;
00650 const sofa::helper::vector<topology::Tetrahedron>& tetras = this->topology->getTetras();
00651
00652 sofa::helper::vector<Matrix3> bases;
00653 sofa::helper::vector<Vector3> centers;
00654
00655 clear(out.size());
00656 bases.resize(tetras.size());
00657 centers.resize(tetras.size());
00658 for (unsigned int t = 0; t < tetras.size(); t++)
00659 {
00660 Mat3x3d m,mt;
00661 m[0] = in[tetras[t][1]]-in[tetras[t][0]];
00662 m[1] = in[tetras[t][2]]-in[tetras[t][0]];
00663 m[2] = in[tetras[t][3]]-in[tetras[t][0]];
00664 mt.transpose(m);
00665 bases[t].invert(mt);
00666 centers[t] = (in[tetras[t][0]]+in[tetras[t][1]]+in[tetras[t][2]]+in[tetras[t][3]])*0.25;
00667 }
00668
00669 for (unsigned int i=0;i<out.size();i++)
00670 {
00671 Vec3d pos = out[i];
00672 Vector3 coefs;
00673 int index = -1;
00674 double distance = 1e10;
00675 for (unsigned int t = 0; t < tetras.size(); t++)
00676 {
00677 Vec3d v = bases[t] * (pos - in[tetras[t][0]]);
00678 double d = std::max(std::max(-v[0],-v[1]),std::max(-v[2],v[0]+v[1]+v[2]-1));
00679 if (d>0) d = (pos-centers[t]).norm2();
00680 if (d<distance) { coefs = v; distance = d; index = t; }
00681 }
00682 if (distance>0)
00683 {
00684 ++outside;
00685 }
00686 addPointInTetra(index, coefs.ptr());
00687 }
00688 }
00689
00690 template <class In, class Out>
00691 void BarycentricMapperHexahedronSetTopology<In,Out>::clear(int reserve)
00692 {
00693 map.clear(); if (reserve>0) map.reserve(reserve);
00694 hexahedronData.clear();
00695 }
00696
00697 template <class In, class Out>
00698 int BarycentricMapperHexahedronSetTopology<In,Out>::addPointInCube(int cubeIndex, const SReal* baryCoords)
00699 {
00700 map.resize(map.size()+1);
00701 MappingData& data = *map.rbegin();
00702 data.in_index = cubeIndex + topology->getNbTetras();
00703 data.baryCoords[0] = (Real)baryCoords[0];
00704 data.baryCoords[1] = (Real)baryCoords[1];
00705 data.baryCoords[2] = (Real)baryCoords[2];
00706 return map.size()-1;
00707 }
00708
00709 template <class In, class Out>
00710 void BarycentricMapperHexahedronSetTopology<In,Out>::init(const typename Out::VecCoord& out, const typename In::VecCoord& in)
00711 {
00712 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
00713
00714 clear(out.size());
00715
00716 hexahedronData.resize(cubes.size());
00717
00718 for (unsigned int c = 0; c < cubes.size(); c++)
00719 {
00720 Mat3x3d m,mt;
00721 const Vector3 origin = in[cubes[c][0]];
00722 m[0] = in[cubes[c][1]]-origin;
00723 m[1] = in[cubes[c][3]]-origin;
00724 m[2] = in[cubes[c][4]]-origin;
00725 mt.transpose(m);
00726 hexahedronData[c].origin = origin;
00727 hexahedronData[c].base.invert(mt);
00728 hexahedronData[c].center = (in[cubes[c][0]]+in[cubes[c][1]]+in[cubes[c][2]]+in[cubes[c][3]]
00729 +in[cubes[c][4]]+in[cubes[c][5]]+in[cubes[c][6]]+in[cubes[c][7]])*0.125;
00730 }
00731
00732 for (unsigned int i=0;i<out.size();i++)
00733 {
00734
00735 Vector3 coefs;
00736 int index=-1;
00737 double distance = 1e10;
00738 Vector3 pos = out[i];
00739 for (unsigned int c = 0; c < cubes.size(); c++)
00740 {
00741 const Vec3d v = hexahedronData[c].base * (pos - hexahedronData[c].origin);
00742 double d = std::max(std::max(-v[0],-v[1]), std::max(std::max(-v[2],v[0]-1), std::max(v[1]-1,v[2]-1)));
00743 if (d>0)
00744 d = (pos-hexahedronData[c].center).norm2();
00745 if (d<distance)
00746 {
00747 coefs = v;
00748 distance = d;
00749 index = c;
00750 }
00751 }
00752 if(index != -1)
00753 addPointInCube(index, coefs.ptr());
00754 }
00755 }
00756
00757 template <class BasicMapping>
00758 void BarycentricMapping<BasicMapping>::createMapperFromTopology(BaseMeshTopology * topology)
00759 {
00760 mapper = NULL;
00761
00762 core::componentmodel::topology::TopologyContainer* topoCont2;
00763 this->fromModel->getContext()->get(topoCont2);
00764
00765 if (topoCont2!=NULL)
00766 {
00767
00768 topology::HexahedronSetTopologyContainer* t1 = dynamic_cast<topology::HexahedronSetTopologyContainer*>(topoCont2);
00769 if(t1 != NULL)
00770 {
00771 typedef BarycentricMapperHexahedronSetTopology<InDataTypes, OutDataTypes> HexahedronSetMapper;
00772 mapper = new HexahedronSetMapper(topology_from);
00773 }
00774 else
00775 {
00776 topology::TetrahedronSetTopologyContainer* t2 = dynamic_cast<topology::TetrahedronSetTopologyContainer*>(topoCont2);
00777 if(t2 != NULL)
00778 {
00779 typedef BarycentricMapperTetrahedronSetTopology<InDataTypes, OutDataTypes> TetrahedronSetMapper;
00780 mapper = new TetrahedronSetMapper(topology_from);
00781 }
00782 else
00783 {
00784 topology::QuadSetTopologyContainer* t3 = dynamic_cast<topology::QuadSetTopologyContainer*>(topoCont2);
00785 if(t3 != NULL)
00786 {
00787 typedef BarycentricMapperQuadSetTopology<InDataTypes, OutDataTypes> QuadSetMapper;
00788 mapper = new QuadSetMapper(topology_from);
00789 }
00790 else
00791 {
00792 topology::TriangleSetTopologyContainer* t4 = dynamic_cast<topology::TriangleSetTopologyContainer*>(topoCont2);
00793 if (t4 != NULL)
00794 {
00795 typedef BarycentricMapperTriangleSetTopology<InDataTypes, OutDataTypes> TriangleSetMapper;
00796 mapper = new TriangleSetMapper(topology_from);
00797 }
00798 else
00799 {
00800 topology::EdgeSetTopologyContainer* t5 = dynamic_cast<topology::EdgeSetTopologyContainer*>(topoCont2);
00801 if(t5 != NULL)
00802 {
00803 typedef BarycentricMapperEdgeSetTopology<InDataTypes, OutDataTypes> EdgeSetMapper;
00804 mapper = new EdgeSetMapper(topology_from);
00805 }
00806 }
00807 }
00808 }
00809 }
00810 }
00811 else
00812 {
00813 topology::RegularGridTopology* t2 = dynamic_cast<topology::RegularGridTopology*>(topology);
00814 if (t2!=NULL)
00815 {
00816 typedef BarycentricMapperRegularGridTopology<InDataTypes, OutDataTypes> RegularGridMapper;
00817 if (f_grid->beginEdit()->isEmpty())
00818 {
00819 f_grid->setValue(RegularGridMapper(t2));
00820 mapper = f_grid->beginEdit();
00821 }
00822 else
00823 {
00824 f_grid->beginEdit()->setTopology(t2);
00825 this->mapper = f_grid->beginEdit();
00826 }
00827 }
00828 else
00829 {
00830 topology::SparseGridTopology* t4 = dynamic_cast<topology::SparseGridTopology*>(topology);
00831 if (t4!=NULL)
00832 {
00833 typedef BarycentricMapperSparseGridTopology<InDataTypes, OutDataTypes> SparseGridMapper;
00834 mapper = new SparseGridMapper(t4);
00835 }
00836 else
00837 {
00838 typedef BarycentricMapperMeshTopology<InDataTypes, OutDataTypes> MeshMapper;
00839 topology::BaseMeshTopology* t3 = dynamic_cast<topology::BaseMeshTopology*>(topology);
00840 mapper = new MeshMapper(t3);
00841 }
00842 }
00843 }
00844 }
00845
00846 template <class BasicMapping>
00847 void BarycentricMapping<BasicMapping>::init()
00848 {
00849 topology_from = this->fromModel->getContext()->getMeshTopology();
00850 topology_to = this->toModel->getContext()->getMeshTopology();
00851
00852 f_grid->beginEdit();
00853 if(mapper == NULL)
00854 {
00855 if (topology_from!=NULL)
00856 {
00857 createMapperFromTopology(topology_from);
00858 }
00859 }
00860
00861 if (mapper != NULL)
00862 {
00863 mapper->init(*this->toModel->getX(), *this->fromModel->getX());
00864 }
00865 else
00866 {
00867 std::cerr << "ERROR: Barycentric mapping does not understand topology."<<std::endl;
00868 }
00869
00870 this->BasicMapping::init();
00871
00872 }
00873
00874 template <class BasicMapping>
00875 void BarycentricMapping<BasicMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00876 {
00877 if (mapper!=NULL) mapper->apply(out, in);
00878 }
00879
00880 template <class In, class Out>
00881 void BarycentricMapperRegularGridTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00882 {
00883 out.resize(map.size());
00884 for(unsigned int i=0;i<map.size();i++)
00885 {
00886 #ifdef SOFA_NEW_HEXA
00887 const topology::RegularGridTopology::Hexa cube = this->topology->getHexaCopy(this->map[i].in_index);
00888 #else
00889 const topology::RegularGridTopology::Cube cube = this->topology->getCubeCopy(this->map[i].in_index);
00890 #endif
00891 const Real fx = map[i].baryCoords[0];
00892 const Real fy = map[i].baryCoords[1];
00893 const Real fz = map[i].baryCoords[2];
00894 out[i] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
00895 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
00896 #ifdef SOFA_NEW_HEXA
00897 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
00898 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
00899 #else
00900 + in[cube[2]] * ((1-fx) * ( fy) * (1-fz))
00901 + in[cube[3]] * (( fx) * ( fy) * (1-fz))
00902 #endif
00903 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
00904 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
00905 #ifdef SOFA_NEW_HEXA
00906 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
00907 + in[cube[6]] * (( fx) * ( fy) * ( fz));
00908 #else
00909 + in[cube[6]] * ((1-fx) * ( fy) * ( fz))
00910 + in[cube[7]] * (( fx) * ( fy) * ( fz));
00911 #endif
00912 }
00913 }
00914
00915 template <class In, class Out>
00916 void BarycentricMapperSparseGridTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00917 {
00918 out.resize(map.size());
00919 for(unsigned int i=0;i<map.size();i++)
00920 {
00921 #ifdef SOFA_NEW_HEXA
00922 const topology::SparseGridTopology::Hexa cube = this->topology->getHexa(this->map[i].in_index);
00923 #else
00924 const topology::SparseGridTopology::Cube cube = this->topology->getCube(this->map[i].in_index);
00925 #endif
00926 const Real fx = map[i].baryCoords[0];
00927 const Real fy = map[i].baryCoords[1];
00928 const Real fz = map[i].baryCoords[2];
00929 out[i] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
00930 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
00931 #ifdef SOFA_NEW_HEXA
00932 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
00933 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
00934 #else
00935 + in[cube[2]] * ((1-fx) * ( fy) * (1-fz))
00936 + in[cube[3]] * (( fx) * ( fy) * (1-fz))
00937 #endif
00938 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
00939 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
00940 #ifdef SOFA_NEW_HEXA
00941 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
00942 + in[cube[6]] * (( fx) * ( fy) * ( fz));
00943 #else
00944 + in[cube[6]] * ((1-fx) * ( fy) * ( fz))
00945 + in[cube[7]] * (( fx) * ( fy) * ( fz));
00946 #endif
00947 }
00948 }
00949
00950 template <class In, class Out>
00951 void BarycentricMapperMeshTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
00952 {
00953 out.resize(map1d.size()+map2d.size()+map3d.size());
00954 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqLines& lines = this->topology->getLines();
00955 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles& triangles = this->topology->getTriangles();
00956 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqQuads& quads = this->topology->getQuads();
00957 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTetras& tetras = this->topology->getTetras();
00958 #ifdef SOFA_NEW_HEXA
00959 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqHexas& cubes = this->topology->getHexas();
00960 #else
00961 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqCubes& cubes = this->topology->getCubes();
00962 #endif
00963
00964 {
00965 for(unsigned int i=0;i<map1d.size();i++)
00966 {
00967 const Real fx = map1d[i].baryCoords[0];
00968 int index = map1d[i].in_index;
00969 {
00970 const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = lines[index];
00971 out[i] = in[line[0]] * (1-fx)
00972 + in[line[1]] * fx;
00973 }
00974 }
00975 }
00976
00977 {
00978 const int i0 = map1d.size();
00979 const int c0 = triangles.size();
00980 for(unsigned int i=0;i<map2d.size();i++)
00981 {
00982 const Real fx = map2d[i].baryCoords[0];
00983 const Real fy = map2d[i].baryCoords[1];
00984 int index = map2d[i].in_index;
00985 if (index<c0)
00986 {
00987 const sofa::core::componentmodel::topology::BaseMeshTopology::Triangle& triangle = triangles[index];
00988 out[i+i0] = in[triangle[0]] * (1-fx-fy)
00989 + in[triangle[1]] * fx
00990 + in[triangle[2]] * fy;
00991 }
00992 else
00993 {
00994 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& quad = quads[index-c0];
00995 out[i+i0] = in[quad[0]] * ((1-fx) * (1-fy))
00996 + in[quad[1]] * (( fx) * (1-fy))
00997 + in[quad[3]] * ((1-fx) * ( fy))
00998 + in[quad[2]] * (( fx) * ( fy));
00999 }
01000 }
01001 }
01002
01003 {
01004 const int i0 = map1d.size() + map2d.size();
01005 const int c0 = tetras.size();
01006 for(unsigned int i=0;i<map3d.size();i++)
01007 {
01008 const Real fx = map3d[i].baryCoords[0];
01009 const Real fy = map3d[i].baryCoords[1];
01010 const Real fz = map3d[i].baryCoords[2];
01011 int index = map3d[i].in_index;
01012 if (index<c0)
01013 {
01014 const sofa::core::componentmodel::topology::BaseMeshTopology::Tetra& tetra = tetras[index];
01015 out[i+i0] = in[tetra[0]] * (1-fx-fy-fz)
01016 + in[tetra[1]] * fx
01017 + in[tetra[2]] * fy
01018 + in[tetra[3]] * fz;
01019 }
01020 else
01021 {
01022 #ifdef SOFA_NEW_HEXA
01023 const sofa::core::componentmodel::topology::BaseMeshTopology::Hexa& cube = cubes[index-c0];
01024 #else
01025 const sofa::core::componentmodel::topology::BaseMeshTopology::Cube& cube = cubes[index-c0];
01026 #endif
01027 out[i+i0] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
01028 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
01029 #ifdef SOFA_NEW_HEXA
01030 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
01031 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
01032 #else
01033 + in[cube[2]] * ((1-fx) * ( fy) * (1-fz))
01034 + in[cube[3]] * (( fx) * ( fy) * (1-fz))
01035 #endif
01036 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
01037 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
01038 #ifdef SOFA_NEW_HEXA
01039 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
01040 + in[cube[6]] * (( fx) * ( fy) * ( fz));
01041 #else
01042 + in[cube[6]] * ((1-fx) * ( fy) * ( fz))
01043 + in[cube[7]] * (( fx) * ( fy) * ( fz));
01044 #endif
01045 }
01046 }
01047 }
01048 }
01049
01050 template <class In, class Out>
01051 void BarycentricMapperEdgeSetTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
01052 {
01053 out.resize(map.size());
01054 const sofa::helper::vector<topology::Edge>& edges = this->topology->getEdges();
01055
01056 for(unsigned int i=0;i<map.size();i++)
01057 {
01058 const Real fx = map[i].baryCoords[0];
01059 int index = map[i].in_index;
01060 const topology::Edge& edge = edges[index];
01061 out[i] = in[edge[0]] * (1-fx)
01062 + in[edge[1]] * fx;
01063 }
01064 }
01065
01066 template <class In, class Out>
01067 void BarycentricMapperTriangleSetTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
01068 {
01069 out.resize(map.size());
01070 const sofa::helper::vector<topology::Triangle>& triangles = this->topology->getTriangles();
01071 for(unsigned int i=0;i<map.size();i++)
01072 {
01073 const Real fx = map[i].baryCoords[0];
01074 const Real fy = map[i].baryCoords[1];
01075 int index = map[i].in_index;
01076 const topology::Triangle& triangle = triangles[index];
01077 out[i] = in[triangle[0]] * (1-fx-fy)
01078 + in[triangle[1]] * fx
01079 + in[triangle[2]] * fy;
01080 }
01081 }
01082
01083 template <class In, class Out>
01084 void BarycentricMapperQuadSetTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
01085 {
01086 out.resize(map.size());
01087 const sofa::helper::vector<topology::Quad>& quads = this->topology->getQuads();
01088 for(unsigned int i=0;i<map.size();i++)
01089 {
01090 const Real fx = map[i].baryCoords[0];
01091 const Real fy = map[i].baryCoords[1];
01092 int index = map[i].in_index;
01093 const topology::Quad& quad = quads[index];
01094 out[i] = in[quad[0]] * ((1-fx) * (1-fy))
01095 + in[quad[1]] * (( fx) * (1-fy))
01096 + in[quad[3]] * ((1-fx) * ( fy))
01097 + in[quad[2]] * (( fx) * ( fy));
01098 }
01099 }
01100
01101 template <class In, class Out>
01102 void BarycentricMapperTetrahedronSetTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
01103 {
01104 out.resize(map.size());
01105 const sofa::helper::vector<topology::Tetrahedron>& tetras = this->topology->getTetras();
01106 for(unsigned int i=0;i<map.size();i++)
01107 {
01108 const Real fx = map[i].baryCoords[0];
01109 const Real fy = map[i].baryCoords[1];
01110 const Real fz = map[i].baryCoords[2];
01111 int index = map[i].in_index;
01112 const topology::Tetrahedron& tetra = tetras[index];
01113 out[i] = in[tetra[0]] * (1-fx-fy-fz)
01114 + in[tetra[1]] * fx
01115 + in[tetra[2]] * fy
01116 + in[tetra[3]] * fz;
01117 }
01118
01119
01120 }
01121
01122 template <class In, class Out>
01123 void BarycentricMapperHexahedronSetTopology<In,Out>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
01124 {
01125 out.resize(map.size());
01126 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
01127 for(unsigned int i=0;i<map.size();i++)
01128 {
01129 const Real fx = map[i].baryCoords[0];
01130 const Real fy = map[i].baryCoords[1];
01131 const Real fz = map[i].baryCoords[2];
01132 int index = map[i].in_index;
01133 const topology::Hexahedron& cube = cubes[index];
01134 out[i] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
01135 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
01136 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
01137 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
01138 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
01139 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
01140 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
01141 + in[cube[6]] * (( fx) * ( fy) * ( fz));
01142 }
01143 }
01144
01145 template <class BasicMapping>
01146 void BarycentricMapping<BasicMapping>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01147 {
01148 out.resize(this->toModel->getX()->size());
01149 if (mapper!=NULL) mapper->applyJ(out, in);
01150 }
01151
01152 template <class In, class Out>
01153 void BarycentricMapperRegularGridTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01154 {
01155 for(unsigned int i=0;i<map.size();i++)
01156 {
01157 #ifdef SOFA_NEW_HEXA
01158 const topology::RegularGridTopology::Hexa cube = this->topology->getHexaCopy(this->map[i].in_index);
01159 #else
01160 const topology::RegularGridTopology::Cube cube = this->topology->getCubeCopy(this->map[i].in_index);
01161 #endif
01162 const Real fx = map[i].baryCoords[0];
01163 const Real fy = map[i].baryCoords[1];
01164 const Real fz = map[i].baryCoords[2];
01165 out[i] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
01166 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
01167 #ifdef SOFA_NEW_HEXA
01168 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
01169 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
01170 #else
01171 + in[cube[2]] * ((1-fx) * ( fy) * (1-fz))
01172 + in[cube[3]] * (( fx) * ( fy) * (1-fz))
01173 #endif
01174 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
01175 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
01176 #ifdef SOFA_NEW_HEXA
01177 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
01178 + in[cube[6]] * (( fx) * ( fy) * ( fz));
01179 #else
01180 + in[cube[6]] * ((1-fx) * ( fy) * ( fz))
01181 + in[cube[7]] * (( fx) * ( fy) * ( fz));
01182 #endif
01183 }
01184 }
01185
01186 template <class In, class Out>
01187 void BarycentricMapperSparseGridTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01188 {
01189 for(unsigned int i=0;i<map.size();i++)
01190 {
01191 #ifdef SOFA_NEW_HEXA
01192 const topology::SparseGridTopology::Hexa cube = this->topology->getHexa(this->map[i].in_index);
01193 #else
01194 const topology::SparseGridTopology::Cube cube = this->topology->getCube(this->map[i].in_index);
01195 #endif
01196 const Real fx = map[i].baryCoords[0];
01197 const Real fy = map[i].baryCoords[1];
01198 const Real fz = map[i].baryCoords[2];
01199 out[i] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
01200 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
01201 #ifdef SOFA_NEW_HEXA
01202 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
01203 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
01204 #else
01205 + in[cube[2]] * ((1-fx) * ( fy) * (1-fz))
01206 + in[cube[3]] * (( fx) * ( fy) * (1-fz))
01207 #endif
01208 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
01209 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
01210 #ifdef SOFA_NEW_HEXA
01211 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
01212 + in[cube[6]] * (( fx) * ( fy) * ( fz));
01213 #else
01214 + in[cube[6]] * ((1-fx) * ( fy) * ( fz))
01215 + in[cube[7]] * (( fx) * ( fy) * ( fz));
01216 #endif
01217 }
01218 }
01219
01220 template <class In, class Out>
01221 void BarycentricMapperMeshTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01222 {
01223
01224 out.resize(map1d.size()+map2d.size()+map3d.size());
01225 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqLines& lines = this->topology->getLines();
01226 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles& triangles = this->topology->getTriangles();
01227 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqQuads& quads = this->topology->getQuads();
01228 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTetras& tetras = this->topology->getTetras();
01229 #ifdef SOFA_NEW_HEXA
01230 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqHexas& cubes = this->topology->getHexas();
01231 #else
01232 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqCubes& cubes = this->topology->getCubes();
01233 #endif
01234
01235 {
01236 for(unsigned int i=0;i<map1d.size();i++)
01237 {
01238 const Real fx = map1d[i].baryCoords[0];
01239 int index = map1d[i].in_index;
01240 {
01241 const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = lines[index];
01242 out[i] = in[line[0]] * (1-fx)
01243 + in[line[1]] * fx;
01244 }
01245 }
01246 }
01247
01248 {
01249 const int i0 = map1d.size();
01250 const int c0 = triangles.size();
01251 for(unsigned int i=0;i<map2d.size();i++)
01252 {
01253 const Real fx = map2d[i].baryCoords[0];
01254 const Real fy = map2d[i].baryCoords[1];
01255 int index = map2d[i].in_index;
01256 if (index<c0)
01257 {
01258 const sofa::core::componentmodel::topology::BaseMeshTopology::Triangle& triangle = triangles[index];
01259 out[i+i0] = in[triangle[0]] * (1-fx-fy)
01260 + in[triangle[1]] * fx
01261 + in[triangle[2]] * fy;
01262 }
01263 else
01264 {
01265 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& quad = quads[index-c0];
01266 out[i+i0] = in[quad[0]] * ((1-fx) * (1-fy))
01267 + in[quad[1]] * (( fx) * (1-fy))
01268 + in[quad[3]] * ((1-fx) * ( fy))
01269 + in[quad[2]] * (( fx) * ( fy));
01270 }
01271 }
01272 }
01273
01274 {
01275 const int i0 = map1d.size() + map2d.size();
01276 const int c0 = tetras.size();
01277 for(unsigned int i=0;i<map3d.size();i++)
01278 {
01279 const Real fx = map3d[i].baryCoords[0];
01280 const Real fy = map3d[i].baryCoords[1];
01281 const Real fz = map3d[i].baryCoords[2];
01282 int index = map3d[i].in_index;
01283 if (index<c0)
01284 {
01285 const sofa::core::componentmodel::topology::BaseMeshTopology::Tetra& tetra = tetras[index];
01286 out[i+i0] = in[tetra[0]] * (1-fx-fy-fz)
01287 + in[tetra[1]] * fx
01288 + in[tetra[2]] * fy
01289 + in[tetra[3]] * fz;
01290 }
01291 else
01292 {
01293 #ifdef SOFA_NEW_HEXA
01294 const sofa::core::componentmodel::topology::BaseMeshTopology::Hexa& cube = cubes[index-c0];
01295 #else
01296 const sofa::core::componentmodel::topology::BaseMeshTopology::Cube& cube = cubes[index-c0];
01297 #endif
01298 out[i+i0] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
01299 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
01300 #ifdef SOFA_NEW_HEXA
01301 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
01302 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
01303 #else
01304 + in[cube[2]] * ((1-fx) * ( fy) * (1-fz))
01305 + in[cube[3]] * (( fx) * ( fy) * (1-fz))
01306 #endif
01307 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
01308 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
01309 #ifdef SOFA_NEW_HEXA
01310 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
01311 + in[cube[6]] * (( fx) * ( fy) * ( fz));
01312 #else
01313 + in[cube[6]] * ((1-fx) * ( fy) * ( fz))
01314 + in[cube[7]] * (( fx) * ( fy) * ( fz));
01315 #endif
01316 }
01317 }
01318 }
01319 }
01320
01321 template <class In, class Out>
01322 void BarycentricMapperEdgeSetTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01323 {
01324 out.resize(map.size());
01325 const sofa::helper::vector<topology::Edge>& edges = this->topology->getEdges();
01326 for(unsigned int i=0;i<map.size();i++)
01327 {
01328 const Real fx = map[i].baryCoords[0];
01329 int index = map[i].in_index;
01330 const topology::Edge& edge = edges[index];
01331 out[i] = in[edge[0]] * (1-fx)
01332 + in[edge[1]] * fx;
01333 }
01334 }
01335
01336 template <class In, class Out>
01337 void BarycentricMapperTriangleSetTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01338 {
01339 out.resize(map.size());
01340 const sofa::helper::vector<topology::Triangle>& triangles = this->topology->getTriangles();
01341 for(unsigned int i=0;i<map.size();i++)
01342 {
01343 const Real fx = map[i].baryCoords[0];
01344 const Real fy = map[i].baryCoords[1];
01345 int index = map[i].in_index;
01346 const topology::Triangle& triangle = triangles[index];
01347 out[i] = in[triangle[0]] * (1-fx-fy)
01348 + in[triangle[1]] * fx
01349 + in[triangle[2]] * fy;
01350 }
01351 }
01352
01353 template <class In, class Out>
01354 void BarycentricMapperQuadSetTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01355 {
01356 out.resize(map.size());
01357 const sofa::helper::vector<topology::Quad>& quads = this->topology->getQuads();
01358 for(unsigned int i=0;i<map.size();i++)
01359 {
01360 const Real fx = map[i].baryCoords[0];
01361 const Real fy = map[i].baryCoords[1];
01362 int index = map[i].in_index;
01363 const topology::Quad& quad = quads[index];
01364 out[i] = in[quad[0]] * ((1-fx) * (1-fy))
01365 + in[quad[1]] * (( fx) * (1-fy))
01366 + in[quad[3]] * ((1-fx) * ( fy))
01367 + in[quad[2]] * (( fx) * ( fy));
01368 }
01369 }
01370
01371 template <class In, class Out>
01372 void BarycentricMapperTetrahedronSetTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01373 {
01374 out.resize(map.size());
01375 const sofa::helper::vector<topology::Tetrahedron>& tetras = this->topology->getTetras();
01376 for(unsigned int i=0;i<map.size();i++)
01377 {
01378 const Real fx = map[i].baryCoords[0];
01379 const Real fy = map[i].baryCoords[1];
01380 const Real fz = map[i].baryCoords[2];
01381 int index = map[i].in_index;
01382 const topology::Tetrahedron& tetra = tetras[index];
01383 out[i] = in[tetra[0]] * (1-fx-fy-fz)
01384 + in[tetra[1]] * fx
01385 + in[tetra[2]] * fy
01386 + in[tetra[3]] * fz;
01387 }
01388 }
01389
01390 template <class In, class Out>
01391 void BarycentricMapperHexahedronSetTopology<In,Out>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
01392 { out.resize(map.size());
01393 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
01394 for(unsigned int i=0;i<map.size();i++)
01395 {
01396 const Real fx = map[i].baryCoords[0];
01397 const Real fy = map[i].baryCoords[1];
01398 const Real fz = map[i].baryCoords[2];
01399 int index = map[i].in_index;
01400 const topology::Hexahedron& cube = cubes[index];
01401 out[i] = in[cube[0]] * ((1-fx) * (1-fy) * (1-fz))
01402 + in[cube[1]] * (( fx) * (1-fy) * (1-fz))
01403 + in[cube[3]] * ((1-fx) * ( fy) * (1-fz))
01404 + in[cube[2]] * (( fx) * ( fy) * (1-fz))
01405 + in[cube[4]] * ((1-fx) * (1-fy) * ( fz))
01406 + in[cube[5]] * (( fx) * (1-fy) * ( fz))
01407 + in[cube[7]] * ((1-fx) * ( fy) * ( fz))
01408 + in[cube[6]] * (( fx) * ( fy) * ( fz));
01409 }
01410 }
01411
01412 template <class BasicMapping>
01413 void BarycentricMapping<BasicMapping>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01414 {
01415 if (mapper!=NULL) mapper->applyJT(out, in);
01416 }
01417
01418 template <class In, class Out>
01419 void BarycentricMapperRegularGridTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01420 {
01421 for(unsigned int i=0;i<map.size();i++)
01422 {
01423 const typename Out::Deriv v = in[i];
01424 #ifdef SOFA_NEW_HEXA
01425 const topology::RegularGridTopology::Hexa cube = this->topology->getHexaCopy(this->map[i].in_index);
01426 #else
01427 const topology::RegularGridTopology::Cube cube = this->topology->getCubeCopy(this->map[i].in_index);
01428 #endif
01429 const OutReal fx = (OutReal)map[i].baryCoords[0];
01430 const OutReal fy = (OutReal)map[i].baryCoords[1];
01431 const OutReal fz = (OutReal)map[i].baryCoords[2];
01432 out[cube[0]] += v * ((1-fx) * (1-fy) * (1-fz));
01433 out[cube[1]] += v * (( fx) * (1-fy) * (1-fz));
01434 #ifdef SOFA_NEW_HEXA
01435 out[cube[3]] += v * ((1-fx) * ( fy) * (1-fz));
01436 out[cube[2]] += v * (( fx) * ( fy) * (1-fz));
01437 #else
01438 out[cube[2]] += v * ((1-fx) * ( fy) * (1-fz));
01439 out[cube[3]] += v * (( fx) * ( fy) * (1-fz));
01440 #endif
01441 out[cube[4]] += v * ((1-fx) * (1-fy) * ( fz));
01442 out[cube[5]] += v * (( fx) * (1-fy) * ( fz));
01443 #ifdef SOFA_NEW_HEXA
01444 out[cube[7]] += v * ((1-fx) * ( fy) * ( fz));
01445 out[cube[6]] += v * (( fx) * ( fy) * ( fz));
01446 #else
01447 out[cube[6]] += v * ((1-fx) * ( fy) * ( fz));
01448 out[cube[7]] += v * (( fx) * ( fy) * ( fz));
01449 #endif
01450 }
01451 }
01452
01453 template <class In, class Out>
01454 void BarycentricMapperSparseGridTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01455 {
01456 for(unsigned int i=0;i<map.size();i++)
01457 {
01458 const typename Out::Deriv v = in[i];
01459 #ifdef SOFA_NEW_HEXA
01460 const topology::SparseGridTopology::Hexa cube = this->topology->getHexa(this->map[i].in_index);
01461 #else
01462 const topology::SparseGridTopology::Cube cube = this->topology->getCube(this->map[i].in_index);
01463 #endif
01464 const OutReal fx = (OutReal)map[i].baryCoords[0];
01465 const OutReal fy = (OutReal)map[i].baryCoords[1];
01466 const OutReal fz = (OutReal)map[i].baryCoords[2];
01467 out[cube[0]] += v * ((1-fx) * (1-fy) * (1-fz));
01468 out[cube[1]] += v * (( fx) * (1-fy) * (1-fz));
01469 #ifdef SOFA_NEW_HEXA
01470 out[cube[3]] += v * ((1-fx) * ( fy) * (1-fz));
01471 out[cube[2]] += v * (( fx) * ( fy) * (1-fz));
01472 #else
01473 out[cube[2]] += v * ((1-fx) * ( fy) * (1-fz));
01474 out[cube[3]] += v * (( fx) * ( fy) * (1-fz));
01475 #endif
01476 out[cube[4]] += v * ((1-fx) * (1-fy) * ( fz));
01477 out[cube[5]] += v * (( fx) * (1-fy) * ( fz));
01478 #ifdef SOFA_NEW_HEXA
01479 out[cube[7]] += v * ((1-fx) * ( fy) * ( fz));
01480 out[cube[6]] += v * (( fx) * ( fy) * ( fz));
01481 #else
01482 out[cube[6]] += v * ((1-fx) * ( fy) * ( fz));
01483 out[cube[7]] += v * (( fx) * ( fy) * ( fz));
01484 #endif
01485 }
01486 }
01487
01488 template <class In, class Out>
01489 void BarycentricMapperMeshTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01490 {
01491 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqLines& lines = this->topology->getLines();
01492 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles& triangles = this->topology->getTriangles();
01493 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqQuads& quads = this->topology->getQuads();
01494 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTetras& tetras = this->topology->getTetras();
01495 #ifdef SOFA_NEW_HEXA
01496 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqHexas& cubes = this->topology->getHexas();
01497 #else
01498 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqCubes& cubes = this->topology->getCubes();
01499 #endif
01500
01501 {
01502 for(unsigned int i=0;i<map1d.size();i++)
01503 {
01504 const typename Out::Deriv v = in[i];
01505 const OutReal fx = (OutReal)map1d[i].baryCoords[0];
01506 int index = map1d[i].in_index;
01507 {
01508 const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = lines[index];
01509 out[line[0]] += v * (1-fx);
01510 out[line[1]] += v * fx;
01511 }
01512 }
01513 }
01514
01515 {
01516 const int i0 = map1d.size();
01517 const int c0 = triangles.size();
01518 for(unsigned int i=0;i<map2d.size();i++)
01519 {
01520 const typename Out::Deriv v = in[i+i0];
01521 const OutReal fx = (OutReal)map2d[i].baryCoords[0];
01522 const OutReal fy = (OutReal)map2d[i].baryCoords[1];
01523 int index = map2d[i].in_index;
01524 if (index<c0)
01525 {
01526 const sofa::core::componentmodel::topology::BaseMeshTopology::Triangle& triangle = triangles[index];
01527 out[triangle[0]] += v * (1-fx-fy);
01528 out[triangle[1]] += v * fx;
01529 out[triangle[2]] += v * fy;
01530 }
01531 else
01532 {
01533 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& quad = quads[index-c0];
01534 out[quad[0]] += v * ((1-fx) * (1-fy));
01535 out[quad[1]] += v * (( fx) * (1-fy));
01536 out[quad[3]] += v * ((1-fx) * ( fy));
01537 out[quad[2]] += v * (( fx) * ( fy));
01538 }
01539 }
01540 }
01541
01542 {
01543 const int i0 = map1d.size() + map2d.size();
01544 const int c0 = tetras.size();
01545 for(unsigned int i=0;i<map3d.size();i++)
01546 {
01547 const typename Out::Deriv v = in[i+i0];
01548 const OutReal fx = (OutReal)map3d[i].baryCoords[0];
01549 const OutReal fy = (OutReal)map3d[i].baryCoords[1];
01550 const OutReal fz = (OutReal)map3d[i].baryCoords[2];
01551 int index = map3d[i].in_index;
01552 if (index<c0)
01553 {
01554 const sofa::core::componentmodel::topology::BaseMeshTopology::Tetra& tetra = tetras[index];
01555 out[tetra[0]] += v * (1-fx-fy-fz);
01556 out[tetra[1]] += v * fx;
01557 out[tetra[2]] += v * fy;
01558 out[tetra[3]] += v * fz;
01559 }
01560 else
01561 {
01562 #ifdef SOFA_NEW_HEXA
01563 const sofa::core::componentmodel::topology::BaseMeshTopology::Hexa& cube = cubes[index-c0];
01564 #else
01565 const sofa::core::componentmodel::topology::BaseMeshTopology::Cube& cube = cubes[index-c0];
01566 #endif
01567 out[cube[0]] += v * ((1-fx) * (1-fy) * (1-fz));
01568 out[cube[1]] += v * (( fx) * (1-fy) * (1-fz));
01569 #ifdef SOFA_NEW_HEXA
01570 out[cube[3]] += v * ((1-fx) * ( fy) * (1-fz));
01571 out[cube[2]] += v * (( fx) * ( fy) * (1-fz));
01572 #else
01573 out[cube[2]] += v * ((1-fx) * ( fy) * (1-fz));
01574 out[cube[3]] += v * (( fx) * ( fy) * (1-fz));
01575 #endif
01576 out[cube[4]] += v * ((1-fx) * (1-fy) * ( fz));
01577 out[cube[5]] += v * (( fx) * (1-fy) * ( fz));
01578 #ifdef SOFA_NEW_HEXA
01579 out[cube[7]] += v * ((1-fx) * ( fy) * ( fz));
01580 out[cube[6]] += v * (( fx) * ( fy) * ( fz));
01581 #else
01582 out[cube[6]] += v * ((1-fx) * ( fy) * ( fz));
01583 out[cube[7]] += v * (( fx) * ( fy) * ( fz));
01584 #endif
01585 }
01586 }
01587 }
01588 }
01589
01590 template <class In, class Out>
01591 void BarycentricMapperEdgeSetTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01592 {
01593 const sofa::helper::vector<topology::Edge>& edges = this->topology->getEdges();
01594 for(unsigned int i=0;i<map.size();i++)
01595 {
01596 const typename Out::Deriv v = in[i];
01597 const OutReal fx = (OutReal)map[i].baryCoords[0];
01598 int index = map[i].in_index;
01599 const topology::Edge& edge = edges[index];
01600 out[edge[0]] += v * (1-fx);
01601 out[edge[1]] += v * fx;
01602 }
01603 }
01604
01605 template <class In, class Out>
01606 void BarycentricMapperTriangleSetTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01607 {
01608 const sofa::helper::vector<topology::Triangle>& triangles = this->topology->getTriangles();
01609 for(unsigned int i=0;i<map.size();i++)
01610 {
01611 const typename Out::Deriv v = in[i];
01612 const OutReal fx = (OutReal)map[i].baryCoords[0];
01613 const OutReal fy = (OutReal)map[i].baryCoords[1];
01614 int index = map[i].in_index;
01615 const topology::Triangle& triangle = triangles[index];
01616 out[triangle[0]] += v * (1-fx-fy);
01617 out[triangle[1]] += v * fx;
01618 out[triangle[2]] += v * fy;
01619 }
01620 }
01621
01622 template <class In, class Out>
01623 void BarycentricMapperQuadSetTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01624 {
01625 const sofa::helper::vector<topology::Quad>& quads = this->topology->getQuads();
01626 for(unsigned int i=0;i<map.size();i++)
01627 {
01628 const typename Out::Deriv v = in[i];
01629 const OutReal fx = (OutReal)map[i].baryCoords[0];
01630 const OutReal fy = (OutReal)map[i].baryCoords[1];
01631 int index = map[i].in_index;
01632 const topology::Quad& quad = quads[index];
01633 out[quad[0]] += v * ((1-fx) * (1-fy));
01634 out[quad[1]] += v * (( fx) * (1-fy));
01635 out[quad[3]] += v * ((1-fx) * ( fy));
01636 out[quad[2]] += v * (( fx) * ( fy));
01637 }
01638 }
01639
01640 template <class In, class Out>
01641 void BarycentricMapperTetrahedronSetTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01642 {
01643 const sofa::helper::vector<topology::Tetrahedron>& tetras = this->topology->getTetras();
01644 for(unsigned int i=0;i<map.size();i++)
01645 {
01646 const typename Out::Deriv v = in[i];
01647 const OutReal fx = (OutReal)map[i].baryCoords[0];
01648 const OutReal fy = (OutReal)map[i].baryCoords[1];
01649 const OutReal fz = (OutReal)map[i].baryCoords[2];
01650 int index = map[i].in_index;
01651 const topology::Tetrahedron& tetra = tetras[index];
01652 out[tetra[0]] += v * (1-fx-fy-fz);
01653 out[tetra[1]] += v * fx;
01654 out[tetra[2]] += v * fy;
01655 out[tetra[3]] += v * fz;
01656 }
01657 }
01658
01659 template <class In, class Out>
01660 void BarycentricMapperHexahedronSetTopology<In,Out>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
01661 {
01662 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
01663 for(unsigned int i=0;i<map.size();i++)
01664 {
01665 const typename Out::Deriv v = in[i];
01666 const OutReal fx = (OutReal)map[i].baryCoords[0];
01667 const OutReal fy = (OutReal)map[i].baryCoords[1];
01668 const OutReal fz = (OutReal)map[i].baryCoords[2];
01669 int index = map[i].in_index;
01670 const topology::Hexahedron& cube = cubes[index];
01671 out[cube[0]] += v * ((1-fx) * (1-fy) * (1-fz));
01672 out[cube[1]] += v * (( fx) * (1-fy) * (1-fz));
01673 out[cube[3]] += v * ((1-fx) * ( fy) * (1-fz));
01674 out[cube[2]] += v * (( fx) * ( fy) * (1-fz));
01675 out[cube[4]] += v * ((1-fx) * (1-fy) * ( fz));
01676 out[cube[5]] += v * (( fx) * (1-fy) * ( fz));
01677 out[cube[7]] += v * ((1-fx) * ( fy) * ( fz));
01678 out[cube[6]] += v * (( fx) * ( fy) * ( fz));
01679 }
01680 }
01681
01682 template <class BasicMapping>
01683 void BarycentricMapping<BasicMapping>::draw()
01684 {
01685 if (!this->getShow()) return;
01686 glDisable (GL_LIGHTING);
01687 glPointSize(7);
01688 glColor4f (1,1,0,1);
01689 const OutVecCoord& out = *this->toModel->getX();
01690 glBegin (GL_POINTS);
01691 for (unsigned int i=0; i<out.size(); i++)
01692 {
01693 helper::gl::glVertexT(out[i]);
01694 }
01695 glEnd();
01696 const InVecCoord& in = *this->fromModel->getX();
01697 if (mapper!=NULL) mapper->draw(out, in);
01698 glPointSize(1);
01699 }
01700
01701 template <class In, class Out>
01702 void BarycentricMapperRegularGridTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
01703 {
01704 glBegin (GL_LINES);
01705 for (unsigned int i=0; i<map.size(); i++)
01706 {
01707 #ifdef SOFA_NEW_HEXA
01708 const topology::RegularGridTopology::Hexa cube = this->topology->getHexaCopy(this->map[i].in_index);
01709 #else
01710 const topology::RegularGridTopology::Cube cube = this->topology->getCubeCopy(this->map[i].in_index);
01711 #endif
01712 const Real fx = map[i].baryCoords[0];
01713 const Real fy = map[i].baryCoords[1];
01714 const Real fz = map[i].baryCoords[2];
01715 Real f[8];
01716 f[0] = (1-fx) * (1-fy) * (1-fz);
01717 f[1] = ( fx) * (1-fy) * (1-fz);
01718 #ifdef SOFA_NEW_HEXA
01719 f[3] = (1-fx) * ( fy) * (1-fz);
01720 f[2] = ( fx) * ( fy) * (1-fz);
01721 #else
01722 f[2] = (1-fx) * ( fy) * (1-fz);
01723 f[3] = ( fx) * ( fy) * (1-fz);
01724 #endif
01725 f[4] = (1-fx) * (1-fy) * ( fz);
01726 f[5] = ( fx) * (1-fy) * ( fz);
01727 #ifdef SOFA_NEW_HEXA
01728 f[7] = (1-fx) * ( fy) * ( fz);
01729 f[6] = ( fx) * ( fy) * ( fz);
01730 #else
01731 f[6] = (1-fx) * ( fy) * ( fz);
01732 f[7] = ( fx) * ( fy) * ( fz);
01733 #endif
01734 for (int j=0;j<8;j++)
01735 {
01736 if (f[j]<=-0.0001 || f[j]>=0.0001)
01737 {
01738 glColor3f((float)f[j],(float)f[j],1);
01739 helper::gl::glVertexT(out[i]);
01740 helper::gl::glVertexT(in[cube[j]]);
01741 }
01742 }
01743 }
01744 glEnd();
01745 }
01746
01747 template <class In, class Out>
01748 void BarycentricMapperSparseGridTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
01749 {
01750 glBegin (GL_LINES);
01751 for (unsigned int i=0; i<map.size(); i++)
01752 {
01753 #ifdef SOFA_NEW_HEXA
01754 const topology::SparseGridTopology::Hexa cube = this->topology->getHexa(this->map[i].in_index);
01755 #else
01756 const topology::SparseGridTopology::Cube cube = this->topology->getCube(this->map[i].in_index);
01757 #endif
01758 const Real fx = map[i].baryCoords[0];
01759 const Real fy = map[i].baryCoords[1];
01760 const Real fz = map[i].baryCoords[2];
01761 Real f[8];
01762 f[0] = (1-fx) * (1-fy) * (1-fz);
01763 f[1] = ( fx) * (1-fy) * (1-fz);
01764 #ifdef SOFA_NEW_HEXA
01765 f[3] = (1-fx) * ( fy) * (1-fz);
01766 f[2] = ( fx) * ( fy) * (1-fz);
01767 #else
01768 f[2] = (1-fx) * ( fy) * (1-fz);
01769 f[3] = ( fx) * ( fy) * (1-fz);
01770 #endif
01771 f[4] = (1-fx) * (1-fy) * ( fz);
01772 f[5] = ( fx) * (1-fy) * ( fz);
01773 #ifdef SOFA_NEW_HEXA
01774 f[7] = (1-fx) * ( fy) * ( fz);
01775 f[6] = ( fx) * ( fy) * ( fz);
01776 #else
01777 f[6] = (1-fx) * ( fy) * ( fz);
01778 f[7] = ( fx) * ( fy) * ( fz);
01779 #endif
01780 for (int j=0;j<8;j++)
01781 {
01782 if (f[j]<=-0.0001 || f[j]>=0.0001)
01783 {
01784 glColor3f((float)f[j],(float)f[j],1);
01785 helper::gl::glVertexT(out[i]);
01786 helper::gl::glVertexT(in[cube[j]]);
01787 }
01788 }
01789 }
01790 glEnd();
01791 }
01792
01793 template <class In, class Out>
01794 void BarycentricMapperMeshTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
01795 {
01796 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqLines& lines = this->topology->getLines();
01797 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles& triangles = this->topology->getTriangles();
01798 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqQuads& quads = this->topology->getQuads();
01799 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTetras& tetras = this->topology->getTetras();
01800 #ifdef SOFA_NEW_HEXA
01801 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqHexas& cubes = this->topology->getHexas();
01802 #else
01803 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqCubes& cubes = this->topology->getCubes();
01804 #endif
01805 glBegin (GL_LINES);
01806
01807 {
01808 const int i0 = 0;
01809 for(unsigned int i=0;i<map1d.size();i++)
01810 {
01811 const Real fx = map1d[i].baryCoords[0];
01812 int index = map1d[i].in_index;
01813 {
01814 const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = lines[index];
01815 Real f[2];
01816 f[0] = (1-fx);
01817 f[1] = fx;
01818 for (int j=0;j<2;j++)
01819 {
01820 if (f[j]<=-0.0001 || f[j]>=0.0001)
01821 {
01822 glColor3f((float)f[j],1,(float)f[j]);
01823 helper::gl::glVertexT(out[i+i0]);
01824 helper::gl::glVertexT(in[line[j]]);
01825 }
01826 }
01827 }
01828 }
01829 }
01830
01831 {
01832 const int i0 = map1d.size();
01833 const int c0 = triangles.size();
01834 for(unsigned int i=0;i<map2d.size();i++)
01835 {
01836 const Real fx = map2d[i].baryCoords[0];
01837 const Real fy = map2d[i].baryCoords[1];
01838 int index = map2d[i].in_index;
01839 if (index<c0)
01840 {
01841 const sofa::core::componentmodel::topology::BaseMeshTopology::Triangle& triangle = triangles[index];
01842 Real f[3];
01843 f[0] = (1-fx-fy);
01844 f[1] = fx;
01845 f[2] = fy;
01846 for (int j=0;j<3;j++)
01847 {
01848 if (f[j]<=-0.0001 || f[j]>=0.0001)
01849 {
01850 glColor3f((float)f[j],1,(float)f[j]);
01851 helper::gl::glVertexT(out[i+i0]);
01852 helper::gl::glVertexT(in[triangle[j]]);
01853 }
01854 }
01855 }
01856 else
01857 {
01858 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& quad = quads[index-c0];
01859 Real f[4];
01860 f[0] = ((1-fx) * (1-fy));
01861 f[1] = (( fx) * (1-fy));
01862 f[3] = ((1-fx) * ( fy));
01863 f[2] = (( fx) * ( fy));
01864 for (int j=0;j<4;j++)
01865 {
01866 if (f[j]<=-0.0001 || f[j]>=0.0001)
01867 {
01868 glColor3f((float)f[j],1,(float)f[j]);
01869 helper::gl::glVertexT(out[i+i0]);
01870 helper::gl::glVertexT(in[quad[j]]);
01871 }
01872 }
01873 }
01874 }
01875 }
01876
01877 {
01878 const int i0 = map1d.size()+map2d.size();
01879 const int c0 = tetras.size();
01880 for (unsigned int i=0; i<map3d.size(); i++)
01881 {
01882 const Real fx = map3d[i].baryCoords[0];
01883 const Real fy = map3d[i].baryCoords[1];
01884 const Real fz = map3d[i].baryCoords[2];
01885 int index = map3d[i].in_index;
01886 if (index<c0)
01887 {
01888 const sofa::core::componentmodel::topology::BaseMeshTopology::Tetra& tetra = tetras[index];
01889 Real f[4];
01890 f[0] = (1-fx-fy-fz);
01891 f[1] = fx;
01892 f[2] = fy;
01893 f[3] = fz;
01894 for (int j=0;j<4;j++)
01895 {
01896 if (f[j]<=-0.0001 || f[j]>=0.0001)
01897 {
01898 glColor3f((float)f[j],1,(float)f[j]);
01899 helper::gl::glVertexT(out[i+i0]);
01900 helper::gl::glVertexT(in[tetra[j]]);
01901 }
01902 }
01903 }
01904 else
01905 {
01906 #ifdef SOFA_NEW_HEXA
01907 const sofa::core::componentmodel::topology::BaseMeshTopology::Hexa& cube = cubes[index-c0];
01908 #else
01909 const sofa::core::componentmodel::topology::BaseMeshTopology::Cube& cube = cubes[index-c0];
01910 #endif
01911 Real f[8];
01912 f[0] = (1-fx) * (1-fy) * (1-fz);
01913 f[1] = ( fx) * (1-fy) * (1-fz);
01914 #ifdef SOFA_NEW_HEXA
01915 f[3] = (1-fx) * ( fy) * (1-fz);
01916 f[2] = ( fx) * ( fy) * (1-fz);
01917 #else
01918 f[2] = (1-fx) * ( fy) * (1-fz);
01919 f[3] = ( fx) * ( fy) * (1-fz);
01920 #endif
01921 f[4] = (1-fx) * (1-fy) * ( fz);
01922 f[5] = ( fx) * (1-fy) * ( fz);
01923 #ifdef SOFA_NEW_HEXA
01924 f[7] = (1-fx) * ( fy) * ( fz);
01925 f[6] = ( fx) * ( fy) * ( fz);
01926 #else
01927 f[6] = (1-fx) * ( fy) * ( fz);
01928 f[7] = ( fx) * ( fy) * ( fz);
01929 #endif
01930 for (int j=0;j<8;j++)
01931 {
01932 if (f[j]<=-0.0001 || f[j]>=0.0001)
01933 {
01934 glColor3f((float)f[j],1,1);
01935 helper::gl::glVertexT(out[i+i0]);
01936 helper::gl::glVertexT(in[cube[j]]);
01937 }
01938 }
01939 }
01940 }
01941 }
01942 glEnd();
01943 }
01944
01945
01946 template <class In, class Out>
01947 void BarycentricMapperEdgeSetTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
01948 {
01949 const sofa::helper::vector<topology::Edge>& edges = this->topology->getEdges();
01950
01951 glBegin (GL_LINES);
01952 {
01953 for(unsigned int i=0;i<map.size();i++)
01954 {
01955 const Real fx = map[i].baryCoords[0];
01956 int index = map[i].in_index;
01957 const topology::Edge& edge = edges[index];
01958 {
01959 const Real f = Real(1.0)-fx;
01960 if (f<=-0.0001 || f>=0.0001)
01961 {
01962 glColor3f((float)f,1,(float)f);
01963 helper::gl::glVertexT(out[i]);
01964 helper::gl::glVertexT(in[edge[0]]);
01965 }
01966 }
01967 {
01968 const Real f = fx;
01969 if (f<=-0.0001 || f>=0.0001)
01970 {
01971 glColor3f((float)f,1,(float)f);
01972 helper::gl::glVertexT(out[i]);
01973 helper::gl::glVertexT(in[edge[1]]);
01974 }
01975 }
01976 }
01977 }
01978 glEnd();
01979 }
01980
01981 template <class In, class Out>
01982 void BarycentricMapperTriangleSetTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
01983 {
01984 const sofa::helper::vector<topology::Triangle>& triangles = this->topology->getTriangles();
01985
01986 glBegin (GL_LINES);
01987 {
01988 for(unsigned int i=0;i<map.size();i++)
01989 {
01990 const Real fx = map[i].baryCoords[0];
01991 const Real fy = map[i].baryCoords[1];
01992 int index = map[i].in_index;
01993 const topology::Triangle& triangle = triangles[index];
01994 Real f[3];
01995 f[0] = (1-fx-fy);
01996 f[1] = fx;
01997 f[2] = fy;
01998 for (int j=0;j<3;j++)
01999 {
02000 if (f[j]<=-0.0001 || f[j]>=0.0001)
02001 {
02002 glColor3f((float)f[j],1,(float)f[j]);
02003 helper::gl::glVertexT(out[i]);
02004 helper::gl::glVertexT(in[triangle[j]]);
02005 }
02006 }
02007 }
02008 }
02009 glEnd();
02010 }
02011
02012 template <class In, class Out>
02013 void BarycentricMapperQuadSetTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
02014 {
02015 const sofa::helper::vector<topology::Quad>& quads = this->topology->getQuads();
02016 glBegin (GL_LINES);
02017 {
02018 for(unsigned int i=0;i<map.size();i++)
02019 {
02020 const Real fx = map[i].baryCoords[0];
02021 const Real fy = map[i].baryCoords[1];
02022 int index = map[i].in_index;
02023 const topology::Quad& quad = quads[index];
02024 Real f[4];
02025 f[0] = ((1-fx) * (1-fy));
02026 f[1] = (( fx) * (1-fy));
02027 f[3] = ((1-fx) * ( fy));
02028 f[2] = (( fx) * ( fy));
02029 for (int j=0;j<4;j++)
02030 {
02031 if (f[j]<=-0.0001 || f[j]>=0.0001)
02032 {
02033 glColor3f((float)f[j],1,(float)f[j]);
02034 helper::gl::glVertexT(out[i]);
02035 helper::gl::glVertexT(in[quad[j]]);
02036 }
02037 }
02038 }
02039 }
02040 glEnd();
02041 }
02042
02043 template <class In, class Out>
02044 void BarycentricMapperTetrahedronSetTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
02045 {
02046 const sofa::helper::vector<topology::Tetrahedron>& tetras = this->topology->getTetras();
02047 glBegin (GL_LINES);
02048 {
02049 for(unsigned int i=0;i<map.size();i++)
02050 {
02051 const Real fx = map[i].baryCoords[0];
02052 const Real fy = map[i].baryCoords[1];
02053 const Real fz = map[i].baryCoords[2];
02054 int index = map[i].in_index;
02055 const topology::Tetrahedron& tetra = tetras[index];
02056 Real f[4];
02057 f[0] = (1-fx-fy-fz);
02058 f[1] = fx;
02059 f[2] = fy;
02060 f[3] = fz;
02061 for (int j=0;j<4;j++)
02062 {
02063 if (f[j]<=-0.0001 || f[j]>=0.0001)
02064 {
02065 glColor3f((float)f[j],1,(float)f[j]);
02066 helper::gl::glVertexT(out[i]);
02067 helper::gl::glVertexT(in[tetra[j]]);
02068 }
02069 }
02070 }
02071 }
02072 glEnd();
02073 }
02074
02075 template <class In, class Out>
02076 void BarycentricMapperHexahedronSetTopology<In,Out>::draw(const typename Out::VecCoord& out, const typename In::VecCoord& in)
02077 {
02078 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
02079 glBegin (GL_LINES);
02080 {
02081 for(unsigned int i=0;i<map.size();i++)
02082 {
02083 const Real fx = map[i].baryCoords[0];
02084 const Real fy = map[i].baryCoords[1];
02085 const Real fz = map[i].baryCoords[2];
02086 int index = map[i].in_index;
02087 const topology::Hexahedron& cube = cubes[index];
02088 Real f[8];
02089 f[0] = (1-fx) * (1-fy) * (1-fz);
02090 f[1] = ( fx) * (1-fy) * (1-fz);
02091 f[3] = (1-fx) * ( fy) * (1-fz);
02092 f[2] = ( fx) * ( fy) * (1-fz);
02093 f[4] = (1-fx) * (1-fy) * ( fz);
02094 f[5] = ( fx) * (1-fy) * ( fz);
02095 f[7] = (1-fx) * ( fy) * ( fz);
02096 f[6] = ( fx) * ( fy) * ( fz);
02097 for (int j=0;j<8;j++)
02098 {
02099 if (f[j]<=-0.0001 || f[j]>=0.0001)
02100 {
02101 glColor3f((float)f[j],1,1);
02102 helper::gl::glVertexT(out[i]);
02103 helper::gl::glVertexT(in[cube[j]]);
02104 }
02105 }
02106 }
02107 }
02108 glEnd();
02109 }
02110
02111
02112
02113
02114 template <class BasicMapping>
02115 void BarycentricMapping<BasicMapping>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02116 {
02117 if (mapper!=NULL)
02118 {
02119 mapper->applyJT(out, in);
02120 }
02121 }
02122
02123 template <class In, class Out>
02124 void BarycentricMapperRegularGridTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02125 {
02126
02127 int offset = out.size();
02128 out.resize(offset+in.size());
02129
02130 for(unsigned int i=0;i<in.size();i++)
02131 {
02132 for(unsigned int j=0;j<in[i].size();j++)
02133 {
02134 const typename Out::SparseDeriv cIn = in[i][j];
02135 #ifdef SOFA_NEW_HEXA
02136 const topology::RegularGridTopology::Hexa cube = this->topology->getHexaCopy(this->map[cIn.index].in_index);
02137 #else
02138 const topology::RegularGridTopology::Cube cube = this->topology->getCubeCopy(this->map[cIn.index].in_index);
02139 #endif
02140 const OutReal fx = (OutReal)map[cIn.index].baryCoords[0];
02141 const OutReal fy = (OutReal)map[cIn.index].baryCoords[1];
02142 const OutReal fz = (OutReal)map[cIn.index].baryCoords[2];
02143
02144 out[i+offset].push_back(typename In::SparseDeriv(cube[0], (typename In::Deriv) (cIn.data * ((1-fx) * (1-fy) * (1-fz)))));
02145 out[i+offset].push_back(typename In::SparseDeriv(cube[1], (typename In::Deriv) (cIn.data * (( fx) * (1-fy) * (1-fz)))));
02146 #ifdef SOFA_NEW_HEXA
02147 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) (cIn.data * ((1-fx) * ( fy) * (1-fz)))));
02148 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) (cIn.data * (( fx) * ( fy) * (1-fz)))));
02149 #else
02150 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) (cIn.data * ((1-fx) * ( fy) * (1-fz)))));
02151 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) (cIn.data * (( fx) * ( fy) * (1-fz)))));
02152 #endif
02153 out[i+offset].push_back(typename In::SparseDeriv(cube[4], (typename In::Deriv) (cIn.data * ((1-fx) * (1-fy) * ( fz)))));
02154 out[i+offset].push_back(typename In::SparseDeriv(cube[5], (typename In::Deriv) (cIn.data * (( fx) * (1-fy) * ( fz)))));
02155 #ifdef SOFA_NEW_HEXA
02156 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) (cIn.data * ((1-fx) * ( fy) * ( fz)))));
02157 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) (cIn.data * (( fx) * ( fy) * ( fz)))));
02158 #else
02159 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) (cIn.data * ((1-fx) * ( fy) * ( fz)))));
02160 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) (cIn.data * (( fx) * ( fy) * ( fz)))));
02161 #endif
02162 }
02163 }
02164 }
02165
02166 template <class In, class Out>
02167 void BarycentricMapperSparseGridTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02168 {
02169
02170 int offset = out.size();
02171 out.resize(offset+in.size());
02172 for(unsigned int i=0;i<in.size();i++)
02173 {
02174 std::map<int,int> outpos;
02175 int nbout = 0;
02176 for(unsigned int j=0;j<in[i].size();j++)
02177 {
02178 const typename Out::SparseDeriv cIn = in[i][j];
02179 #ifdef SOFA_NEW_HEXA
02180 const topology::SparseGridTopology::Hexa cube = this->topology->getHexa(this->map[cIn.index].in_index);
02181 #else
02182 const topology::SparseGridTopology::Cube cube = this->topology->getCube(this->map[cIn.index].in_index);
02183 #endif
02184 const OutReal fx = (OutReal)map[cIn.index].baryCoords[0];
02185 const OutReal fy = (OutReal)map[cIn.index].baryCoords[1];
02186 const OutReal fz = (OutReal)map[cIn.index].baryCoords[2];
02187 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[0],nbout)); OutReal f = ((1-fx) * (1-fy) * (1-fz));
02188 if (it.second)
02189 {
02190 out[i+offset].push_back(typename In::SparseDeriv(cube[0], (typename In::Deriv) (cIn.data * f))); ++nbout;
02191 }
02192 else
02193 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02194 }
02195 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[1],nbout)); OutReal f = (( fx) * (1-fy) * (1-fz));
02196 if (it.second)
02197 {
02198 out[i+offset].push_back(typename In::SparseDeriv(cube[1], (typename In::Deriv) (cIn.data * f))); ++nbout;
02199 }
02200 else
02201 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02202 }
02203 #ifdef SOFA_NEW_HEXA
02204 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[3],nbout)); OutReal f = ((1-fx) * ( fy) * (1-fz));
02205 if (it.second)
02206 {
02207 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) (cIn.data * f))); ++nbout;
02208 }
02209 else
02210 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02211 }
02212 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[2],nbout)); OutReal f = (( fx) * ( fy) * (1-fz));
02213 if (it.second)
02214 {
02215 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) (cIn.data * f))); ++nbout;
02216 }
02217 else
02218 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02219 }
02220 #else
02221 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[2],nbout)); OutReal f = ((1-fx) * ( fy) * (1-fz));
02222 if (it.second)
02223 {
02224 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) (cIn.data * f))); ++nbout;
02225 }
02226 else
02227 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02228 }
02229 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[3],nbout)); OutReal f = (( fx) * ( fy) * (1-fz));
02230 if (it.second)
02231 {
02232 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) (cIn.data * f))); ++nbout;
02233 }
02234 else
02235 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02236 }
02237 #endif
02238 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[4],nbout)); OutReal f = ((1-fx) * (1-fy) * ( fz));
02239 if (it.second)
02240 {
02241 out[i+offset].push_back(typename In::SparseDeriv(cube[4], (typename In::Deriv) (cIn.data * f))); ++nbout;
02242 }
02243 else
02244 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02245 }
02246 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[5],nbout)); OutReal f = (( fx) * (1-fy) * ( fz));
02247 if (it.second)
02248 {
02249 out[i+offset].push_back(typename In::SparseDeriv(cube[5], (typename In::Deriv) (cIn.data * f))); ++nbout;
02250 }
02251 else
02252 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02253 }
02254 #ifdef SOFA_NEW_HEXA
02255 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[7],nbout)); OutReal f = ((1-fx) * ( fy) * ( fz));
02256 if (it.second)
02257 {
02258 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) (cIn.data * f))); ++nbout;
02259 }
02260 else
02261 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02262 }
02263 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[6],nbout)); OutReal f = (( fx) * ( fy) * ( fz));
02264 if (it.second)
02265 {
02266 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) (cIn.data * f))); ++nbout;
02267 }
02268 else
02269 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02270 }
02271 #else
02272 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[6],nbout)); OutReal f = ((1-fx) * ( fy) * ( fz));
02273 if (it.second)
02274 {
02275 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) (cIn.data * f))); ++nbout;
02276 }
02277 else
02278 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02279 }
02280 { std::pair<std::map<int,int>::iterator,bool> it = outpos.insert(std::make_pair(cube[7],nbout)); OutReal f = (( fx) * ( fy) * ( fz));
02281 if (it.second)
02282 {
02283 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) (cIn.data * f))); ++nbout;
02284 }
02285 else
02286 out[i+offset][it.first->second].data += (typename In::Deriv) (cIn.data * f);
02287 }
02288 #endif
02289
02290
02291
02292
02293
02294
02295
02296
02297 }
02298 }
02299 }
02300
02301 template <class In, class Out>
02302 void BarycentricMapperMeshTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02303 {
02304
02305 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqLines& lines = this->topology->getLines();
02306 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles& triangles = this->topology->getTriangles();
02307 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqQuads& quads = this->topology->getQuads();
02308 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqTetras& tetras = this->topology->getTetras();
02309 #ifdef SOFA_NEW_HEXA
02310 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqHexas& cubes = this->topology->getHexas();
02311 #else
02312 const sofa::core::componentmodel::topology::BaseMeshTopology::SeqCubes& cubes = this->topology->getCubes();
02313 #endif
02314
02315 const int iTri = triangles.size();
02316
02317 const int iTetra= tetras.size();
02318
02319
02320 const int i1d = map1d.size();
02321 const int i2d = map2d.size();
02322 const int i3d = map3d.size();
02323
02324 int indexIn;
02325
02326 int offset = out.size();
02327 out.resize(offset+in.size());
02328
02329 for(unsigned int i=0;i<in.size();i++)
02330 {
02331 for(unsigned int j=0;j<in[i].size();j++)
02332 {
02333 const typename Out::SparseDeriv cIn = in[i][j];
02334 indexIn = cIn.index;
02335
02336 if (indexIn < i1d)
02337 {
02338 const OutReal fx = (OutReal)map1d[indexIn].baryCoords[0];
02339 int index = map1d[indexIn].in_index;
02340 {
02341 const sofa::core::componentmodel::topology::BaseMeshTopology::Line& line = lines[index];
02342 out[i+offset].push_back(typename In::SparseDeriv((unsigned) line[0], (typename In::Deriv) cIn.data * (1-fx)));
02343 out[i+offset].push_back(typename In::SparseDeriv(line[1], (typename In::Deriv) cIn.data * fx));
02344 }
02345 }
02346
02347 else if (indexIn < i2d)
02348 {
02349 const OutReal fx = (OutReal)map2d[indexIn].baryCoords[0];
02350 const OutReal fy = (OutReal)map2d[indexIn].baryCoords[1];
02351 int index = map2d[indexIn].in_index;
02352 if (index < iTri)
02353 {
02354 const sofa::core::componentmodel::topology::BaseMeshTopology::Triangle& triangle = triangles[index];
02355 out[i+offset].push_back(typename In::SparseDeriv(triangle[0], (typename In::Deriv) cIn.data * (1-fx-fy)));
02356 out[i+offset].push_back(typename In::SparseDeriv(triangle[1], (typename In::Deriv) cIn.data * fx));
02357 out[i+offset].push_back(typename In::SparseDeriv(triangle[2], (typename In::Deriv) cIn.data * fy));
02358 }
02359 else
02360 {
02361 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& quad = quads[index - iTri];
02362 out[i+offset].push_back(typename In::SparseDeriv(quad[0], (typename In::Deriv) cIn.data * ((1-fx) * (1-fy))));
02363 out[i+offset].push_back(typename In::SparseDeriv(quad[1], (typename In::Deriv) cIn.data * (( fx) * (1-fy))));
02364 out[i+offset].push_back(typename In::SparseDeriv(quad[3], (typename In::Deriv) cIn.data * ((1-fx) * ( fy))));
02365 out[i+offset].push_back(typename In::SparseDeriv(quad[2], (typename In::Deriv) cIn.data * (( fx) * ( fy))));
02366 }
02367 }
02368
02369 else if (indexIn < i3d)
02370 {
02371 const OutReal fx = (OutReal)map3d[indexIn].baryCoords[0];
02372 const OutReal fy = (OutReal)map3d[indexIn].baryCoords[1];
02373 const OutReal fz = (OutReal)map3d[indexIn].baryCoords[2];
02374 int index = map3d[indexIn].in_index;
02375 if (index < iTetra)
02376 {
02377 const sofa::core::componentmodel::topology::BaseMeshTopology::Tetra& tetra = tetras[index];
02378 out[i+offset].push_back(typename In::SparseDeriv(tetra[0], (typename In::Deriv) cIn.data * (1-fx-fy-fz)));
02379 out[i+offset].push_back(typename In::SparseDeriv(tetra[1], (typename In::Deriv) cIn.data * fx));
02380 out[i+offset].push_back(typename In::SparseDeriv(tetra[2], (typename In::Deriv) cIn.data * fy));
02381 out[i+offset].push_back(typename In::SparseDeriv(tetra[3], (typename In::Deriv) cIn.data * fz));
02382 }
02383 else
02384 {
02385 #ifdef SOFA_NEW_HEXA
02386 const sofa::core::componentmodel::topology::BaseMeshTopology::Hexa& cube = cubes[index-iTetra];
02387 #else
02388 const sofa::core::componentmodel::topology::BaseMeshTopology::Cube& cube = cubes[index-iTetra];
02389 #endif
02390 out[i+offset].push_back(typename In::SparseDeriv(cube[0], (typename In::Deriv) cIn.data * ((1-fx) * (1-fy) * (1-fz))));
02391 out[i+offset].push_back(typename In::SparseDeriv(cube[1], (typename In::Deriv) cIn.data * (( fx) * (1-fy) * (1-fz))));
02392 #ifdef SOFA_NEW_HEXA
02393 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) cIn.data * ((1-fx) * ( fy) * (1-fz))));
02394 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) cIn.data * (( fx) * ( fy) * (1-fz))));
02395 #else
02396 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) cIn.data * ((1-fx) * ( fy) * (1-fz))));
02397 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) cIn.data * (( fx) * ( fy) * (1-fz))));
02398 #endif
02399 out[i+offset].push_back(typename In::SparseDeriv(cube[4], (typename In::Deriv) cIn.data * ((1-fx) * (1-fy) * ( fz))));
02400 out[i+offset].push_back(typename In::SparseDeriv(cube[5], (typename In::Deriv) cIn.data * (( fx) * (1-fy) * ( fz))));
02401 #ifdef SOFA_NEW_HEXA
02402 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) cIn.data * ((1-fx) * ( fy) * ( fz))));
02403 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) cIn.data * (( fx) * ( fy) * ( fz))));
02404 #else
02405 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) cIn.data * ((1-fx) * ( fy) * ( fz))));
02406 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) cIn.data * (( fx) * ( fy) * ( fz))));
02407 #endif
02408 }
02409 }
02410 }
02411 }
02412 }
02413
02414 template <class In, class Out>
02415 void BarycentricMapperEdgeSetTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02416 {
02417 int offset = out.size();
02418 out.resize(offset+in.size());
02419 const sofa::helper::vector<topology::Edge>& edges = this->topology->getEdges();
02420
02421 for(unsigned int i=0;i<in.size();i++)
02422 {
02423 for(unsigned int j=0;j<in[i].size();j++)
02424 {
02425 const typename Out::SparseDeriv cIn = in[i][j];
02426 const topology::Edge edge = edges[this->map[cIn.index].in_index];
02427 const OutReal fx = (OutReal)map[cIn.index].baryCoords[0];
02428
02429 out[i+offset].push_back(typename In::SparseDeriv(edge[0], (typename In::Deriv) (cIn.data * (1-fx))));
02430 out[i+offset].push_back(typename In::SparseDeriv(edge[1], (typename In::Deriv) (cIn.data * (fx))));
02431 }
02432 }
02433 }
02434
02435 template <class In, class Out>
02436 void BarycentricMapperTriangleSetTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02437 {
02438 int offset = out.size();
02439 out.resize(offset+in.size());
02440 const sofa::helper::vector<topology::Triangle>& triangles = this->topology->getTriangles();
02441
02442 for(unsigned int i=0;i<in.size();i++)
02443 {
02444 for(unsigned int j=0;j<in[i].size();j++)
02445 {
02446 const typename Out::SparseDeriv cIn = in[i][j];
02447 const topology::Triangle triangle = triangles[this->map[cIn.index].in_index];
02448 const OutReal fx = (OutReal)map[cIn.index].baryCoords[0];
02449 const OutReal fy = (OutReal)map[cIn.index].baryCoords[1];
02450
02451 out[i+offset].push_back(typename In::SparseDeriv(triangle[0], (typename In::Deriv) (cIn.data * (1-fx-fy))));
02452 out[i+offset].push_back(typename In::SparseDeriv(triangle[1], (typename In::Deriv) (cIn.data * (fx))));
02453 out[i+offset].push_back(typename In::SparseDeriv(triangle[2], (typename In::Deriv) (cIn.data * (fy))));
02454 }
02455 }
02456 }
02457
02458 template <class In, class Out>
02459 void BarycentricMapperQuadSetTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02460 {
02461 int offset = out.size();
02462 out.resize(offset+in.size());
02463 const sofa::helper::vector<topology::Quad>& quads = this->topology->getQuads();
02464
02465 for(unsigned int i=0;i<in.size();i++)
02466 {
02467 for(unsigned int j=0;j<in[i].size();j++)
02468 {
02469 const typename Out::SparseDeriv cIn = in[i][j];
02470 const int indexIn = cIn.index;
02471 const OutReal fx = (OutReal)map[cIn.index].baryCoords[0];
02472 const OutReal fy = (OutReal)map[cIn.index].baryCoords[1];
02473
02474 const sofa::core::componentmodel::topology::BaseMeshTopology::Quad& quad = quads[map[indexIn].in_index];
02475 out[i+offset].push_back(typename In::SparseDeriv(quad[0], (typename In::Deriv) cIn.data * ((1-fx) * (1-fy))));
02476 out[i+offset].push_back(typename In::SparseDeriv(quad[1], (typename In::Deriv) cIn.data * (( fx) * (1-fy))));
02477 out[i+offset].push_back(typename In::SparseDeriv(quad[3], (typename In::Deriv) cIn.data * ((1-fx) * ( fy))));
02478 out[i+offset].push_back(typename In::SparseDeriv(quad[2], (typename In::Deriv) cIn.data * (( fx) * ( fy))));
02479 }
02480 }
02481 }
02482
02483 template <class In, class Out>
02484 void BarycentricMapperTetrahedronSetTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02485 {
02486 int offset = out.size();
02487 out.resize(offset+in.size());
02488 const sofa::helper::vector<topology::Tetrahedron>& tetras = this->topology->getTetras();
02489
02490 for(unsigned int i=0;i<in.size();i++)
02491 {
02492 for(unsigned int j=0;j<in[i].size();j++)
02493 {
02494 const typename Out::SparseDeriv cIn = in[i][j];
02495 const int indexIn = cIn.index;
02496 const OutReal fx = (OutReal)map[indexIn].baryCoords[0];
02497 const OutReal fy = (OutReal)map[indexIn].baryCoords[1];
02498 const OutReal fz = (OutReal)map[indexIn].baryCoords[2];
02499 int index = map[indexIn].in_index;
02500 const topology::Tetrahedron& tetra = tetras[index];
02501 out[i+offset].push_back(typename In::SparseDeriv(tetra[0], (typename In::Deriv) cIn.data * (1-fx-fy-fz)));
02502 out[i+offset].push_back(typename In::SparseDeriv(tetra[1], (typename In::Deriv) cIn.data * fx));
02503 out[i+offset].push_back(typename In::SparseDeriv(tetra[2], (typename In::Deriv) cIn.data * fy));
02504 out[i+offset].push_back(typename In::SparseDeriv(tetra[3], (typename In::Deriv) cIn.data * fz));
02505 }
02506 }
02507 }
02508
02509 template <class In, class Out>
02510 void BarycentricMapperHexahedronSetTopology<In,Out>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
02511 {
02512 int offset = out.size();
02513 out.resize(offset+in.size());
02514 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
02515
02516 for(unsigned int i=0;i<in.size();i++)
02517 {
02518 for(unsigned int j=0;j<in[i].size();j++)
02519 {
02520 const typename Out::SparseDeriv cIn = in[i][j];
02521 const int indexIn = cIn.index;
02522 const OutReal fx = (OutReal)map[indexIn].baryCoords[0];
02523 const OutReal fy = (OutReal)map[indexIn].baryCoords[1];
02524 const OutReal fz = (OutReal)map[indexIn].baryCoords[2];
02525 int index = map[indexIn].in_index;
02526 const topology::Hexahedron& cube = cubes[index];
02527 out[i+offset].push_back(typename In::SparseDeriv(cube[0], (typename In::Deriv) cIn.data * ((1-fx) * (1-fy) * (1-fz))));
02528 out[i+offset].push_back(typename In::SparseDeriv(cube[1], (typename In::Deriv) cIn.data * (( fx) * (1-fy) * (1-fz))));
02529 out[i+offset].push_back(typename In::SparseDeriv(cube[3], (typename In::Deriv) cIn.data * ((1-fx) * ( fy) * (1-fz))));
02530 out[i+offset].push_back(typename In::SparseDeriv(cube[2], (typename In::Deriv) cIn.data * (( fx) * ( fy) * (1-fz))));
02531 out[i+offset].push_back(typename In::SparseDeriv(cube[4], (typename In::Deriv) cIn.data * ((1-fx) * (1-fy) * ( fz))));
02532 out[i+offset].push_back(typename In::SparseDeriv(cube[5], (typename In::Deriv) cIn.data * (( fx) * (1-fy) * ( fz))));
02533 out[i+offset].push_back(typename In::SparseDeriv(cube[7], (typename In::Deriv) cIn.data * ((1-fx) * ( fy) * ( fz))));
02534 out[i+offset].push_back(typename In::SparseDeriv(cube[6], (typename In::Deriv) cIn.data * (( fx) * ( fy) * ( fz))));
02535 }
02536 }
02537 }
02538
02539 template <class In, class Out>
02540 void BarycentricMapperEdgeSetTopology<In,Out>::handleTopologyChange()
02541 {
02542 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin = topology->firstChange();
02543 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd = topology->lastChange();
02544
02545 for(std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator changeIt = itBegin;
02546 changeIt != itEnd; ++changeIt)
02547 {
02548 const core::componentmodel::topology::TopologyChangeType changeType = (*changeIt)->getChangeType();
02549 switch(changeType)
02550 {
02551
02552 case core::componentmodel::topology::ENDING_EVENT:
02553 break;
02554 case core::componentmodel::topology::POINTSINDICESSWAP:
02555 break;
02556 case core::componentmodel::topology::POINTSADDED:
02557 break;
02558 case core::componentmodel::topology::POINTSREMOVED:
02559 break;
02560 case core::componentmodel::topology::POINTSRENUMBERING:
02561 break;
02562 case core::componentmodel::topology::EDGESADDED:
02563 break;
02564 case core::componentmodel::topology::EDGESREMOVED:
02565 break;
02566 case core::componentmodel::topology::EDGESRENUMBERING:
02567 break;
02568 default:
02569 break;
02570 }
02571 }
02572 }
02573
02574 template <class In, class Out>
02575 void BarycentricMapperTriangleSetTopology<In,Out>::handleTopologyChange()
02576 {
02577 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin = topology->firstChange();
02578 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd = topology->lastChange();
02579
02580 for(std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator changeIt = itBegin;
02581 changeIt != itEnd; ++changeIt)
02582 {
02583 const core::componentmodel::topology::TopologyChangeType changeType = (*changeIt)->getChangeType();
02584 switch(changeType)
02585 {
02586
02587 case core::componentmodel::topology::ENDING_EVENT:
02588 break;
02589 case core::componentmodel::topology::POINTSINDICESSWAP:
02590 break;
02591 case core::componentmodel::topology::POINTSADDED:
02592 break;
02593 case core::componentmodel::topology::POINTSREMOVED:
02594 break;
02595 case core::componentmodel::topology::POINTSRENUMBERING:
02596 break;
02597 case core::componentmodel::topology::TRIANGLESADDED:
02598 break;
02599 case core::componentmodel::topology::TRIANGLESREMOVED:
02600 break;
02601 case core::componentmodel::topology::TRIANGLESRENUMBERING:
02602 break;
02603 default:
02604 break;
02605 }
02606 }
02607 }
02608
02609 template <class In, class Out>
02610 void BarycentricMapperQuadSetTopology<In,Out>::handleTopologyChange()
02611 {
02612 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin = topology->firstChange();
02613 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd = topology->lastChange();
02614
02615 for(std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator changeIt = itBegin;
02616 changeIt != itEnd; ++changeIt)
02617 {
02618 const core::componentmodel::topology::TopologyChangeType changeType = (*changeIt)->getChangeType();
02619 switch(changeType)
02620 {
02621
02622 case core::componentmodel::topology::ENDING_EVENT:
02623 break;
02624 case core::componentmodel::topology::POINTSINDICESSWAP:
02625 break;
02626 case core::componentmodel::topology::POINTSADDED:
02627 break;
02628 case core::componentmodel::topology::POINTSREMOVED:
02629 break;
02630 case core::componentmodel::topology::POINTSRENUMBERING:
02631 break;
02632 case core::componentmodel::topology::QUADSADDED:
02633 break;
02634 case core::componentmodel::topology::QUADSREMOVED:
02635 break;
02636 case core::componentmodel::topology::QUADSRENUMBERING:
02637 break;
02638 default:
02639 break;
02640 }
02641 }
02642 }
02643
02644 template <class In, class Out>
02645 void BarycentricMapperTetrahedronSetTopology<In,Out>::handleTopologyChange()
02646 {
02647 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin = topology->firstChange();
02648 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd = topology->lastChange();
02649
02650 for(std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator changeIt = itBegin;
02651 changeIt != itEnd; ++changeIt)
02652 {
02653 const core::componentmodel::topology::TopologyChangeType changeType = (*changeIt)->getChangeType();
02654 switch(changeType)
02655 {
02656
02657 case core::componentmodel::topology::ENDING_EVENT:
02658 break;
02659 case core::componentmodel::topology::POINTSINDICESSWAP:
02660 break;
02661 case core::componentmodel::topology::POINTSADDED:
02662 break;
02663 case core::componentmodel::topology::POINTSREMOVED:
02664 break;
02665 case core::componentmodel::topology::POINTSRENUMBERING:
02666 break;
02667 case core::componentmodel::topology::TETRAHEDRAADDED:
02668 break;
02669 case core::componentmodel::topology::TETRAHEDRAREMOVED:
02670 break;
02671 case core::componentmodel::topology::TETRAHEDRARENUMBERING:
02672 break;
02673 default:
02674 break;
02675 }
02676 }
02677 }
02678
02679 template <class In, class Out>
02680 void BarycentricMapperHexahedronSetTopology<In,Out>::handleTopologyChange()
02681 {
02682 if(topology->firstChange()==topology->lastChange())
02683 return;
02684
02685 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin = topology->firstChange();
02686 std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd = topology->lastChange();
02687
02688 for(std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator changeIt = itBegin;
02689 changeIt != itEnd; ++changeIt)
02690 {
02691 const core::componentmodel::topology::TopologyChangeType changeType = (*changeIt)->getChangeType();
02692 switch(changeType)
02693 {
02694
02695 case core::componentmodel::topology::ENDING_EVENT:
02696 break;
02697 case core::componentmodel::topology::POINTSINDICESSWAP:
02698 break;
02699 case core::componentmodel::topology::POINTSADDED:
02700 break;
02701 case core::componentmodel::topology::POINTSREMOVED:
02702 break;
02703 case core::componentmodel::topology::POINTSRENUMBERING:
02704 break;
02705 case core::componentmodel::topology::HEXAHEDRAADDED:
02706 break;
02707 case core::componentmodel::topology::HEXAHEDRAREMOVED:
02708 {
02709 const sofa::helper::vector<topology::Hexahedron>& cubes = this->topology->getHexas();
02710
02711 #ifndef NDEBUG
02712 if(cubes.size() != hexahedronData.size())
02713 {
02714 std::cout << "Error. BarycentricMapperHexahedronSetTopology::handleTopologyChange() : Topology container size does not match the hexahedron data size.";
02715 return;
02716 }
02717 #endif
02718
02719 const sofa::helper::vector<unsigned int> &tab = (static_cast< const component::topology::HexahedraRemoved *> (*changeIt))->getArray();
02720 sofa::helper::vector<unsigned int> hexahedra(tab);
02721
02722 for(unsigned int i=0; i<hexahedra.size(); ++i)
02723 {
02724
02725 int cubeId = (int) hexahedra[i];
02726 for(unsigned int j=0; j<map.size(); ++j)
02727 {
02728 if(map[j].in_index == cubeId)
02729 {
02730 Vector3 coefs;
02731 coefs[0] = map[j].baryCoords[0];
02732 coefs[1] = map[j].baryCoords[1];
02733 coefs[2] = map[j].baryCoords[2];
02734
02735
02736 Matrix3 m;
02737 m.invert(hexahedronData[cubeId].base);
02738 Vector3 pos = (m * coefs) + hexahedronData[cubeId].origin;
02739
02740
02741 int index=-1;
02742 double distance = 1e10;
02743 for (unsigned int c = 0; c < cubes.size(); c++)
02744 {
02745 bool validC = true;
02746
02747 for(unsigned int k=0; k<hexahedra.size(); ++k)
02748 {
02749 if(c == hexahedra[k])
02750 {
02751 validC = false;
02752 break;
02753 }
02754 }
02755
02756 if(validC)
02757 {
02758 const Vec3d v = hexahedronData[c].base * (pos - hexahedronData[c].origin);
02759 double d = std::max(std::max(-v[0],-v[1]), std::max(std::max(-v[2],v[0]-1), std::max(v[1]-1,v[2]-1)));
02760 if (d>0)
02761 d = (pos-hexahedronData[c].center).norm2();
02762 if (d<distance)
02763 {
02764 coefs = v;
02765 distance = d;
02766 index = c;
02767 }
02768 }
02769 }
02770
02771 if(index != -1)
02772 {
02773 map[j].baryCoords[0] = (Real) coefs[0];
02774 map[j].baryCoords[1] = (Real) coefs[1];
02775 map[j].baryCoords[2] = (Real) coefs[2];
02776 map[j].in_index = index;
02777 }
02778 }
02779 }
02780 }
02781
02782
02783 int lastCubeId = (int) cubes.size()-1;
02784 for(unsigned int i=0; i<hexahedra.size(); ++i)
02785 {
02786 unsigned int cubeId = hexahedra[i];
02787 for(unsigned int j=0; j<map.size(); ++j)
02788 {
02789 if(map[j].in_index == lastCubeId)
02790 map[j].in_index = cubeId;
02791 }
02792 lastCubeId -= 1;
02793 }
02794 }
02795 break;
02796 case core::componentmodel::topology::HEXAHEDRARENUMBERING:
02797 break;
02798 default:
02799 break;
02800 }
02801 }
02802
02803 hexahedronData.handleTopologyEvents(itBegin, itEnd);
02804 }
02805
02806 template <class In, class Out>
02807 void BarycentricMapperEdgeSetTopology<In,Out>::handlePointEvents(std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin,
02808 std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd)
02809 {
02810 map.handleTopologyEvents(itBegin, itEnd);
02811 }
02812
02813 template <class In, class Out>
02814 void BarycentricMapperTriangleSetTopology<In,Out>::handlePointEvents(std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin,
02815 std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd)
02816 {
02817 map.handleTopologyEvents(itBegin, itEnd);
02818 }
02819
02820 template <class In, class Out>
02821 void BarycentricMapperQuadSetTopology<In,Out>::handlePointEvents(std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin,
02822 std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd)
02823 {
02824 map.handleTopologyEvents(itBegin, itEnd);
02825 }
02826
02827 template <class In, class Out>
02828 void BarycentricMapperTetrahedronSetTopology<In,Out>::handlePointEvents(std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin,
02829 std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd)
02830 {
02831 map.handleTopologyEvents(itBegin, itEnd);
02832 }
02833
02834 template <class In, class Out>
02835 void BarycentricMapperHexahedronSetTopology<In,Out>::handlePointEvents(std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin,
02836 std::list< const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd)
02837 {
02838 map.handleTopologyEvents(itBegin, itEnd);
02839 }
02840
02841 template <class BasicMapping>
02842 void BarycentricMapping<BasicMapping>::handleTopologyChange()
02843 {
02844 BarycentricMapperBaseTopology* topoMapper = dynamic_cast<BarycentricMapperBaseTopology*>(mapper);
02845
02846 if(topoMapper != NULL)
02847 {
02848
02849 topoMapper->handleTopologyChange();
02850
02851
02852 core::componentmodel::topology::BaseMeshTopology* topology_to = this->toModel->getContext()->getMeshTopology();
02853 if (topology_to != NULL)
02854 {
02855 if(topology_to->firstChange() != topology_to->lastChange())
02856 {
02857 const std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin = topology_to->firstChange();
02858 const std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd = topology_to->lastChange();
02859
02860 topoMapper->handlePointEvents(itBegin, itEnd);
02861 }
02862 }
02863 }
02864 }
02865
02866 }
02867
02868 }
02869
02870 }
02871
02872 #endif