diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp
index e3d2a25ca298ee17caf36fab0fb648d2cb082857..9a0be8f95293996fe0dd823b28f7b39502a70ed7 100644
--- a/Plugin/AnalyseCurvedMesh.cpp
+++ b/Plugin/AnalyseCurvedMesh.cpp
@@ -7,6 +7,7 @@
 
 #if defined(HAVE_MESH)
 
+
 #include "AnalyseCurvedMesh.h"
 #include "OS.h"
 #include "Context.h"
@@ -30,14 +31,14 @@
 class bezierBasis;
 
 StringXNumber CurvedMeshOptions_Number[] = {
-  {GMSH_FULLRC, "Jacobian determinant", NULL, 1},
-  {GMSH_FULLRC, "IGE measure", NULL, 1},
+  {GMSH_FULLRC, "Jacobian determinant", NULL, 2},
+  {GMSH_FULLRC, "IGE measure", NULL, 2},
   {GMSH_FULLRC, "ICN measure", NULL, 1},
   {GMSH_FULLRC, "Hiding threshold", NULL, 9},
   {GMSH_FULLRC, "Draw PView", NULL, 0},
   {GMSH_FULLRC, "Recompute", NULL, 1},
   {GMSH_FULLRC, "Dimension of elements", NULL, -1},
-  {GMSH_FULLRC, "Element to print quality", NULL, -7}
+  {GMSH_FULLRC, "Element to draw quality", NULL, -1}
 };
 
 extern "C"
@@ -105,22 +106,23 @@ std::string GMSH_AnalyseCurvedMeshPlugin::getHelp() const
 PView* GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
 {
   _m = GModel::current();
-  bool computeJac = static_cast<int>(CurvedMeshOptions_Number[0].def);
-  bool computeIGE = static_cast<int>(CurvedMeshOptions_Number[1].def);
-  bool computeICN = static_cast<int>(CurvedMeshOptions_Number[2].def);
-  _threshold      = static_cast<double>(CurvedMeshOptions_Number[3].def);
-  bool drawPView  = static_cast<int>(CurvedMeshOptions_Number[4].def);
-  bool recompute  = static_cast<bool>(CurvedMeshOptions_Number[5].def);
-  int askedDim    = static_cast<int>(CurvedMeshOptions_Number[6].def);
+  int computeJac = static_cast<int>(CurvedMeshOptions_Number[0].def);
+  int computeIGE = static_cast<int>(CurvedMeshOptions_Number[1].def);
+  int computeICN = static_cast<int>(CurvedMeshOptions_Number[2].def);
+  _threshold     = CurvedMeshOptions_Number[3].def;
+  bool drawPView = static_cast<bool>(CurvedMeshOptions_Number[4].def);
+  bool recompute = static_cast<bool>(CurvedMeshOptions_Number[5].def);
+  int askedDim   = static_cast<int>(CurvedMeshOptions_Number[6].def);
+
+  _pwJac = computeJac/2;
+  _pwIGE = computeIGE/2;
+  _pwICN = computeICN/2;
 
   _numElementToScan = static_cast<int>(CurvedMeshOptions_Number[7].def);
-  _viewOrder = 10;
-  _elementToScan = NULL;
-//  _hoElement = NULL;
-  for (int type = 0; type < 20; ++type) {
-//    _allElem[type].clear();
-    _dataPViewJacAllElements[type].clear();
-  }
+  _viewOrder = 0;
+  _dataPViewJac.clear();
+  _dataPViewIGE.clear();
+  _dataPViewICN.clear();
 
   if (askedDim < 0 || askedDim > 4) askedDim = _m->getDim();
 
@@ -180,7 +182,7 @@ PView* GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
   if (printStatS) _printStatIGE();
   if (printStatI) _printStatICN();
 
-  _createPViewElementToScan();
+  _createPViewPointwise();
 
   // Create PView
   if (drawPView)
@@ -362,7 +364,7 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinMaxJandValidity(int dim)
       if (min < 0 && max < 0) ++cntInverted;
       progress.next();
 
-      _computeJacobianToScan(el, entity, normals);
+      _computePointwiseQuantities(el, normals);
     }
     delete normals;
   }
