Esempio n. 1
0
void drawContext::drawMesh()
{
  if(!CTX::instance()->mesh.draw) return;

  // make sure to flag any model-dependent post-processing view as
  // changed if the underlying mesh has, before resetting the changed
  // flag
  if(CTX::instance()->mesh.changed){
    for(unsigned int i = 0; i < GModel::list.size(); i++)
      for(unsigned int j = 0; j < PView::list.size(); j++)
        if(PView::list[j]->getData()->hasModel(GModel::list[i]))
          PView::list[j]->setChanged(true);
  }

  glPointSize((float)CTX::instance()->mesh.pointSize);
  gl2psPointSize((float)(CTX::instance()->mesh.pointSize *
                         CTX::instance()->print.epsPointSizeFactor));

  glLineWidth((float)CTX::instance()->mesh.lineWidth);
  gl2psLineWidth((float)(CTX::instance()->mesh.lineWidth *
                         CTX::instance()->print.epsLineWidthFactor));

  if(CTX::instance()->mesh.lightTwoSide)
    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  else
    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);

  if(!CTX::instance()->clipWholeElements){
    for(int i = 0; i < 6; i++)
      if(CTX::instance()->mesh.clip & (1 << i))
        glEnable((GLenum)(GL_CLIP_PLANE0 + i));
      else
        glDisable((GLenum)(GL_CLIP_PLANE0 + i));
  }

  for(unsigned int i = 0; i < GModel::list.size(); i++){
    GModel *m = GModel::list[i];
    m->fillVertexArrays();
    if(m->getVisibility() && isVisible(m)){
      int status = m->getMeshStatus();
      if(status >= 0)
        std::for_each(m->firstVertex(), m->lastVertex(), drawMeshGVertex(this));
      if(status >= 1)
        std::for_each(m->firstEdge(), m->lastEdge(), drawMeshGEdge(this));
      if(status >= 2){
        beginFakeTransparency();
        std::for_each(m->firstFace(), m->lastFace(), drawMeshGFace(this));
        endFakeTransparency();
      }
      if(status >= 3)
        std::for_each(m->firstRegion(), m->lastRegion(), drawMeshGRegion(this));
    }
  }

  CTX::instance()->mesh.changed = 0;

  for(int i = 0; i < 6; i++)
    glDisable((GLenum)(GL_CLIP_PLANE0 + i));
}
Esempio n. 2
0
void collapseSmallEdges(GModel &gm)
{
  return;
  // gm.renumberMeshVertices(true);
  std::list<GFace*> faces;
  for (GModel::fiter fit = gm.firstFace(); fit != gm.lastFace(); fit++){
    faces.push_back(*fit);
  }
  BDS_Mesh *pm = gmsh2BDS(faces);
  outputScalarField(pm->triangles, "all.pos", 0);

  for (GModel::eiter eit = gm.firstEdge(); eit != gm.lastEdge(); eit++){
  }

  delete pm;
}
Esempio n. 3
0
PView *GMSH_CVTRemeshPlugin::execute(PView *v)
{
  //TODO normalization

  GModel* m = GModel::current() ;

  std::vector<double> vertices ;
  std::vector<unsigned int> faces ;

  unsigned int offset = 0 ;
  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
    (*it)->buildSTLTriangulation() ;
    for(unsigned int i = 0; i < (*it)->stl_vertices.size(); ++i) {
      GPoint p = (*it)->point((*it)->stl_vertices[i]) ;
      vertices.push_back(p.x()) ;
      vertices.push_back(p.y()) ;
      vertices.push_back(p.z()) ;
    }
    for(unsigned int i = 0; i < (*it)->stl_triangles.size(); ++i) {
      faces.push_back((*it)->stl_triangles[i]+offset) ;
    }
    offset += (*it)->stl_vertices.size() ;
  }

  Revoropt::MeshBuilder<3> mesh ;
  mesh.swap_vertices(vertices) ;
  mesh.swap_faces(faces) ;

  double mesh_center[3] ;
  double mesh_scale ;
  Revoropt::normalize_mesh(&mesh, mesh_center, &mesh_scale) ;

  double nradius = (double)CVTRemeshOptions_Number[5].def ;

  //normals
  std::vector<double> normals(3*mesh.vertices_size()) ;
  Revoropt::full_robust_vertex_normals(&mesh,nradius,normals.data()) ;

  //lifted vertices
  std::vector<double> lifted_vertices(6*mesh.vertices_size(), 0) ;
  for(unsigned int vertex = 0; vertex < mesh.vertices_size(); ++vertex) {
    std::copy( mesh.vertex(vertex),
               mesh.vertex(vertex)+3,
               lifted_vertices.data()+6*vertex
             ) ;
    std::copy( normals.data()+3*vertex,
               normals.data()+3*vertex+3,
               lifted_vertices.data()+6*vertex+3
             ) ;
  }

  //setup lifted mesh
  Revoropt::ROMeshWrapper<3,6> lifted_mesh(
    lifted_vertices.data(),
    lifted_vertices.size()/6,
    &mesh
  ) ;

  //triangle weight factor
  double twfactor = (double)CVTRemeshOptions_Number[3].def ;

  //face ratios
  std::vector<double> triangle_weights(lifted_mesh.faces_size()) ;
  if(twfactor > 0) {
    for(unsigned int f = 0; f < lifted_mesh.faces_size(); ++f) {
      //vertices of the initial triangle
      const unsigned int* fverts = mesh.face(f) ;

      //positions
      const double* x[3] ;
      for(int i=0; i<3; ++i) {
        x[i] = lifted_mesh.vertex(fverts[i]) ;
      }

      //ratio
      double ratio = 1 ;

      //vectors
      typedef Eigen::Matrix<double,3,1> Vector3 ;

      Eigen::Map<const Vector3> v0(x[0]) ;
      Eigen::Map<const Vector3> v1(x[1]) ;
      Eigen::Map<const Vector3> v2(x[2]) ;

      //triangle frame
      Vector3 U = (v1-v0) ;
      const double U_len = U.norm() ;
      if(U_len > 0) {
        U /= U_len ;
        Vector3 H = (v2-v0) ;
        H = H - H.dot(U)*U ;
        const double H_len = H.norm() ;
        if(H_len > 0) {
          //we know that the triangle is not flat
          H /= H_len ;

          //gradient of the barycentric weights in the triangle
          Eigen::Matrix<double,3,2> bar_grads ;
          bar_grads(2,0) = 0 ;
          bar_grads(2,1) = 1/H_len ;

          //gradient norms of every normal component
          for(int i = 0; i < 2; ++i) {
            //reference frame for the vertex
            Eigen::Map<const Vector3> vi0(x[(i+1)%3]) ;
            Eigen::Map<const Vector3> vi1(x[(i+2)%3]) ;
            Eigen::Map<const Vector3> vi2(x[ i     ]) ;

            Vector3 Ui = (vi1-vi0) ;
            Ui /= Ui.norm() ;
            Vector3 Hi = (vi2-vi0) ;
            Hi = Hi - Hi.dot(Ui)*Ui ;
            const double Hi_invlen = 1/Hi.norm() ;
            Hi *= Hi_invlen ;
            bar_grads(i,0) = Hi.dot(U)*Hi_invlen ;
            bar_grads(i,1) = Hi.dot(H)*Hi_invlen ;
          }

          //gradient of each component of the normal
          Eigen::Map<const Vector3> n0(x[0]+3) ;
          Eigen::Map<const Vector3> n1(x[1]+3) ;
          Eigen::Map<const Vector3> n2(x[2]+3) ;

          Eigen::Matrix<double,3,2> n_grads = Eigen::Matrix<double,3,2>::Zero() ;

          n_grads = n0*bar_grads.row(0) ;
          n_grads += n1*bar_grads.row(1) ;
          n_grads += n2*bar_grads.row(2) ;

          //maximal gradient norm
          double g_max = n_grads.row(0).dot(n_grads.row(0)) ;
          double g_other = n_grads.row(1).dot(n_grads.row(1)) ;
          g_max = g_max > g_other ? g_max : g_other ;
          g_other = n_grads.row(2).dot(n_grads.row(2)) ;
          g_max = g_max > g_other ? g_max : g_other ;

          if(g_max == g_max) { //prevent nan
            ratio += g_max ;
          }
        }
      }
      triangle_weights[f] = pow(ratio,twfactor) ;
    }
  }

  //normal factor
  double nfactor = (double)CVTRemeshOptions_Number[2].def ; ;

  //weight the normal component by the provided factor
  for(unsigned int i = 0; i<lifted_mesh.vertices_size(); ++i) {
    double* v = lifted_vertices.data() + 6*i ;
    v[3]*= nfactor ;
    v[4]*= nfactor ;
    v[5]*= nfactor ;
  }

  //number of sites
  unsigned int nsites = (unsigned int)CVTRemeshOptions_Number[0].def ;

  //lifted sites
  std::vector<double> lifted_sites(6*nsites) ;
  if(twfactor > 0) {
    Revoropt::generate_random_sites< Revoropt::ROMesh<3,6> >(
      &lifted_mesh, nsites, lifted_sites.data(), triangle_weights.data()
    ) ;
  } else {
    Revoropt::generate_random_sites< Revoropt::ROMesh<3,6> >(
      &lifted_mesh, nsites, lifted_sites.data()
    ) ;
  }

  //setup the cvt minimizer
  Revoropt::CVT::DirectMinimizer< Revoropt::ROMesh<3,6> > cvt ;
  cvt.set_sites(lifted_sites.data(), nsites) ;
  cvt.set_mesh(&lifted_mesh) ;
  if(twfactor > 0) {
    cvt.set_triangle_weights(triangle_weights.data()) ;
  }

  //setup the callback
  SolverCallback callback ;

  //number of iterations
  unsigned int niter = (unsigned int)CVTRemeshOptions_Number[1].def ; ;
  unsigned int aniso_niter = std::min<unsigned int>(10,niter) ;

  //solver status
  int status = 0 ;

  //isotropic iterations
  if(niter > 10) {
    aniso_niter = std::max(aniso_niter,niter*10/100) ;
    cvt.set_anisotropy(1) ;
    status = cvt.minimize<Revoropt::Solver::AlgLBFGS>(niter-aniso_niter, &callback) ;
  }

  //anisotropic iterations
  if(niter > 0) {
    //tangent space anisotropy
    double tanisotropy = (double)CVTRemeshOptions_Number[4].def ; ;

    //anisotropic iterations
    cvt.set_anisotropy(tanisotropy) ;
    status = cvt.minimize<Revoropt::Solver::AlgLBFGS>(aniso_niter, &callback) ;
  }

  //rdt
  std::vector<unsigned int> rdt_triangles ;
  Revoropt::RDTBuilder< Revoropt::ROMesh<3,6> > build_rdt(rdt_triangles) ;
  Revoropt::RVD< Revoropt::ROMesh<3,6> > rvd ;
  rvd.set_sites(lifted_sites.data(), nsites) ;
  rvd.set_mesh(&lifted_mesh) ;
  rvd.compute(build_rdt) ;

  GFace* res_face = new discreteFace(m, m->getMaxElementaryNumber(2)+1) ;
  m->add(res_face) ;

  //scale back and transfer to gmsh
  std::vector<MVertex*> m_verts(nsites) ;
  for(unsigned int i = 0; i < nsites; ++i) {
    m_verts[i] = new MVertex(
        lifted_sites[6*i  ]*mesh_scale + mesh_center[0],
        lifted_sites[6*i+1]*mesh_scale + mesh_center[1],
        lifted_sites[6*i+2]*mesh_scale + mesh_center[2]
        ) ;
    res_face->addMeshVertex(m_verts[i]) ;
  }
  for(unsigned int i = 0; i < rdt_triangles.size()/3; ++i) {
    res_face->addTriangle(
      new MTriangle(
        m_verts[rdt_triangles[3*i  ]],
        m_verts[rdt_triangles[3*i+1]],
        m_verts[rdt_triangles[3*i+2]]
        )
    ) ;
  }

  res_face->setAllElementsVisible(true) ;

  return v ;
}
Esempio n. 4
0
bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gradObj)
{
  // set the mesh to its present position
  std::vector<SPoint3> xyz,uvw;
  mesh.getGEntityPositions(xyz,uvw);
  mesh.updateGEntityPositions();

  //could be better (e.g. store the model in the Mesh:: datastrucure)

  GModel *gm = GModel::current();

  // for all model edges, compute the error between the geometry and the mesh

  maxDistCAD = 0.0;
  double distCAD = 0.0;

  for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
    // do not do straight lines
    if ((*it)->geomType() == GEntity::Line)continue;
    // look at all mesh lines

    std::vector<bool> doWeCompute((*it)->lines.size());
    for (unsigned int i=0;i<(*it)->lines.size(); i++){
      doWeCompute[i] = false;
      for (unsigned int j=0;j<(*it)->lines[i]->getNumVertices(); j++){
        int index = mesh.getFreeVertexStartIndex((*it)->lines[i]->getVertex(j));
        if (index >=0){
          doWeCompute[i] = true;
          continue;
        }
      }
    }

    std::vector<double> dist((*it)->lines.size());
    for (unsigned int i=0;i<(*it)->lines.size(); i++){
      if (doWeCompute[i]){
        // compute the distance from the geometry to the mesh
        dist[i] = MLineGEdgeDistance ( (*it)->lines[i] , *it );
        maxDistCAD = std::max(maxDistCAD,dist[i]);
        distCAD += dist [i] * factor;
      }
    }
    // be clever to compute the derivative : iterate on all
    // Distance = \sum_{lines} Distance (line, GEdge)
    // For a high order vertex, we compute the derivative only by
    // recomputing the distance to one only line
    const double eps = 1.e-6;
    for (unsigned int i=0;i<(*it)->lines.size(); i++){
      if (doWeCompute[i]){
        for (int j=2 ; j<(*it)->lines[i]->getNumVertices()  ; j++){
          MVertex *v = (*it)->lines[i]->getVertex(j);
          int index = mesh.getFreeVertexStartIndex(v);
          //	printf("%d %d (%d %d)\n",v->getNum(),index,v->onWhat()->tag(),v->onWhat()->dim());
          if (index >= 0){
            double t;
            v->getParameter(0,t);
            SPoint3 pp (v->x(),v->y(),v->z());
            GPoint gp = (*it)->point(t+eps);
            v->setParameter(0,t+eps);
            v->setXYZ(gp.x(),gp.y(),gp.z());
            double dist2 = MLineGEdgeDistance ( (*it)->lines[i] , *it );
            double deriv = (dist2 - dist[i])/eps;
            v->setXYZ(pp.x(),pp.y(),pp.z());
            v->setParameter(0,t);
            //	  printf("%g %g %g\n",dist[i],dist2, MLineGEdgeDistance ( (*it)->lines[i] , *it ));
            // get the index of the vertex
            gradObj[index] += deriv * factor;
          }
        }
      }
      //    printf("done\n");
      // For a low order vertex classified on the GEdge, we recompute
    // two distances for the two MLines connected to the vertex
      for (unsigned int i=0;i<(*it)->lines.size()-1; i++){
        MVertex *v =  (*it)->lines[i]->getVertex(1);
        int index = mesh.getFreeVertexStartIndex(v);
        if (index >= 0){
          double t;
          v->getParameter(0,t);
          SPoint3 pp (v->x(),v->y(),v->z());
          GPoint gp = (*it)->point(t+eps);
          v->setParameter(0,t+eps);
          v->setXYZ(gp.x(),gp.y(),gp.z());
          MLine *l1 = (*it)->lines[i];
          MLine *l2 = (*it)->lines[i+1];
          //	printf("%d %d -- %d %d\n",l1->getVertex(0)->getNum(),l1->getVertex(1)->getNum(),l2->getVertex(0)->getNum(),l2->getVertex(1)->getNum());
          double deriv =
            (MLineGEdgeDistance ( l1 , *it ) - dist[i])  /eps +
            (MLineGEdgeDistance ( l2 , *it ) - dist[i+1])/eps;
          v->setXYZ(pp.x(),pp.y(),pp.z());
          v->setParameter(0,t);
          gradObj[index] += deriv * factor;
        }
      }
    }
  }
  //  printf("computing distance : 1D part %12.5E\n",distCAD);

  // now the 3D part !

  std::vector<std::vector<SVector3> > gsfT;
  computeGradSFAtNodes ( (*gm->firstFace())->triangles[0],gsfT);

  std::map<MVertex*,SVector3> normalsToCAD;


  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
    // do not do plane surfaces
    if ((*it)->geomType() == GEntity::Plane)continue;
    std::map<MTriangle*,double> dist;

    std::vector<bool> doWeCompute((*it)->triangles.size());
    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
      doWeCompute[i] = false;
      for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
        int index = mesh.getFreeVertexStartIndex((*it)->triangles[i]->getVertex(j));
        if (index >=0){
          doWeCompute[i] = true;
        }
      }
      if (doWeCompute[i]){
        for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
          MVertex *v = (*it)->triangles[i]->getVertex(j);
          if (normalsToCAD.find(v) == normalsToCAD.end()){
            SPoint2 p_cad;
            reparamMeshVertexOnFace(v, *it, p_cad);
            SVector3 tg_cad = (*it)->normal(p_cad);
            tg_cad.normalize();
            normalsToCAD[v] = tg_cad;
          }
        }
      }
    }

    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
      // compute the distance from the geometry to the mesh
      if(doWeCompute[i]){
        const double d = MFaceGFaceDistanceOld((*it)->triangles[i], *it, &gsfT, &normalsToCAD);
        dist[(*it)->triangles[i]] = d;
        maxDistCAD = std::max(maxDistCAD,d);
        distCAD += d * factor;
      }
    }

    // be clever again to compute the derivatives
    const double eps = 1.e-6;
    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
      if(doWeCompute[i]){
        for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
          //    for (; itm !=v2t.end(); ++itm){
          MVertex   *v = (*it)->triangles[i]->getVertex(j);
          if(v->onWhat()->dim() == 1){
            int index = mesh.getFreeVertexStartIndex(v);
            if (index >= 0){
              MTriangle *t = (*it)->triangles[i];
              GEdge *ge = v->onWhat()->cast2Edge();
              double t_;
              v->getParameter(0,t_);
              SPoint3 pp (v->x(),v->y(),v->z());
              GPoint gp = ge->point(t_+eps);
              v->setParameter(0,t_+eps);
              v->setXYZ(gp.x(),gp.y(),gp.z());
              const double distT = dist[t];
              double deriv =  (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps;
              v->setXYZ(pp.x(),pp.y(),pp.z());
              v->setParameter(0,t_);
              gradObj[index] += deriv * factor;
            }
          }

          if(v->onWhat() == *it){
            int index = mesh.getFreeVertexStartIndex(v);
            if (index >= 0){
              MTriangle *t = (*it)->triangles[i];
              double uu,vv;
              v->getParameter(0,uu);
              v->getParameter(1,vv);
              SPoint3 pp (v->x(),v->y(),v->z());

              const double distT = dist[t];

              GPoint gp = (*it)->point(uu+eps,vv);
              v->setParameter(0,uu+eps);
              v->setXYZ(gp.x(),gp.y(),gp.z());
              double deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps;
              v->setXYZ(pp.x(),pp.y(),pp.z());
              v->setParameter(0,uu);
              gradObj[index] += deriv * factor;

              gp = (*it)->point(uu,vv+eps);
              v->setParameter(1,vv+eps);
              v->setXYZ(gp.x(),gp.y(),gp.z());
              deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps;
              v->setXYZ(pp.x(),pp.y(),pp.z());
              v->setParameter(1,vv);
              gradObj[index+1] += deriv * factor;
            }
          }
        }
      }
    }
  }
  mesh.updateGEntityPositions(xyz,uvw);
  Obj +=distCAD;
  //  printf("computing distance : 2D part %12.5E\n",distCAD);
  //  printf("%22.15E\n",distCAD);
  return true;
}
Esempio n. 5
0
int main(int argc,char *argv[])
{
  if(argc < 6){
    printf("Usage: %s file lx ly lz rmax [levels=1] [refcs=1]\n", argv[0]);
    printf("where\n");
    printf("  'file' contains a CAD model\n");
    printf("  'lx', 'ly' and 'lz' are the sizes of the elements along the"
           " x-, y- and z-axis at the coarsest level\n");
    printf("  'rmax' is the radius of the largest sphere that can be inscribed"
           " in the structure\n");
    printf("  'levels' sets the number of levels in the grid\n");
    printf("  'refcs' selects if curved surfaces should be refined\n");
    return -1;
  }

  GmshInitialize();
  GmshSetOption("General", "Terminal", 1.);
  GmshMergeFile(argv[1]);
  double lx = atof(argv[2]), ly = atof(argv[3]), lz = atof(argv[4]);
  double rmax = atof(argv[5]);
  int levels = (argc > 6) ? atof(argv[6]) : 1;
  int refineCurvedSurfaces = (argc > 7) ? atof(argv[7]) : 1;

  // minimum distance between points in the cloud at the coarsest
  // level
  double sampling = std::min(rmax, std::min(lx, std::min(ly, lz)));

  // radius of the "tube" created around parts to refine at the
  // coarsest level
  double rtube = std::max(lx, std::max(ly, lz)) * 2.;

  GModel *gm = GModel::current();

  std::vector<SPoint3> points;
  Msg::Info("Filling coarse point cloud on surfaces");
  for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++)
    (*fit)->fillPointCloud(sampling, &points);
  Msg::Info("  %d points in the surface cloud", (int)points.size());

  std::vector<SPoint3> refinePoints;
  if(levels > 1){
    double s = sampling / pow(2., levels - 1);
    Msg::Info("Filling refined point cloud on curves and curved surfaces");
    for (GModel::eiter eit = gm->firstEdge(); eit != gm->lastEdge(); eit++)
      fillPointCloud(*eit, s, refinePoints);

    // FIXME: refine this by computing e.g. "mean" curvature
    if(refineCurvedSurfaces){
      for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++)
        if((*fit)->geomType() != GEntity::Plane)
          (*fit)->fillPointCloud(2 * s, &refinePoints);
    }
    Msg::Info("  %d points in the refined cloud", (int)refinePoints.size());
  }

  SBoundingBox3d bb;
  for(unsigned int i = 0; i < points.size(); i++) bb += points[i];
  for(unsigned int i = 0; i < refinePoints.size(); i++) bb += refinePoints[i];
  bb.scale(1.21, 1.21, 1.21);
  SVector3 range = bb.max() - bb.min();
  int NX = range.x() / lx;
  int NY = range.y() / ly;
  int NZ = range.z() / lz;
  if(NX < 2) NX = 2;
  if(NY < 2) NY = 2;
  if(NZ < 2) NZ = 2;

  Msg::Info("  bounding box min: %g %g %g -- max: %g %g %g",
            bb.min().x(), bb.min().y(), bb.min().z(),
            bb.max().x(), bb.max().y(), bb.max().z());
  Msg::Info("  Nx=%d Ny=%d Nz=%d", NX, NY, NZ);

  cartesianBox<double> box(bb.min().x(), bb.min().y(), bb.min().z(),
                           SVector3(range.x(), 0, 0),
                           SVector3(0, range.y(), 0),
                           SVector3(0, 0, range.z()),
                           NX, NY, NZ, levels);

  Msg::Info("Inserting active cells in the cartesian grid");
  Msg::Info("  level %d", box.getLevel());
  for (unsigned int i = 0; i < points.size(); i++)
    insertActiveCells(points[i].x(), points[i].y(), points[i].z(), rmax, box);

  cartesianBox<double> *parent = &box, *child;
  while((child = parent->getChildBox())){
    Msg::Info("  level %d", child->getLevel());
    for(unsigned int i = 0; i < refinePoints.size(); i++)
      insertActiveCells(refinePoints[i].x(), refinePoints[i].y(), refinePoints[i].z(),
                        rtube / pow(2., (levels - child->getLevel())), *child);
    parent = child;
  }

  // remove child cells that do not entirely fill parent cell or for
  // which there is no parent neighbor; then remove parent cells that
  // have children
  Msg::Info("Removing cells to match X-FEM mesh topology constraints");
  removeBadChildCells(&box);
  removeParentCellsWithChildren(&box);

  // we generate duplicate nodes at this point so we can easily access
  // cell values at each level; we will clean up by renumbering after
  // filtering
  Msg::Info("Initializing nodal values in the cartesian grid");
  box.createNodalValues();

  Msg::Info("Computing levelset on the cartesian grid");
  computeLevelset(gm, box);

  Msg::Info("Removing cells outside the structure");
  removeOutsideCells(&box);

  Msg::Info("Renumbering mesh vertices across levels");
  box.renumberNodes();

  bool decomposeInSimplex = false;
  box.writeMSH("yeah.msh", decomposeInSimplex);

  Msg::Info("Done!");
  GmshFinalize();
}
Esempio n. 6
0
PView *GMSH_BubblesPlugin::execute(PView *v)
{
  double shrink = (double)BubblesOptions_Number[0].def;
  std::string fileName = BubblesOptions_String[0].def;

  FILE *fp = Fopen(fileName.c_str(), "w");
  if(!fp){
    Msg::Error("Could not open output file '%s'", fileName.c_str());
    return v;
  }

  GModel *m = GModel::current();

  int p = m->getMaxElementaryNumber(0) + 1;
  int l = m->getMaxElementaryNumber(1) + 1;
  int s = m->getMaxElementaryNumber(2) + 1;
  int ll = s, ps = 1;

  SBoundingBox3d bbox = m->bounds();
  double lc = norm(SVector3(bbox.max(), bbox.min())) / 100;
  fprintf(fp, "lc = %g;\n", lc);

  for(GModel::viter vit = m->firstVertex(); vit != m->lastVertex(); vit++)
    (*vit)->writeGEO(fp, "lc");

  for(GModel::eiter eit = m->firstEdge(); eit != m->lastEdge(); eit++)
    (*eit)->writeGEO(fp);

  for(GModel::fiter fit = m->firstFace(); fit != m->lastFace(); fit++){
    (*fit)->writeGEO(fp);
    fprintf(fp, "Delete { Surface {%d}; }\n", (*fit)->tag());

    int sbeg = s;
    int llbeg = ll;

    // compute vertex-to-triangle_barycenter map
    std::map<MVertex*, std::vector<SPoint3> > v2t;
    for(unsigned int i = 0; i < (*fit)->triangles.size(); i++)
      for(int j = 0; j < 3; j++)
        v2t[(*fit)->triangles[i]->getVertex(j)].push_back((*fit)->triangles[i]->barycenter());

    // add boundary vertices in map to get cells "closer" to the boundary
    for(std::map<MVertex*, std::vector<SPoint3> >::iterator it = v2t.begin();
        it != v2t.end(); it++){
      MVertex *v = it->first;
      if(v->onWhat() && v->onWhat()->dim() < 2)
        it->second.push_back(SPoint3(it->first->x(), it->first->y(), it->first->z()));
    }

    for(std::map<MVertex*, std::vector<SPoint3> >::iterator it = v2t.begin();
        it != v2t.end(); it++){
      if(it->second.size() > 2){
        // get barycenter of cell boundary points and order them
        SPoint3 bc;
        for(unsigned int i = 0; i < it->second.size(); i++)
          bc += it->second[i];
        bc *= 1. / (double)it->second.size();
        compareAngle comp(bc);
        std::sort(it->second.begin(), it->second.end(), comp);
        // shrink cells
        if(shrink){
          for(unsigned int i = 0; i < it->second.size(); i++){
            double dir[3] = {it->second[i].x() - bc.x(),
                             it->second[i].y() - bc.y(),
                             it->second[i].z() - bc.z()};
            it->second[i][0] -= shrink * dir[0];
            it->second[i][1] -= shrink * dir[1];
            it->second[i][2] -= shrink * dir[2];
          }
        }
        // create b-spline bounded surface for each cell
        int nump = it->second.size();
        for(int i = 0; i < nump; i++){
          SPoint3 &b(it->second[i]);
          fprintf(fp, "Point(%d) = {%.16g, %.16g, %.16g, lc};\n", p++, b.x(), b.y(), b.z());
        }
        fprintf(fp, "BSpline(%d) = {", l++);
        for(int i = nump - 1; i >= 0; i--)
          fprintf(fp, "%d,", p - i - 1);
        fprintf(fp, "%d};\n", p - nump);
        fprintf(fp, "Line Loop(%d) = {%d};\n", ll++, l - 1);
        fprintf(fp, "Plane Surface(%d) = {%d};\n", s++, ll - 1);
      }
    }
    fprintf(fp, "Physical Surface(%d) = {%d:%d};\n", ps++, sbeg, s - 1);

    fprintf(fp, "Plane Surface(%d) = {%d, %d:%d};\n", s++, (*fit)->tag(), llbeg, ll - 1);
    fprintf(fp, "Physical Surface(%d) = {%d};\n", ps++, s - 1);
  }

  fclose(fp);

  return v;
}