Esempio n. 1
0
void Octree2::FindMultiCells(const Polylines& lines) {
  using namespace Karras;

  cell_intersections.clear();
  cell_intersections.resize(octree.size(), CellIntersections());
  MCData data(cell_intersections);

  const vector<vector<float2>>& polygons = lines.getPolygons();;

  // For each line segment in each polygon do a cell walk, updating
  // the cell_intersections structure.
  intersections.clear();
  for (int j = 0; j < polygons.size(); ++j) {
    const std::vector<float2>& polygon = polygons[j];
    data.cur_label = j;
    for (int i = 0; i < polygon.size() - 1; ++i) {
      const floatn a = obj2Oct(polygon[i]);
      const floatn b = obj2Oct(polygon[i+1]);
      // Visit each octree cell intersected by segment a-b. The visitor
      // is MCCallback.
      CellWalk(a, b, octree, resln, MCCallback, &data);
      vector<OctreeUtils::CellIntersection> local = Walk(a, b);
      for (const OctreeUtils::CellIntersection& ci : local) {
        intersections.push_back(ci.p);
      }
    }
  }

  // Find points that we want to add in order to run a more effective
  // Karras octree construction.
  extra_qpoints.clear();
  _origins.clear();
  _lengths.clear();
  for (int i = 0; i < octree.size(); ++i) {
    const CellIntersections& intersection = cell_intersections[i];
    for (int octant = 0; octant < (1<<DIM); ++octant) {
      const int num_labels = intersection.num_labels(octant);
      // cout << "cell = " << i << "/" << octant << ": " << num_labels << endl;
      // if (intersection.is_multi(octant)) {
      //   {
      for (int j = 0; j < num_labels; ++j) {
      // for (int j = 0; j < 1; ++j) {
        for (int k = j+1; k < num_labels; ++k) {
        // for (int k = j+1; k < std::min(2, num_labels); ++k) {
          // We'll compare segments at j and k.
          FloatSegment segs[2] = { intersection.seg(j, octant),
                                intersection.seg(k, octant) };
          vector<floatn> samples;
          vector<floatn> origins;
          vector<float> lengths;
          if (!Geom::multi_intersection(segs[0], segs[1])) {
            try {
              if (i == fnode.get_parent_idx() && octant == fnode.get_octant()) {
                cout << "here in FitBoxes" << endl;
                write_seg(segs[0], "seg0.dat");
                write_seg(segs[1], "seg1.dat");
              }
              Geom::FitBoxes(segs[0], segs[1], 1, &samples, &origins, &lengths);
            } catch(logic_error& e) {
              cerr << "segments: " << segs[0] << " " << segs[1] << endl;
              cerr << "labels: " << intersection.label(0, octant)
                   << " " << intersection.label(1, octant) << endl;
              write_seg(segs[0], "seg0.dat");
              write_seg(segs[1], "seg1.dat");
              throw e;
            }
          }
          _origins.insert(_origins.end(), origins.begin(), origins.end());
          _lengths.insert(_lengths.end(), lengths.begin(), lengths.end());
          for (const floatn& sample : samples) {
            extra_qpoints.push_back(convert_intn(sample));
          }
        }
      }
    }
  }
}
Esempio n. 2
0
void Octree2::build(const Polylines& lines,
                    const BoundingBox<float2>* customBB) {
  using namespace std;

  //------------------
  // Initialize OpenCL
  //------------------
// #ifdef __OPEN_CL_SUPPORT__
//   static bool initialized = false;
//   if (options.gpu && !initialized) {
//     OpenCLInit(2, o, options.opencl_log);
//     initialized = true;
//   }
// #endif

  karras_points.clear();
  bb = BoundingBox<float2>();
  extra_qpoints.clear();
  octree.clear();

  const vector<vector<float2>>& polygons = lines.getPolygons();
  if (polygons.empty()) {
    buildOctVertices();
    return;
  }

  // Get all vertices into a 1D array (karras_points).
  for (int i = 0; i < polygons.size(); ++i) {
    const vector<float2>& polygon = polygons[i];
    for (int j = 0; j < polygon.size()-1; ++j) {
      karras_points.push_back(polygon[j]);
    }
    karras_points.push_back(polygon.back());
  }

  // Compute bounding box
  if (customBB) {
    bb = *customBB;
  } else {
    for (int i = 0; i < karras_points.size(); ++i) {
      bb(karras_points[i]);
    }
  }
  
  // Karras iterations
  vector<intn> qpoints = Karras::Quantize(karras_points, resln);
  int iterations = 0;
  do {
    qpoints.insert(qpoints.end(), extra_qpoints.begin(), extra_qpoints.end());
    for (const intn& qp : extra_qpoints) {
      karras_points.push_back(oct2Obj(qp));
    }
    extra_qpoints.clear();
    if (qpoints.size() > 1) {
      octree = Karras::BuildOctreeInParallel(qpoints, resln, true);
    }
    else {
      octree.clear();
    }
    //FindMultiCells(lines);

    ++iterations;
  } while (iterations < options.karras_iterations && !extra_qpoints.empty());
  //cout << "Karras iterations: " << iterations << endl;

  // Count the number of cells with multiple intersections
  int count = 0;
  for (int i = 0; i < cell_intersections.size(); ++i) {
    for (int j = 0; j < 4; ++j) {
      if (cell_intersections[i].is_multi(j)) {
        ++count;
      }
    }
  }
  //cout << "Number of multi-intersection cells: " << count << endl;

  // todo: setup vertices on GPU for rendering
  buildOctVertices();
  
  //------------------
  // Cleanup OpenCL
  //------------------
// #ifdef __OPEN_CL_SUPPORT__
//   if (options.gpu) {
//     OpenCLCleanup();
//   }
// #endif
}