00001 #ifndef GL_FIELD
00002 #define GL_FIELD
00003
00004 #include <vcg/complex/algorithms/parametrization/tangent_field_operators.h>
00005 #include <vcg/complex/allocate.h>
00006
00007 namespace vcg{
00008 template <class MeshType>
00009 class GLField
00010 {
00011 typedef typename MeshType::FaceType FaceType;
00012 typedef typename MeshType::VertexType VertexType;
00013 typedef typename MeshType::CoordType CoordType;
00014 typedef typename MeshType::ScalarType ScalarType;
00015
00016 public:
00017
00018 static void GLDrawField(CoordType dir[4],
00019 CoordType center,
00020 ScalarType &size,
00021 bool onlyPD1=false,
00022 bool oneside=false)
00023 {
00024 ScalarType size1=size;
00025 ScalarType size2=size;
00026 if (oneside)size2=0;
00027
00028 glLineWidth(2);
00029
00030 vcg::glColor(vcg::Color4b(0,0,0,255));
00031 glBegin(GL_LINES);
00032 glVertex(center+dir[0]*size1);
00033 glVertex(center-dir[0]*size2);
00034 glEnd();
00035
00036 if (onlyPD1)return;
00037 glLineWidth(2);
00038
00039 vcg::glColor(vcg::Color4b(0,0,0,255));
00040 glBegin(GL_LINES);
00041 glVertex(center+dir[1]*size1);
00042 glVertex(center-dir[1]*size2);
00043 glEnd();
00044
00045 }
00046
00048 static void GLDrawSingleFaceField(const FaceType &f,
00049 CoordType pos,
00050 ScalarType &size,
00051 bool onlyPD1=false,
00052 bool oneside=false)
00053 {
00054 CoordType center=pos;
00055 CoordType normal=f.cN();
00056 CoordType dir[4];
00057 vcg::tri::CrossField<MeshType>::CrossVector(f,dir);
00058 GLDrawField(dir,center,size,onlyPD1,oneside);
00059 }
00060
00062 static void GLDrawSingleFaceField(const FaceType &f,
00063 ScalarType &size,
00064 bool onlyPD1=false,
00065 bool oneside=false)
00066 {
00067 CoordType center=(f.cP(0)+f.cP(1)+f.cP(2))/3;
00068 CoordType normal=f.cN();
00069 CoordType dir[4];
00070 vcg::tri::CrossField<MeshType>::CrossVector(f,dir);
00071 GLDrawField(dir,center,size,onlyPD1,oneside);
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 static void GLDrawVertField(const VertexType &v,
00092 ScalarType &size)
00093 {
00094 CoordType center=v.cP();
00095 CoordType normal=v.cN();
00096 CoordType dir[4];
00097 vcg::tri::CrossField<MeshType>::CrossVector(v,dir);
00098 GLDrawField(dir,center,size);
00099 }
00100
00101
00102 static void GLDrawFaceField(const MeshType &mesh,
00103 bool onlyPD1=false,
00104 bool oneside=false,
00105 ScalarType scale=0.002)
00106 {
00107
00108 glPushAttrib(GL_ALL_ATTRIB_BITS);
00109 glDepthRange(0.0,0.999);
00110 glEnable(GL_COLOR_MATERIAL);
00111 glDisable(GL_LIGHTING);
00112 glDisable(GL_BLEND);
00113 ScalarType size=mesh.bbox.Diag()*scale;
00114 for (unsigned int i=0;i<mesh.face.size();i++)
00115 {
00116 if (mesh.face[i].IsD())continue;
00117 GLDrawSingleFaceField(mesh.face[i],size,onlyPD1,oneside);
00118 }
00119 glPopAttrib();
00120 }
00121
00122 static void GLDrawVertField(const MeshType &mesh,ScalarType sizeF=0.01)
00123 {
00124 glPushAttrib(GL_ALL_ATTRIB_BITS);
00125 glDepthRange(0.0,0.9999);
00126 glEnable(GL_COLOR_MATERIAL);
00127 glDisable(GL_LIGHTING);
00128 glDisable(GL_BLEND);
00129 ScalarType size=mesh.bbox.Diag()*sizeF;
00130 for (int i=0;i<mesh.vert.size();i++)
00131 {
00132 if (mesh.vert[i].IsD())continue;
00133 GLDrawVertField(mesh.vert[i],size);
00134 }
00135 glPopAttrib();
00136 }
00137
00138 static void GLDrawSingularity(MeshType &mesh)
00139 {
00140
00141 bool hasSingular = vcg::tri::HasPerVertexAttribute(mesh,std::string("Singular"));
00142 bool hasSingularIndex = vcg::tri::HasPerVertexAttribute(mesh,std::string("SingularIndex"));
00143
00144 if (!hasSingular)return;
00145 if(!hasSingularIndex)return;
00146
00147 typename MeshType::template PerVertexAttributeHandle<bool> Handle_Singular;
00148 Handle_Singular=vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<bool>(mesh,std::string("Singular"));
00149 typename MeshType::template PerVertexAttributeHandle<int> Handle_SingularIndex;
00150 Handle_SingularIndex =vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<int>(mesh,std::string("SingularIndex"));
00151
00152 glPushAttrib(GL_ALL_ATTRIB_BITS);
00153
00154 glDepthRange(0.0,0.9999);
00155 glEnable(GL_COLOR_MATERIAL);
00156 glDisable(GL_LIGHTING);
00157 glDisable(GL_BLEND);
00158 glPointSize(10);
00159 glBegin(GL_POINTS);
00160 for (size_t i=0;i<mesh.vert.size();i++)
00161 {
00162 if (mesh.vert[i].IsD())continue;
00163 if (!Handle_Singular[i])continue;
00164
00165
00166 int SingIndex=Handle_SingularIndex[i];
00167
00168 vcg::Color4b colSing;
00169
00170 switch (SingIndex)
00171 {
00172 case 1:colSing=vcg::Color4b(0,0,255,255); break;
00173 case 2:colSing=vcg::Color4b(0,255,0,255); break;
00174 case 3:colSing=vcg::Color4b(255,0,0,255); break;
00175 case 4:colSing=vcg::Color4b(255,255,0,255); break;
00176 default:colSing=vcg::Color4b(255,0,255,255);
00177 }
00178
00179
00180 vcg::glColor(colSing);
00181 vcg::glVertex(mesh.vert[i].P());
00182 }
00183 glEnd();
00184 glPopAttrib();
00185 }
00186 };
00187
00188 }
00189
00190 #endif