typename beziervolume<point_t>::array_type beziervolume<point_t>::ocsplit ( ) const { array_type result; std::size_t new_size_u = order_u() + degree_u(); std::size_t new_size_v = order_v() + degree_v(); std::size_t new_size_w = order_w() + degree_w(); // generate point-meshes for different steps of split pointmesh3d<point_t> cpsplit_u ( new_size_u, order_v(), order_w() ); pointmesh3d<point_t> cpsplit_uv ( new_size_u, new_size_v, order_w() ); pointmesh3d<point_t> cpsplit_uvw ( new_size_u, new_size_v, new_size_w ); converter<point_t> converter; // split in u for (std::size_t v = 0; v != order_v(); ++v) { for (std::size_t w = 0; w != order_w(); ++w) { // elevate to virtual nurbscurve to apply knot insertion std::vector<point_t> tmp_curve = _points.submesh ( 0, v, w ); // create knot vector std::vector<value_type> kv_min (order_u(), 0); std::vector<value_type> kv_max (order_u(), 1); std::multiset<value_type> kv; kv.insert ( kv_min.begin(), kv_min.end() ); kv.insert ( kv_max.begin(), kv_max.end() ); converter.knot_insertion (tmp_curve, kv, order_u(), value_type(0.5)); cpsplit_u.submesh (tmp_curve.begin(), 0, v, w); } } // split in v for (std::size_t u = 0; u != new_size_u; ++u) { for (std::size_t w = 0; w != order_w(); ++w) { // elevate to virtual nurbscurve to apply knot insertion std::vector<point_t> tmp_curve = cpsplit_u.submesh ( 1, u, w ); // create knot vector std::vector<value_type> kv_min (order_v(), 0); std::vector<value_type> kv_max (order_v(), 1); std::multiset<value_type> kv; kv.insert ( kv_min.begin(), kv_min.end() ); kv.insert ( kv_max.begin(), kv_max.end() ); converter.knot_insertion (tmp_curve, kv, order_v(), value_type(0.5)); cpsplit_uv.submesh (tmp_curve.begin(), 1, u, w); } } // split in w for (std::size_t u = 0; u != new_size_u; ++u) { for (std::size_t v = 0; v != new_size_v; ++v) { // elevate to virtual nurbscurve to apply knot insertion std::vector<point_t> tmp_curve = cpsplit_uv.submesh ( 2, u, v ); // create knot vector std::vector<value_type> kv_min (order_w(), 0); std::vector<value_type> kv_max (order_w(), 1); std::multiset<value_type> kv; kv.insert ( kv_min.begin(), kv_min.end() ); kv.insert ( kv_max.begin(), kv_max.end() ); converter.knot_insertion (tmp_curve, kv, order_w(), value_type(0.5)); cpsplit_uvw.submesh (tmp_curve.begin(), 2, u, v); } } // generate subvolumes for (std::size_t w = 0; w != 2; ++w) { for (std::size_t v = 0; v != 2; ++v) { for (std::size_t u = 0; u != 2; ++u) { pointmesh3d<point_t> submesh = cpsplit_uvw.submesh(u*degree_u(), v*degree_v(), w*degree_w(), order_u(), order_v(), order_w()); beziervolume subvolume (submesh); //result[array_index(u)][array_index(v)][array_index(w)] = subvolume; result[u][v][w] = subvolume; } } } return result; }
inline void converter<point_t>::convert( nurbsvolume_type const& volume, insert_iterator_t ins_iter, std::list<beziervolumeindex>& indices) const { typedef typename std::set<value_type>::const_iterator set_const_iterator; std::set<value_type> unique_knots_u(volume.knotvector_u().begin(), volume.knotvector_u().end()); std::set<value_type> unique_knots_v(volume.knotvector_v().begin(), volume.knotvector_v().end()); std::set<value_type> unique_knots_w(volume.knotvector_w().begin(), volume.knotvector_w().end()); std::vector<value_type> unique_knots_u_as_vector(unique_knots_u.begin(), unique_knots_u.end()); std::vector<value_type> unique_knots_v_as_vector(unique_knots_v.begin(), unique_knots_v.end()); std::vector<value_type> unique_knots_w_as_vector(unique_knots_w.begin(), unique_knots_w.end()); // compute target size of mesh after knot insertion std::size_t knotspans_u = unique_knots_u.size() - 1; std::size_t knotspans_v = unique_knots_v.size() - 1; std::size_t knotspans_w = unique_knots_w.size() - 1; std::size_t targetsize_u = (knotspans_u) * (volume.order_u() - 1) + 1; std::size_t targetsize_v = (knotspans_v) * (volume.order_v() - 1) + 1; std::size_t targetsize_w = (knotspans_w) * (volume.order_w() - 1) + 1; pointmesh3d<point_t> mesh(volume.points().begin(), volume.points().end(), volume.knotvector_u().size() - volume.order_u(), volume.knotvector_v().size() - volume.order_v(), volume.knotvector_w().size() - volume.order_w()); // knot insertion in u direction pointmesh3d<point_t> mesh_u( targetsize_u, volume.numberofpoints_v(), volume.numberofpoints_w()); for (unsigned int v = 0; v != volume.numberofpoints_v(); ++v) { for (unsigned int w = 0; w != volume.numberofpoints_w(); ++w) { std::vector<point_t> curve = mesh.submesh(0, v, w); std::multiset<value_type> knots(volume.knotvector_u().begin(), volume.knotvector_u().end()); knot_insertion(curve, knots, volume.order_u()); mesh_u.submesh(curve.begin(), 0, v, w); } } // knot insertion in v direction pointmesh3d<point_t> mesh_uv( targetsize_u, targetsize_v, volume.numberofpoints_w()); for (unsigned int u = 0; u != targetsize_u; ++u) { for (unsigned int w = 0; w != volume.numberofpoints_w(); ++w) { std::vector<point_t> curve = mesh_u.submesh(1, u, w); std::multiset<value_type> knots(volume.knotvector_v().begin(), volume.knotvector_v().end()); knot_insertion(curve, knots, volume.order_v()); mesh_uv.submesh(curve.begin(), 1, u, w); } } // knot insertion in w direction pointmesh3d<point_t> mesh_uvw(targetsize_u, targetsize_v, targetsize_w); for (unsigned int u = 0; u != targetsize_u; ++u) { for (unsigned int v = 0; v != targetsize_v; ++v) { std::vector<point_t> curve = mesh_uv.submesh(2, u, v); std::multiset<value_type> knots(volume.knotvector_w().begin(), volume.knotvector_w().end()); knot_insertion(curve, knots, volume.order_w()); mesh_uvw.submesh(curve.begin(), 2, u, v); } } typename beziervolume_type::parameter_type uvwglobalmin( unique_knots_u_as_vector[0], unique_knots_v_as_vector[0], unique_knots_w_as_vector[0]); typename beziervolume_type::parameter_type uvwglobalmax( unique_knots_u_as_vector[knotspans_u], unique_knots_v_as_vector[knotspans_v], unique_knots_w_as_vector[knotspans_w]); indices.clear(); // read control points of submeshes for (int u = 0; u != int(knotspans_u); ++u) { for (int v = 0; v != int(knotspans_v); ++v) { for (int w = 0; w != int(knotspans_w); ++w) { typename beziervolume_type::parameter_type uvwmin( unique_knots_u_as_vector[u], unique_knots_v_as_vector[v], unique_knots_w_as_vector[w]); typename beziervolume_type::parameter_type uvwmax( unique_knots_u_as_vector[u + 1], unique_knots_v_as_vector[v + 1], unique_knots_w_as_vector[w + 1]); // create control point mesh of target size pointmesh3d<point_t> bmesh( volume.order_u(), volume.order_v(), volume.order_w()); for (unsigned int du = 0; du != volume.order_u(); ++du) { for (unsigned int dv = 0; dv != volume.order_v(); ++dv) { for (unsigned int dw = 0; dw != volume.order_w(); ++dw) { bmesh(du, dv, dw) = mesh_uvw(u * (volume.order_u() - 1) + du, v * (volume.order_v() - 1) + dv, w * (volume.order_w() - 1) + dw); } } } // create and insert sub bezier volume beziervolume<point_t> subvolume(bmesh); subvolume.uvw_local(uvwmin, uvwmax); subvolume.uvw_global(uvwglobalmin, uvwglobalmax); *ins_iter = subvolume; beziervolumeindex idx = { u, v, w }; indices.push_back(idx); } } } }