@@ -536,215 +538,81 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatICN()
             infminI, avgminI, supminI);
 }
 
-void GMSH_AnalyseCurvedMeshPlugin::_computeJacobianToScan(MElement *el,
-                                                          GEntity *entity,
-                                                          const fullMatrix<double> *normals)
-{
-  if (_numElementToScan != -7 && el->getNum() != _numElementToScan) return;
-
-  _entity = entity;
-  _elementToScan = el;
-//  fullMatrix<double> points =
-//          _elementToScan->getFunctionSpace(_viewOrder)->points;
-//  int tag = ElementType::getTag(_elementToScan->getType(), _viewOrder);
-//  std::vector<MVertex *> v;
-//  for (int k = 0; k < points.size1(); k++) {
-//    double t1 = points(k, 0);
-//    double t2 = points(k, 1);
-//    double t3 = points(k, 2);
-//    SPoint3 pos;
-//    _elementToScan->pnt(t1, t2, t3, pos);
-//    v.push_back(new MVertex(pos.x(), pos.y(), pos.z()));
-//  }
-//  MElementFactory factory;
-//  _hoElement = factory.create(tag, v);
-
-  fullVector<double> jac;
-  jacobianBasedQuality::sampleJacobian(_elementToScan, _viewOrder,
-                                       jac, normals);
-  _jacElementToScan.clear();
-  for (int j = 0; j < jac.size(); ++j) {
-    _jacElementToScan.push_back(jac(j));
+void GMSH_AnalyseCurvedMeshPlugin::_computePointwiseQuantities(MElement *el,
+                                                               const fullMatrix<double> *normals) {
+  if (_numElementToScan != -1 && el->getNum() != _numElementToScan) return;
+
+  if (!_type2tag[el->getType()])
+    _type2tag[el->getType()] = el->getTypeForMSH();
+  else
+    // Skip if element tag is different from previous elements of same type
+    if (_type2tag[el->getType()] != el->getTypeForMSH()) return;
+
+  static fullVector<double> tmpVector;
+  int num = el->getNum();
+
+  if (!_viewOrder) {
+//    _viewOrder = 2 * el->getPolynomialOrder();
+    _viewOrder = 10;
   }
 
-  if (_numElementToScan == -7) {
-    const int type = el->getType();
-//    _allElem[type].push_back(std::make_pair(el, _hoElement));
-    _allElem[type].push_back(std::make_pair(el, el));
-//    _dataPViewJacAllElements[type][_hoElement->getNum()] = _jacElementToScan;
-    _dataPViewJacAllElements[type][_elementToScan->getNum()] = _jacElementToScan;
+  if (_pwJac) {
+    jacobianBasedQuality::sampleJacobian(el, _viewOrder, tmpVector, normals);
+    std::vector<double> &vec = _dataPViewJac[num];
+    for (int j = 0; j < tmpVector.size(); ++j)
+      vec.push_back(tmpVector(j));
+  }
+
+  if (_pwIGE) {
+    jacobianBasedQuality::sampleIGEMeasure(el, _viewOrder, tmpVector);
+    std::vector<double> &vec = _dataPViewIGE[num];
+    for (int j = 0; j < tmpVector.size(); ++j)
+      vec.push_back(tmpVector(j));
+  }
+
+  if (_pwICN) {
+//    jacobianBasedQuality::sampleICNMeasure(el, _viewOrder, tmpVector);
+//    std::vector<double> &vec = _dataPViewICN[num];
+//    for (int j = 0; j < tmpVector.size(); ++j)
+//      vec.push_back(tmpVector(j));
   }
 }
 
-void GMSH_AnalyseCurvedMeshPlugin::_addElementInEntity(MElement *element,
-                                                       GEntity *entity)
+void GMSH_AnalyseCurvedMeshPlugin::_setInterpolationMatrices(PView *view)
 {
-  int dim = entity->dim();
-  switch (dim) {
-  case 1:
-    {
-      GEdge *gedge = dynamic_cast<GEdge*>(entity);
-      int type = element->getType();
-      switch (type) {
-        case TYPE_LIN:
-          gedge->lines.push_back(dynamic_cast<MLine*>(element));
-      }
-    }
-    break;
-  case 2:
-    {
-      GFace *gface = dynamic_cast<GFace*>(entity);
-      int type = element->getType();
-      switch (type) {
-        case TYPE_TRI:
-          gface->triangles.push_back(dynamic_cast<MTriangle*>(element));
-          break;
-        case TYPE_QUA:
-          gface->quadrangles.push_back(dynamic_cast<MQuadrangle*>(element));
-          break;
-      }
-    }
-    break;
-  case 3:
-    {
-      GRegion *gregion = dynamic_cast<GRegion*>(entity);
-      int type = element->getType();
-      switch (type) {
-        case TYPE_TET:
-          gregion->tetrahedra.push_back(dynamic_cast<MTetrahedron*>(element));
-          break;
-        case TYPE_HEX:
-          gregion->hexahedra.push_back(dynamic_cast<MHexahedron*>(element));
-          break;
-        case TYPE_PRI:
-          gregion->prisms.push_back(dynamic_cast<MPrism*>(element));
-          break;
-      }
-    }
-    break;
+  PViewData *viewData = view->getData();
+  for (int type = 0; type < 20; ++type) {
+    if (!_type2tag[type]) continue;
+    viewData->deleteInterpolationMatrices(type);
+    const nodalBasis *fsE = BasisFactory::getNodalBasis(_type2tag[type]);
+    const polynomialBasis *pfsE = dynamic_cast<const polynomialBasis *>(fsE);
+    const int hoTag = ElementType::getTag(type, _viewOrder);
+    const nodalBasis *fsV = BasisFactory::getNodalBasis(hoTag);
+    const polynomialBasis *pfsV = dynamic_cast<const polynomialBasis *>(fsV);
+    viewData->setInterpolationMatrices(type,
+                                       pfsV->coefficients, pfsV->monomials,
+                                       pfsE->coefficients, pfsE->monomials);
   }
 }
 
-void GMSH_AnalyseCurvedMeshPlugin::_createPViewElementToScan()
+void GMSH_AnalyseCurvedMeshPlugin::_createPViewPointwise()
 {
-//  if (!_hoElement) return;
-
-  // Jacobian determinant
-  std::map<int, std::vector<double>> dataPView;
-  std::stringstream name;
-  if (_numElementToScan != -7) {
-//    const nodalBasis *fs = BasisFactory::getNodalBasis(_hoElement->getTypeForMSH());
-//    const polynomialBasis *pfs = dynamic_cast<const polynomialBasis*>(fs);
-//
-//    dataPView[_hoElement->getNum()] = _jacElementToScan;
-//    name.str(std::string());
-//    name << "Jacobian elem " << _numElementToScan;
-//    _addElementInEntity(_hoElement, _entity);
-//    PView *view = new PView(name.str().c_str(), "ElementNodeData",
-//                            _m, dataPView, 0, 1);
-//    PViewData *viewData = view->getData();
-//    viewData->deleteInterpolationMatrices(_hoElement->getType());
-//    viewData->setInterpolationMatrices(_hoElement->getType(),
-//                                       pfs->coefficients, pfs->monomials,
-//                                       pfs->coefficients, pfs->monomials);
-  }
-  else {
-    for (int type = 0; type < 20; ++type) {
-      if (_dataPViewJacAllElements[type].empty()) continue;
-//      for (int i = 0; i < _allElem[type].size(); ++i) {
-//        _addElementInEntity(_allElem[type][i].second, _entity);
-//      }
-      name.str(std::string());
-      name << "Jacobian all ";
-      switch (type) {
-        case TYPE_TRI: name << "triangles"; break;
-        case TYPE_QUA: name << "quadrangles"; break;
-        default: name << "?"; break;
-      }
-      PView *view = new PView(name.str().c_str(), "ElementNodeData",
-                              _m, _dataPViewJacAllElements[type], 0, 1);
-      PViewData *viewData = view->getData();
-      viewData->deleteInterpolationMatrices(type);
-
-//      const int hoTag = _allElem[type][0].second->getTypeForMSH();
-//      const nodalBasis *fs = BasisFactory::getNodalBasis(hoTag);
-//      const polynomialBasis *pfs = dynamic_cast<const polynomialBasis*>(fs);
-//      viewData->setInterpolationMatrices(type,
-//                                         pfs->coefficients, pfs->monomials,
-//                                         pfs->coefficients, pfs->monomials);
-      const nodalBasis *fsE = BasisFactory::getNodalBasis(_allElem[type][0].first->getTypeForMSH());
-      const polynomialBasis *pfsE = dynamic_cast<const polynomialBasis*>(fsE);
-      const int hoTag = ElementType::getTag(type, _viewOrder);
-      const nodalBasis *fsV = BasisFactory::getNodalBasis(hoTag);
-      const polynomialBasis *pfsV = dynamic_cast<const polynomialBasis*>(fsV);
-      viewData->setInterpolationMatrices(type,
-                                         pfsV->coefficients, pfsV->monomials,
-                                         pfsE->coefficients, pfsE->monomials);
-    }
+  if (_pwJac) {
+    _setInterpolationMatrices(
+        new PView("Pointwise Jacobian", "ElementNodeData", _m, _dataPViewJac, 0, 1)
+    );
   }
 
-  // Quality measures
-  fullVector<double> ige;
-  if (_numElementToScan != -7) {
-//    jacobianBasedQuality::sampleIGEMeasure(_elementToScan, _viewOrder, ige);
-//    dataPView.clear();
-//    for (int j = 0; j < ige.size(); ++j) {
-//      dataPView[_hoElement->getNum()].push_back(ige(j));
-//    }
-//    name.str(std::string());
-//    name << "IGE elem " << _numElementToScan;
-//    PView *view = new PView(name.str().c_str(), "ElementNodeData",
-//                            _m, dataPView, 0, 1);
-//    PViewData *viewData = view->getData();
-//    viewData->deleteInterpolationMatrices(_hoElement->getType());
-//    viewData->setInterpolationMatrices(_hoElement->getType(),
-//                                       pfs->coefficients, pfs->monomials,
-//                                       pfs->coefficients, pfs->monomials);
+  if (_pwIGE) {
+    _setInterpolationMatrices(
+        new PView("Pointwise IGE", "ElementNodeData", _m, _dataPViewIGE, 0, 1)
+    );
   }
-  else {
-    for (int type = 0; type < 20; ++type) {
-      if (_allElem[type].empty()) continue;
-      dataPView.clear();
-
-      for (int i = 0; i < _allElem[type].size(); ++i) {
-        MElement *loElement = _allElem[type][i].first;
-        MElement *hoElement = _allElem[type][i].second;
-        jacobianBasedQuality::sampleIGEMeasure(loElement, _viewOrder, ige);
-        for (int j = 0; j < ige.size(); ++j) {
-          dataPView[hoElement->getNum()].push_back(ige(j));
-        }
-      }
-
-      name.str(std::string());
-      name << "IGE all ";
-      switch (type) {
-        case TYPE_TRI: name << "triangles"; break;
-        case TYPE_QUA: name << "quadrangles"; break;
-        default: name << "?"; break;
-      }
-      PView *view = new PView(name.str().c_str(), "ElementNodeData",
-                              _m, dataPView, 0, 1);
-      PViewData *viewData = view->getData();
-      viewData->deleteInterpolationMatrices(type);
-
-//      const int hoTag = _allElem[type][0].second->getTypeForMSH();
-//      const nodalBasis *fs = BasisFactory::getNodalBasis(hoTag);
-//      const polynomialBasis *pfs = dynamic_cast<const polynomialBasis*>(fs);
-//      viewData->setInterpolationMatrices(type,
-//                                         pfs->coefficients, pfs->monomials,
-//                                         pfs->coefficients, pfs->monomials);
-      const nodalBasis *fsE = BasisFactory::getNodalBasis(_allElem[type][0].first->getTypeForMSH());
-      const polynomialBasis *pfsE = dynamic_cast<const polynomialBasis*>(fsE);
-      const int hoTag = ElementType::getTag(type, _viewOrder);
-      const nodalBasis *fsV = BasisFactory::getNodalBasis(hoTag);
-      const polynomialBasis *pfsV = dynamic_cast<const polynomialBasis*>(fsV);
-      viewData->setInterpolationMatrices(type,
-                                         pfsV->coefficients, pfsV->monomials,
-                                         pfsE->coefficients, pfsE->monomials);
-    }
-
 
-    name << "IGE all elem";
+  if (_pwICN) {
+    _setInterpolationMatrices(
+        new PView("Pointwise ICN", "ElementNodeData", _m, _dataPViewICN, 0, 1)
+    );
   }
 }
 
diff --git a/Plugin/AnalyseCurvedMesh.h b/Plugin/AnalyseCurvedMesh.h
index dbc906a021dfb658931aca89bd08e201048e6408..358f03ed139a86ce25586d34ce33b6e54bd184de 100644
--- a/Plugin/AnalyseCurvedMesh.h
+++ b/Plugin/AnalyseCurvedMesh.h
@@ -22,11 +22,9 @@ private:
   double _minJac, _maxJac, _minIGE, _minICN;
 public:
   data_elementMinMax(MElement *e,
-                     double minJ = 2,
-                     double maxJ = 0,
-                     double minIGE = -1,
-                     double minICN = -1)
-    : _el(e), _minJac(minJ), _maxJac(maxJ), _minIGE(minIGE), _minICN(minICN) {}
+                     double minJ = 2, double maxJ = 0,
+                     double minIGE = -1, double minICN = -1)
+      : _el(e), _minJac(minJ), _maxJac(maxJ), _minIGE(minIGE), _minICN(minICN) {}
   void setMinS(double r) { _minIGE = r; }
   void setMinI(double r) { _minICN = r; }
   MElement* element() { return _el; }
@@ -42,16 +40,14 @@ private :
   GModel *_m;
   double _threshold;
 
-  // Element to scan
+  // Pointwise data
   int _numElementToScan;
-  MElement *_elementToScan, *__hoElement;
-  int _viewOrder;
-  std::vector<double> _jacElementToScan;
-
-  // All elements to scan
-  std::vector<std::pair<MElement*, MElement*>> _allElem[20];
-  std::map<int, std::vector<double>> _dataPViewJacAllElements[20];
-  GEntity *_entity;
+  bool _pwJac, _pwIGE, _pwICN;
+  std::map<int, std::vector<double>> _dataPViewJac;
+  std::map<int, std::vector<double>> _dataPViewIGE;
+  std::map<int, std::vector<double>> _dataPViewICN;
+  int _type2tag[20] = {0};
+  int _viewOrder = 0;
 
   // for 1d, 2d, 3d
   bool _computedJac[3], _computedIGE[3], _computedICN[3];
@@ -93,10 +89,9 @@ private :
   void _printStatIGE();
   void _printStatICN();
 
-  void _computeJacobianToScan(MElement*, GEntity*,
-                              const fullMatrix<double> *normals);
-  void _addElementInEntity(MElement*, GEntity*);
-  void _createPViewElementToScan();
+  void _computePointwiseQuantities(MElement *, const fullMatrix<double> *normals);
+  void _createPViewPointwise();
+  void _setInterpolationMatrices(PView *);
 };
 
 #endif