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)); } } } } } }
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 }