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_IMPLICITSURFACEMAPPING_H
00026 #define SOFA_COMPONENT_MAPPING_IMPLICITSURFACEMAPPING_H
00027
00028 #include <sofa/core/Mapping.h>
00029 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00030 #include <sofa/component/topology/MeshTopology.h>
00031 #include <sofa/helper/MarchingCubeUtility.h>
00032 #include <vector>
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace mapping
00041 {
00042
00043
00044
00045 template <class In, class Out>
00046 class ImplicitSurfaceMapping : public core::Mapping<In, Out>, public topology::MeshTopology
00047 {
00048 public:
00049 typedef core::Mapping<In, Out> Inherit;
00050 typedef typename Out::VecCoord OutVecCoord;
00051 typedef typename Out::VecDeriv OutVecDeriv;
00052 typedef typename Out::Coord OutCoord;
00053 typedef typename Out::Deriv OutDeriv;
00054 typedef typename OutCoord::value_type OutReal;
00055 typedef typename In::VecCoord InVecCoord;
00056 typedef typename In::VecDeriv InVecDeriv;
00057 typedef typename In::Coord InCoord;
00058 typedef typename In::Deriv InDeriv;
00059 typedef typename InCoord::value_type InReal;
00060
00061 ImplicitSurfaceMapping(In* from, Out* to)
00062 : Inherit(from, to),
00063 mStep(initData(&mStep,0.5,"step","Step")),
00064 mRadius(initData(&mRadius,2.0,"radius","Radius")),
00065 mIsoValue(initData(&mIsoValue,0.5,"isoValue","Iso Value")),
00066 mGridMin(initData(&mGridMin,InCoord(-100,-100,-100),"min","Grid Min")),
00067 mGridMax(initData(&mGridMax,InCoord(100,100,100),"max","Grid Max"))
00068 {
00069 }
00070
00071 virtual ~ImplicitSurfaceMapping()
00072 {
00073 }
00074
00075 virtual void init();
00076
00077 virtual void parse(core::objectmodel::BaseObjectDescription* arg);
00078
00079 double getStep() const { return mStep.getValue(); }
00080 void setStep(double val) { mStep.setValue(val); }
00081
00082 double getRadius() const { return mRadius.getValue(); }
00083 void setRadius(double val) { mRadius.setValue(val); }
00084
00085 double getIsoValue() const { return mIsoValue.getValue(); }
00086 void setIsoValue(double val) { mIsoValue.setValue(val); }
00087
00088 const InCoord& getGridMin() const { return mGridMin.getValue(); }
00089 void setGridMin(const InCoord& val) { mGridMin.setValue(val); }
00090 void setGridMin(double x, double y, double z) { mGridMin.setValue( InCoord((InReal)x,(InReal)y,(InReal)z)); }
00091
00092 const InCoord& getGridMax() const { return mGridMax.getValue(); }
00093 void setGridMax(const InCoord& val) { mGridMax.setValue(val); }
00094 void setGridMax(double x, double y, double z) { mGridMax.setValue( InCoord((InReal)x,(InReal)y,(InReal)z)); }
00095
00096 void apply( OutVecCoord& out, const InVecCoord& in );
00097
00098 void applyJ( OutVecDeriv& out, const InVecDeriv& in );
00099
00100
00101 protected:
00102 Data <double > mStep;
00103 Data <double > mRadius;
00104 Data <double > mIsoValue;
00105
00106 Data< InCoord > mGridMin;
00107 Data< InCoord > mGridMax;
00108
00109
00110
00112 struct CubeData
00113 {
00114 int p[3];
00115 OutReal data;
00116 inline friend std::istream& operator >> ( std::istream& in, CubeData& c)
00117 {
00118 in >> c.p[0] >> c.p[1] >> c.p[2] >> c.data;
00119
00120 return in;
00121 }
00122
00123 inline friend std::ostream& operator << ( std::ostream& out, const CubeData& c){
00124 out << c.p[0] << " " << c.p[1] << " " << c.p[2] << " " << c.data ;
00125 return out;
00126 }
00127 };
00128
00129 Data < sofa::helper::vector<CubeData> > planes;
00130 typename sofa::helper::vector<CubeData>::iterator P0;
00131 typename sofa::helper::vector<CubeData>::iterator P1;
00132
00133 void newPlane();
00134
00135 template<int C>
00136 int addPoint(OutVecCoord& out, int x,int y,int z, OutReal v0, OutReal v1, OutReal iso)
00137 {
00138 int p = out.size();
00139 OutCoord pos = OutCoord((OutReal)x,(OutReal)y,(OutReal)z);
00140 pos[C] -= (iso-v0)/(v1-v0);
00141 out.resize(p+1);
00142 out[p] = pos * mStep.getValue();
00143 return p;
00144 }
00145
00146 int addFace(int p1, int p2, int p3, int nbp)
00147 {
00148 if ((unsigned)p1<(unsigned)nbp &&
00149 (unsigned)p2<(unsigned)nbp &&
00150 (unsigned)p3<(unsigned)nbp)
00151 {
00152 SeqTriangles& triangles = *seqTriangles.beginEdit();
00153 int f = triangles.size();
00154 triangles.push_back(Triangle(p1, p3, p2));
00155 seqTriangles.endEdit();
00156 return f;
00157 }
00158 else
00159 {
00160 std::cerr << "ERROR: Invalid face "<<p1<<" "<<p2<<" "<<p3<<std::endl;
00161 return -1;
00162 }
00163 }
00164
00165 };
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 }
00196
00197 }
00198
00199 }
00200
00201 #endif