关于Gmsh如何实现三角形合并为四边形的测试,显示效果用OSG

之前因为成功调用了Gmsh的API进行网格划分,效果也还不错,考虑到都是三角形或者四面体,突然有种想法就是怎么实现四边形或者六面体,在查看Gmsh的PDF文档时候发现,Gmsh和Netgen一样具有将三角形合并为四边形的功能,于是我在参考Gmsh的C++例子中找到了一些有效信息,这些例子在PDF文档中也提到过,核心就是recombine选项开启,例子如下:

//

// -----------------------------------------------------------------------------
//
//  Gmsh C++ tutorial 11
//
//  Unstructured quadrangular meshes
//
// -----------------------------------------------------------------------------

#include
#include

int main(int argc, char **argv)
{
  gmsh::initialize();

  gmsh::model::add("t11");

  // We have seen in tutorials `t3.cpp' and `t6.cpp' that extruded and
  // transfinite meshes can be "recombined" into quads, prisms or
  // hexahedra. Unstructured meshes can be recombined in the same way. Let's
  // define a simple geometry with an analytical mesh size field:

  int p1 = gmsh::model::geo::addPoint(-1.25, -.5, 0);
  int p2 = gmsh::model::geo::addPoint(1.25, -.5, 0);
  int p3 = gmsh::model::geo::addPoint(1.25, 1.25, 0);
  int p4 = gmsh::model::geo::addPoint(-1.25, 1.25, 0);

  int l1 = gmsh::model::geo::addLine(p1, p2);
  int l2 = gmsh::model::geo::addLine(p2, p3);
  int l3 = gmsh::model::geo::addLine(p3, p4);
  int l4 = gmsh::model::geo::addLine(p4, p1);

  int cl = gmsh::model::geo::addCurveLoop({l1, l2, l3, l4});
  int pl = gmsh::model::geo::addPlaneSurface({cl});

  gmsh::model::geo::synchronize();

  gmsh::model::mesh::field::add("MathEval", 1);
  gmsh::model::mesh::field::setString(
    1, "F", "0.01*(1.0+30.*(y-x*x)*(y-x*x) + (1-x)*(1-x))");
  gmsh::model::mesh::field::setAsBackgroundMesh(1);

  // To generate quadrangles instead of triangles, we can simply add
  gmsh::model::mesh::setRecombine(2, pl);

  // If we'd had several surfaces, we could have used the global option
  // "Mesh.RecombineAll":
  //
  // gmsh::option::setNumber("Mesh.RecombineAll", 1);

  // The default recombination algorithm is called "Blossom": it uses a minimum
  // cost perfect matching algorithm to generate fully quadrilateral meshes from
  // triangulations. More details about the algorithm can be found in the
  // following paper: J.-F. Remacle, J. Lambrechts, B. Seny, E. Marchandise,
  // A. Johnen and C. Geuzaine, "Blossom-Quad: a non-uniform quadrilateral mesh
  // generator using a minimum cost perfect matching algorithm", International
  // Journal for Numerical Methods in Engineering 89, pp. 1102-1119, 2012.

  // For even better 2D (planar) quadrilateral meshes, you can try the
  // experimental "Frontal-Delaunay for quads" meshing algorithm, which is a
  // triangulation algorithm that enables to create right triangles almost
  // everywhere: J.-F. Remacle, F. Henrotte, T. Carrier-Baudouin, E. Bechet,
  // E. Marchandise, C. Geuzaine and T. Mouton. A frontal Delaunay quad mesh
  // generator using the L^inf norm. International Journal for Numerical Methods
  // in Engineering, 94, pp. 494-512, 2013. Uncomment the following line to try
  // the Frontal-Delaunay algorithms for quads:
  //
  // gmsh::option::setNumber("Mesh.Algorithm", 8);

  // The default recombination algorithm might leave some triangles in the mesh,
  // if recombining all the triangles leads to badly shaped quads. In such
  // cases, to generate full-quad meshes, you can either subdivide the resulting
  // hybrid mesh (with `Mesh.SubdivisionAlgorithm' set to 1), or use the
  // full-quad recombination algorithm, which will automatically perform a
  // coarser mesh followed by recombination, smoothing and
  // subdivision. Uncomment the following line to try the full-quad algorithm:
  //
  // gmsh::option::setNumber("Mesh.RecombinationAlgorithm", 2); // or 3

  // You can also set the subdivision step alone, with
  //
  // gmsh::option::setNumber("Mesh.SubdivisionAlgorithm", 1);

  gmsh::model::mesh::generate(2);

  // Note that you could also apply the recombination algorithm and/or the
  // subdivision step explicitly after meshing, as follows:
  //
  // gmsh::model::mesh::generate(2);
  // gmsh::model::mesh::recombine();
  // gmsh::option::setNumber("Mesh.SubdivisionAlgorithm", 1);
  // gmsh::model::mesh::refine();

  // Launch the GUI to see the results:
  std::set args(argv, argv + argc);
  if(!args.count("-nopopup")) gmsh::fltk::run();

  gmsh::finalize();
  return 0;
}

//

大概可以总结为2句:gmsh::model::geo::mesh::setRecombine(dim,tag),当前仅支持dim = 2; gmsh::option::setNumber("Mesh.RecombineAll", 1);对有所的surface有效。划分完成后,获取Node 和 Eement的方法可以参考我前面的文章,比较简单。OSG显示效果展示如下:

关于Gmsh如何实现三角形合并为四边形的测试,显示效果用OSG_第1张图片

关于Gmsh如何实现三角形合并为四边形的测试,显示效果用OSG_第2张图片

 

效果中可以看见,大部分的三角形合并成了四边形,但是也有少数的三角形没有成功,这个问题暂时不得而知,在Gmsh中也出现过这样的现象,所以暂时不作处理。

最近参考了下开源的SALOME软件,SALOME是一个基于Opencascade内核的CAD/CAE程序,其网格划分功能还是很丰富的,而且效果好像也不错,考虑将其SMESH集成进来。如果有知道怎么处理部分三角形合并失败的朋友、老师,请指教,感激不尽。

你可能感兴趣的:(OpenCascade,OSG,negtgen,gmesh,图形学,3d)