diff --git a/Common/Context.h b/Common/Context.h
index c8dad77afbebd6b9776b8992cd2dae111d7ba924..da6b16ac4973d6a9512841d031445f229312a506 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -34,7 +34,8 @@ struct contextMeshOptions {
   int lcFromPoints, lcFromCurvature, lcExtendFromBoundary;
   int dual, voronoi, drawSkinOnly, colorCarousel, labelSampling;
   int fileFormat, nbSmoothing, algo2d, algo3d, algoSubdivide;
-  int algoRecombine, recombineAll, recombine3DAll, flexibleTransfinite;
+  int algoRecombine, recombineAll, recombine3DAll, recombine3DLevel, recombine3DConformity;
+  int flexibleTransfinite;
   //-- for recombination test (amaury) --
     int doRecombinationTest, recombinationTestStart;
     int recombinationTestNoGreedyStrat, recombinationTestNewStrat;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 10c36cba74e01445cba47b66e5813dabb7756f0c..8d97bb47952c6b509b09511a47d1f9bf3d0aec8a 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1180,6 +1180,10 @@ StringXNumber MeshOptions_Number[] = {
     "Apply recombination algorithm to all surfaces, ignoring per-surface spec" },
   { F|O, "Recombine3DAll" , opt_mesh_recombine3d_all , 0 ,
     "Apply recombination3D algorithm to all volumes, ignoring per-volume spec" },
+  { F|O, "Recombine3DLevel" , opt_mesh_recombine3d_level , 0 ,
+    "3d recombination level (0: hex, 1: hex+prisms, 2: hex+prism+pyramids)" },
+  { F|O, "Recombine3DConformity" , opt_mesh_recombine3d_conformity , 0 ,
+    "3d recombination conformity type (0: nonconforming, 1: conformity using trihedra, 2: conformity using pyramids)" },
   { F|O, "DoRecombinationTest" , opt_mesh_do_recombination_test , 0 ,
     "Apply recombination algorithm for test" },
   { F|O, "RecombinationTestHorizStart" , opt_mesh_recombination_test_start , 1 ,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 5e0170cc31ce5eb55b7dcdcc31347259c7b3cbea..6a46c32432fcba3066d915c603b5195133f416c9 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5743,6 +5743,34 @@ double opt_mesh_recombine3d_all(OPT_ARGS_NUM)
   return CTX::instance()->mesh.recombine3DAll;
 }
 
+double opt_mesh_recombine3d_level(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET){
+    CTX::instance()->mesh.recombine3DLevel = (int)val;
+  }
+#if defined(HAVE_FLTK)
+  if(FlGui::available() && (action & GMSH_GUI)){
+    FlGui::instance()->options->mesh.butt[22]->value
+      (CTX::instance()->mesh.recombine3DLevel);
+  }
+#endif
+  return CTX::instance()->mesh.recombine3DLevel;
+}
+
+double opt_mesh_recombine3d_conformity(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET){
+    CTX::instance()->mesh.recombine3DConformity = (int)val;
+  }
+#if defined(HAVE_FLTK)
+  if(FlGui::available() && (action & GMSH_GUI)){
+    FlGui::instance()->options->mesh.butt[22]->value
+      (CTX::instance()->mesh.recombine3DConformity);
+  }
+#endif
+  return CTX::instance()->mesh.recombine3DConformity;
+}
+
 double opt_mesh_flexible_transfinite(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
diff --git a/Common/Options.h b/Common/Options.h
index 0f3f076fad9436b46c723eb566feaa11683fc7e3..6e5cd7a76b52ad224a31ff5ee524e7078b18b452 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -465,6 +465,8 @@ double opt_mesh_algo3d(OPT_ARGS_NUM);
 double opt_mesh_algo_recombine(OPT_ARGS_NUM);
 double opt_mesh_recombine_all(OPT_ARGS_NUM);
 double opt_mesh_recombine3d_all(OPT_ARGS_NUM);
+double opt_mesh_recombine3d_level(OPT_ARGS_NUM);
+double opt_mesh_recombine3d_conformity(OPT_ARGS_NUM);
 double opt_mesh_flexible_transfinite(OPT_ARGS_NUM);
 double opt_mesh_do_recombination_test(OPT_ARGS_NUM);
 double opt_mesh_recombination_test_start(OPT_ARGS_NUM);
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 2b6476758c434c0ab9560082fe70534e4d911992..a3a2c2c5c14d1b0c7d29936cb5a5f40e581b81a4 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -532,12 +532,16 @@ static void Mesh3D(GModel *m)
       if(treat_region_ok && (CTX::instance()->mesh.recombine3DAll ||
                              gr->meshAttributes.recombine3D)){
         double a = Cpu();
-        Recombinator rec;
-        rec.execute(gr);
-        Supplementary sup;
-        sup.execute(gr);
+        if (CTX::instance()->mesh.recombine3DLevel >= 0){
+          Recombinator rec;
+          rec.execute(gr);
+        }
+        if (CTX::instance()->mesh.recombine3DLevel >= 1){
+          Supplementary sup;
+          sup.execute(gr);
+        }
         PostOp post;
-        post.execute(gr,0, true); //0: no pyramid, 1: single-step, 2: two-steps (conforming), true: fill non-conformities with trihedra
+        post.execute(gr,CTX::instance()->mesh.recombine3DLevel, CTX::instance()->mesh.recombine3DConformity); //0: no pyramid, 1: single-step, 2: two-steps (conforming), true: fill non-conformities with trihedra
         nb_elements_recombination += post.get_nb_elements();
         nb_hexa_recombination += post.get_nb_hexahedra();
         vol_element_recombination += post.get_vol_elements();
diff --git a/Mesh/yamakawa.cpp b/Mesh/yamakawa.cpp
index d7b82b4549a28620c78c49ea60530d99a91b3003..5fe1f8de2c153afb6db5ef21484dd433e435a966 100644
--- a/Mesh/yamakawa.cpp
+++ b/Mesh/yamakawa.cpp
@@ -4882,7 +4882,7 @@ PostOp::PostOp(){}
 
 PostOp::~PostOp(){}
 
-void PostOp::execute(int level, bool insertTrihedra){
+void PostOp::execute(int level, int conformity){
   GRegion* gr;
   GModel* model = GModel::current();
   GModel::riter it;
@@ -4891,41 +4891,38 @@ void PostOp::execute(int level, bool insertTrihedra){
     {
       gr = *it;
       if(gr->getNumMeshElements()>0){
-        execute(gr,level, insertTrihedra);
+        execute(gr,level, conformity);
       }
     }
 }
 
-void PostOp::execute(GRegion* gr,int level,bool insertTrihedra){
+void PostOp::execute(GRegion* gr,int level, int conformity){
   printf("................PYRAMIDS................\n");
   estimate1 = 0;
   estimate2 = 0;
   iterations = 0;
 
   build_tuples(gr);
-  if (level >= 1){
+  if (level >= 2){
     init_markings(gr);
     build_vertex_to_tetrahedra(gr);
     pyramids1(gr);
     rearrange(gr);
   }
 
-  if(level >= 2){
+  if (conformity == 1){
     init_markings(gr);
     build_vertex_to_tetrahedra(gr);
     build_vertex_to_pyramids(gr);
-    pyramids2(gr);
+    trihedra(gr);
     rearrange(gr);
-  }
-
-  if (insertTrihedra){
+  } else if(conformity == 2){
     init_markings(gr);
     build_vertex_to_tetrahedra(gr);
     build_vertex_to_pyramids(gr);
-    trihedra(gr);
+    pyramids2(gr);
     rearrange(gr);
-  }
-    
+  }    
 
   statistics(gr);
 
diff --git a/Mesh/yamakawa.h b/Mesh/yamakawa.h
index ec7b9b07ae33ba572cd5209c131eea315785a291..292166beb38bbe68abea16732f6d9b57b29fb74b 100644
--- a/Mesh/yamakawa.h
+++ b/Mesh/yamakawa.h
@@ -623,9 +623,10 @@ public:
   PostOp();
   ~PostOp();
 
-  void execute(int, bool);
-  //0: no pyramid, 1: single-step, 2: two-steps (conforming), true: fill non-conformities with trihedra
-  void execute(GRegion*,int level, bool addTrihedra);
+  void execute(int, int);
+  //level: 0,1=no pyramid 2=pyramids
+  //conformity= 0=nonconforming, 1=conformity using trihedra, 2=conformity using pyramids
+  void execute(GRegion*,int level, int conformity);
 
   inline int get_nb_hexahedra()const{return nbr8;};
   inline double get_vol_hexahedra()const{return vol8;};
diff --git a/benchmarks/3d/Submarine/Submarine.geo b/benchmarks/3d/Submarine/Submarine.geo
index e592c80a88f7f5ac337495486b786a565c9ffe3c..4de39b39d6109131578d0056d7bb663f11acc2b1 100644
--- a/benchmarks/3d/Submarine/Submarine.geo
+++ b/benchmarks/3d/Submarine/Submarine.geo
@@ -5,6 +5,10 @@ Mesh.Algorithm=9;
 Mesh.Algorithm3D=9;
 Mesh.Smoothing=0;
 Mesh.Recombine3DAll=1;
+//0: hex, 1: hex+prisms, 2: hex+prism+pyramids
+Mesh.Recombine3DLevel = 1;
+//0: nonconforming, 1: conformity using trihedra, 2: conformity using pyramids
+Mesh.Recombine3DConformity = 1;
 Mesh.SaveParametric = 1;
 
 MeshAlgorithm Surface {12}  5; //Not in final mesh