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_SPHFLUIDSURFACEMAPPING_H
00026 #define SOFA_COMPONENT_MAPPING_SPHFLUIDSURFACEMAPPING_H
00027
00028 #if !defined(__GNUC__) || (__GNUC__ > 3 || (_GNUC__ == 3 && __GNUC_MINOR__ > 3))
00029 #pragma once
00030 #endif
00031
00032 #include <sofa/component/forcefield/SPHFluidForceField.h>
00033 #include <sofa/core/Mapping.h>
00034 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00035 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00036 #include <sofa/component/topology/MeshTopology.h>
00037 #include <sofa/helper/MarchingCubeUtility.h>
00038 #include <vector>
00039
00040 namespace sofa
00041 {
00042
00043 namespace component
00044 {
00045
00046 namespace mapping
00047 {
00048
00049 using namespace sofa::component::container;
00050
00051 template <class InDataTypes, class OutDataTypes>
00052 class SPHFluidSurfaceMappingGridTypes : public SpatialGridTypes<InDataTypes>
00053 {
00054 public:
00055 typedef forcefield::SPHFluidForceField<InDataTypes> ParticleField;
00056 typedef typename InDataTypes::Real Real;
00058 class CellData
00059 {
00060 public:
00061 int p[3];
00062 typename OutDataTypes::Real val;
00063 CellData()
00064 {
00065 clear();
00066 }
00067 void clear()
00068 {
00069 p[0]=p[1]=p[2]=-1;
00070 val=0;
00071 }
00072 void add
00073 (ParticleField* field, int i, Real r2, Real h2)
00074 {
00075 val += (typename OutDataTypes::Real) field->getParticleField(i, r2/h2);
00076 }
00077 };
00078
00079 class GridData
00080 {
00081 public:
00082 bool visited;
00083 void clear()
00084 {
00085 visited = false;
00086 }
00087 GridData()
00088 {
00089 clear();
00090 }
00091 };
00092 enum { GRIDDIM_LOG2 = 2 };
00093 };
00094
00095 template <class In, class Out>
00096 class SPHFluidSurfaceMapping : public core::Mapping<In, Out>, public topology::MeshTopology
00097 {
00098 public:
00099 typedef core::Mapping<In, Out> Inherit;
00100 typedef typename Out::VecCoord OutVecCoord;
00101 typedef typename Out::VecDeriv OutVecDeriv;
00102 typedef typename Out::Coord OutCoord;
00103 typedef typename Out::Deriv OutDeriv;
00104 typedef typename OutCoord::value_type OutReal;
00105 typedef typename In::VecCoord InVecCoord;
00106 typedef typename In::VecDeriv InVecDeriv;
00107 typedef typename In::Coord InCoord;
00108 typedef typename In::Deriv InDeriv;
00109 typedef typename InCoord::value_type InReal;
00110
00111 SPHFluidSurfaceMapping(In* from, Out* to)
00112 : Inherit(from, to),
00113 mStep(initData(&mStep,0.5,"step","Step")),
00114 mRadius(initData(&mRadius,2.0,"radius","Radius")),
00115 mIsoValue(initData(&mIsoValue,0.5,"isoValue", "Iso Value")),
00116 sph(NULL), grid(NULL)
00117 {
00118 }
00119
00120 virtual ~SPHFluidSurfaceMapping()
00121 {}
00122
00123 double getStep() const
00124 {
00125 return mStep.getValue();
00126 }
00127 void setStep(double val)
00128 {
00129 mStep.setValue(val);
00130 }
00131
00132 double getRadius() const
00133 {
00134 return mRadius.getValue();
00135 }
00136 void setRadius(double val)
00137 {
00138 mRadius.setValue(val);
00139 }
00140
00141 double getIsoValue() const
00142 {
00143 return mIsoValue.getValue();
00144 }
00145 void setIsoValue(double val)
00146 {
00147 mIsoValue.setValue(val);
00148 }
00149
00150 void init();
00151
00152 void apply( OutVecCoord& out, const InVecCoord& in );
00153
00154 void applyJ( OutVecDeriv& out, const InVecDeriv& in );
00155
00156
00157
00158 void draw();
00159
00160
00161 protected:
00162 Data< double > mStep;
00163 Data< double > mRadius;
00164 Data< double > mIsoValue;
00165
00166 typedef forcefield::SPHFluidForceField<typename In::DataTypes> SPHForceField;
00167 SPHForceField* sph;
00168
00169
00170
00171 typedef SPHFluidSurfaceMappingGridTypes<typename In::DataTypes, typename Out::DataTypes> GridTypes;
00172
00173 typedef SpatialGrid<GridTypes> Grid;
00174 typedef typename Grid::Cell Cell;
00175 enum { GRIDDIM = Grid::GRIDDIM };
00176 enum { DX = Grid::DX };
00177 enum { DY = Grid::DY };
00178 enum { DZ = Grid::DZ };
00179
00180 Grid* grid;
00181
00182 void createPoints(OutVecCoord& out, int x, int y, int z, Cell* c, const Cell* cx, const Cell* cy, const Cell* cz, const OutReal isoval);
00183
00184 void createFaces(OutVecCoord& out, const Cell** cells, const OutReal isoval);
00185
00186 template<int C>
00187 int addPoint(OutVecCoord& out, int x,int y,int z, OutReal v0, OutReal v1, OutReal iso)
00188 {
00189 int p = out.size();
00190 OutCoord pos = OutCoord((OutReal)x,(OutReal)y,(OutReal)z);
00191 pos[C] += (iso-v0)/(v1-v0);
00192 out.resize(p+1);
00193 out[p] = pos * mStep.getValue();
00194 return p;
00195 }
00196
00197 int addFace(int p1, int p2, int p3, int nbp)
00198 {
00199 if ((unsigned)p1<(unsigned)nbp &&
00200 (unsigned)p2<(unsigned)nbp &&
00201 (unsigned)p3<(unsigned)nbp)
00202 {
00203 SeqTriangles& triangles = *seqTriangles.beginEdit();
00204 int f = triangles.size();
00205 triangles.push_back(Triangle(p1, p3, p2));
00206 seqTriangles.endEdit();
00207 return f;
00208 }
00209 else
00210 {
00211 std::cerr << "ERROR: Invalid face "<<p1<<" "<<p2<<" "<<p3<<std::endl;
00212 return -1;
00213 }
00214 }
00215
00216 };
00217
00218 }
00219
00220 }
00221
00222 }
00223
00224 #endif