示例#1
0
CgalTriCadInterface::CgalTriCadInterface(vtkUnstructuredGrid *grid)
{
  m_BGrid = vtkUnstructuredGrid::New();
  makeCopy(grid, m_BGrid);
  m_BPart.setGrid(m_BGrid, true);

  double feature_angle;

  EG_STOPDATE("2015-01-01");
  //getXmlSetting("engrid/surface/settings", "feature_angle", feature_angle);
  getSet("surface meshing", "feature angle", 20, feature_angle);
  feature_angle = GeometryTools::deg2rad(feature_angle);

  // build triangle tree
  {
    m_Triangles.clear();
    QVector<vtkIdType> tris;
    getAllCellsOfType(VTK_TRIANGLE, tris, m_BGrid);
    m_Triangles.fill(Triangle(), tris.size());
    m_Tri2Grid.fill(-1, tris.size());
    int i = 0;
    foreach (vtkIdType id_cell, tris) {
      EG_GET_CELL(id_cell, m_BGrid);
      vec3_t a, b, c;
      m_BGrid->GetPoint(pts[0], a.data());
      m_BGrid->GetPoint(pts[1], b.data());
      m_BGrid->GetPoint(pts[2], c.data());
      m_Triangles[i] = Triangle(Point(a[0], a[1], a[2]), Point(b[0], b[1], b[2]), Point(c[0], c[1], c[2]));
      m_Tri2Grid[i] = id_cell;
      ++i;
    }
    m_TriangleTree.rebuild(m_Triangles.begin(), m_Triangles.end());
    m_TriangleTree.accelerate_distance_queries();
  }
示例#2
0
void CreateCadTesselation::scan(bool create_grid, int interlaces)
{
  m_Dx = (m_X2[0] - m_X1[0])/(m_Ni-1);
  m_Dy = (m_X2[1] - m_X1[1])/(m_Nj-1);
  m_Dz = (m_X2[2] - m_X1[2])/(m_Nk-1);

  EG_VTKSP(vtkImageData, gdata);
  gdata->SetDimensions(m_Ni, m_Nj, m_Nk);
  EG_VTKSP(vtkFloatArray, g);
  g->SetName("g");
  g->SetNumberOfValues(m_Ni*m_Nj*m_Nk);
  gdata->GetPointData()->AddArray(g);
  for (int i = 0; i < m_Ni; ++i) {
    for (int j = 0; j < m_Nj; ++j) {
      for (int k = 0; k < m_Nk; ++k) {                
        if (preserveFluid()) {
          g->SetValue(getIdx(i,j,k), 1);
        } else {
          g->SetValue(getIdx(i,j,k), 0);
        }
      }
    }
  }
  m_XScan1 = m_X2;
  m_XScan2 = m_X1;

  vec3_t x_in, x_out, n_in, n_out;

  int progress = 0;
  m_GeometryFound = false;

  double dxi = m_Dx/(interlaces + 1);
  double dyi = m_Dy/(interlaces + 1);
  double dzi = m_Dz/(interlaces + 1);

  double shift = 1e-6;

  // scan ij plane -> k direction
  //      xy plane -> z direction
  for (int i = 0; i < m_Ni; ++i) {
    for (int j = 0; j < m_Nj; ++j) {
      vec3_t x0 = getX(i,j,0);
      for (int i_il = 0; i_il <= interlaces; ++i_il) {
        for (int j_il = 0; j_il <= interlaces; ++j_il) {
          vec3_t x = x0;
          x[0] += i_il*dxi;
          x[1] += j_il*dyi;
          int k_last = 0;
          while (shootRay(x, vec3_t(0,0,1), x_in, x_out, n_in, n_out)) {
            m_GeometryFound = true;
            m_XScan1[2] = min(m_XScan1[2], x_in[2]);
            m_XScan2[2] = max(m_XScan2[2], x_out[2]);
            int k1 = int((x_in[2] - m_X1[2])/m_Dz) + 1;
            int k2 = int((x_out[2] - m_X1[2])/m_Dz);
            if (preserveFluid()) {
              for (int k = k_last; k < min(m_Nk-1,k1); ++k) {
                g->SetValue(getIdx(i,j,k), 0);
              }
            } else {
              for (int k = max(0,k1); k <= min(m_Nk-1,k2); ++k) {
                g->SetValue(getIdx(i,j,k), 1);
              }
            }
            x = x_out;
            x[2] += shift*m_Dz;
            k_last = min(m_Nk-1,k2+1);
          }
          if (preserveFluid()) {
            for (int k = k_last; k <= m_Nk-1; ++k) {
              g->SetValue(getIdx(i,j,k), 0);
            }
          }
        }
      }
    }
    progress += m_Nj;
    GuiMainWindow::pointer()->setProgress(progress);
  }

  // scan ik plane -> j direction
  //      xz plane -> y direction
  for (int i = 0; i < m_Ni; ++i) {
    for (int k = 0; k < m_Nk; ++k) {
      vec3_t x0 = getX(i,0,k);
      for (int i_il = 0; i_il <= interlaces; ++i_il) {
        for (int k_il = 0; k_il <= interlaces; ++k_il) {
          vec3_t x = x0;
          x[0] += i_il*dxi;
          x[2] += k_il*dzi;
          int j_last = 0;
          /*
          if (fabs(x0[0]) < 1.5 && fabs(x0[2]) < 1.5 && create_grid) {
            cout << x0 << endl;
          }
          */
          while (shootRay(x, vec3_t(0,1,0), x_in, x_out, n_in, n_out)) {
            m_GeometryFound = true;
            m_XScan1[1] = min(m_XScan1[1], x_in[1]);
            m_XScan2[1] = max(m_XScan2[1], x_out[1]);
            int j1 = int((x_in[1]-m_X1[1])/m_Dy) + 1;
            int j2 = int((x_out[1]-m_X1[1])/m_Dy);
            if (preserveFluid()) {
              for (int j = j_last; j < min(m_Nj-1,j1); ++j) {
                g->SetValue(getIdx(i,j,k), 0);
              }
            } else {
              for (int j = max(0,j1); j <= min(m_Nj-1,j2); ++j) {
                g->SetValue(getIdx(i,j,k), 1);
              }
            }
            x = x_out;
            x[1] += shift*m_Dy;
            j_last = min(m_Nj-1,j2+1);
          }
          if (preserveFluid()) {
            for (int j = j_last; j <= m_Nj-1; ++j) {
              g->SetValue(getIdx(i,j,k), 0);
            }
          }
        }
      }
    }
    progress += m_Nk;
    GuiMainWindow::pointer()->setProgress(progress);
  }

  // scan jk plane -> i direction
  //      yz plane -> x direction
  for (int j = 0; j < m_Nj; ++j) {
    for (int k = 0; k < m_Nk; ++k) {
      vec3_t x0 = getX(0,j,k);
      for (int j_il = 0; j_il <= interlaces; ++j_il) {
        for (int k_il = 0; k_il <= interlaces; ++k_il) {
          vec3_t x = x0;
          x[1] += j_il*dyi;
          x[2] += k_il*dzi;
          int i_last = 0;
          while (shootRay(x, vec3_t(1,0,0), x_in, x_out, n_in, n_out)) {
            m_GeometryFound = true;
            m_XScan1[0] = min(m_XScan1[0], x_in[0]);
            m_XScan2[0] = max(m_XScan2[0], x_out[0]);
            int i1 = int((x_in[0]-m_X1[0])/m_Dx) + 1;
            int i2 = int((x_out[0]-m_X1[0])/m_Dx);
            if (preserveFluid()) {
              for (int i = i_last; i < min(m_Ni-1,i1); ++i) {
                g->SetValue(getIdx(i,j,k), 0);
              }
            } else {
              for (int i = max(0,i1); i <= min(m_Ni-1,i2); ++i) {
                g->SetValue(getIdx(i,j,k), 1);
              }
            }
            x = x_out;
            x[0] += shift*m_Dx;
            i_last = min(m_Ni-1,i2+1);
          }
          if (preserveFluid()) {
            for (int i = i_last; i <= m_Ni-1; ++i) {
              g->SetValue(getIdx(i,j,k), 0);
            }
          }
        }
      }
    }
    progress += m_Nk;
    GuiMainWindow::pointer()->setProgress(progress);
  }

  if (create_grid) {

    GuiMainWindow::pointer()->resetProgress("smoothing", m_Ni*m_Nj*m_Nk*m_NumIterations);

    // smooth image data
    int progress = 0;
    for (int iter = 1; iter <= m_NumIterations; ++iter) {
      for (int i = 1; i < m_Ni-1; ++i) {
        for (int j = 1; j < m_Nj-1; ++j) {
          for (int k = 1; k < m_Nk-1; ++k) {
            int idx = getIdx(i,j,k);
            bool preserve = false;
            if (m_PreservationType == 1 && g->GetValue(idx) > 0.999) {
              preserve = true;
            }
            if (m_PreservationType == 2 && g->GetValue(idx) < 0.001) {
              preserve = true;
            }
            if (!preserve) {
              double g_new = 0;
              g_new += g->GetValue(getIdx(i+1,j,k));
              g_new += g->GetValue(getIdx(i-1,j,k));
              g_new += g->GetValue(getIdx(i,j+1,k));
              g_new += g->GetValue(getIdx(i,j-1,k));
              g_new += g->GetValue(getIdx(i,j,k+1));
              g_new += g->GetValue(getIdx(i,j,k-1));
              g_new *= 1.0/6.0;
              g->SetValue(idx, g_new);
            }
          }
        }
        progress += m_Nj*m_Nk;
        GuiMainWindow::pointer()->setProgress(progress);
      }
    }    

    // write image data for testing and reporting purposes
    EG_VTKSP(vtkXMLImageDataWriter, vti);
    QString file_name = GuiMainWindow::pointer()->getCwd() + "/g.vti";
    vti->SetFileName(qPrintable(file_name));
    vti->SetDataModeToBinary();
    vti->SetInputData(gdata);
    vti->Write();

    gdata->GetPointData()->SetActiveScalars("g");
    EG_VTKSP(vtkContourFilter, contour);
    contour->SetInputData(gdata);
    contour->SetNumberOfContours(1);
    double g_level = 0.5;
    if (m_PreservationType == 1) {
      g_level = 0.5;
    }
    if (m_PreservationType == 2) {
      g_level = 0.5;
    }
    contour->SetValue(0, g_level);
    EG_VTKSP(vtkTriangleFilter, tri);
    tri->SetInputConnection(contour->GetOutputPort());
    EG_VTKSP(vtkDecimatePro, decimate);
    decimate->PreserveTopologyOn();
    decimate->SetTargetReduction(m_TargetReduction);
    decimate->SetFeatureAngle(GeometryTools::deg2rad(45));
    decimate->SetInputConnection(tri->GetOutputPort());
    decimate->Update();

    allocateGrid(m_Grid, decimate->GetOutput()->GetNumberOfPolys(), decimate->GetOutput()->GetNumberOfPoints());
    for (vtkIdType id_node = 0; id_node < m_Grid->GetNumberOfPoints(); ++id_node) {
      vec3_t x;
      decimate->GetOutput()->GetPoint(id_node, x.data());
      x[0] = m_X1[0] + x[0]*m_Dx;
      x[1] = m_X1[1] + x[1]*m_Dx;
      x[2] = m_X1[2] + x[2]*m_Dx;
      m_Grid->GetPoints()->SetPoint(id_node, x.data());
    }
    EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
    for (vtkIdType id_cell = 0; id_cell < decimate->GetOutput()->GetNumberOfPolys(); ++id_cell) {
      EG_GET_CELL(id_cell, decimate->GetOutput());
      vtkIdType id_new_cell = m_Grid->InsertNextCell(type_cell, num_pts, pts);
      cell_code->SetValue(id_new_cell, 1);
    }
  }
}