void SequentialFitter::compute_quadfit () { ON_NurbsSurface nurbs; if (m_have_corners) { nurbs = FittingSurface::initNurbs4Corners (2, m_corners[0], m_corners[1], m_corners[2], m_corners[3]); } else { nurbs = FittingSurface::initNurbsPCA (2, &m_data); nurbs.GetCV (0, 0, m_corners[0]); nurbs.GetCV (1, 0, m_corners[1]); nurbs.GetCV (1, 1, m_corners[2]); nurbs.GetCV (0, 1, m_corners[3]); Eigen::Vector3d v0 (m_corners[0].x, m_corners[0].y, m_corners[0].z); Eigen::Vector3d v1 (m_corners[1].x, m_corners[1].y, m_corners[1].z); Eigen::Vector3d v2 (m_corners[2].x, m_corners[2].y, m_corners[2].z); Eigen::Vector3d v3 (m_corners[3].x, m_corners[3].y, m_corners[3].z); if (is_back_facing (v0, v1, v2, v3)) { ON_3dPoint tmp[4]; tmp[0] = m_corners[0]; tmp[1] = m_corners[1]; tmp[2] = m_corners[2]; tmp[3] = m_corners[3]; m_corners[3] = tmp[0]; m_corners[2] = tmp[1]; m_corners[1] = tmp[2]; m_corners[0] = tmp[3]; nurbs = FittingSurface::initNurbs4Corners (2, m_corners[0], m_corners[1], m_corners[2], m_corners[3]); } } FittingSurface fitting (&m_data, nurbs); FittingSurface::Parameter paramFP (m_params.forceInterior, 1.0, 0.0, m_params.forceBoundary, 1.0, 0.0); // Quad fitting // if( !m_quiet && m_dbgWin != NULL ) // NurbsConvertion::Nurbs2TomGine(m_dbgWin, *fitting->m_nurbs, m_surf_id, m_params.resolution); for (int r = 0; r < m_params.iterationsQuad; r++) { fitting.assemble (paramFP); fitting.solve (); } fitting.m_nurbs.GetCV (0, 0, m_corners[0]); fitting.m_nurbs.GetCV (1, 0, m_corners[1]); fitting.m_nurbs.GetCV (1, 1, m_corners[2]); fitting.m_nurbs.GetCV (0, 1, m_corners[3]); }
ON_NurbsSurface SequentialFitter::compute_interior (const ON_NurbsSurface &nurbs) { if (m_data.boundary.size () <= 0) { printf ("[SequentialFitter::compute_interior] Warning, no interior points given: setInterior()\n"); return nurbs; } FittingSurface *fitting = new FittingSurface (&m_data, nurbs); this->compute_interior (fitting); // update error fitting->assemble (); m_nurbs = fitting->m_nurbs; delete (fitting); return m_nurbs; }
void ClosingBoundary::optimizeBoundary (std::vector<ON_NurbsSurface> &nurbs_list, std::vector<NurbsDataSurface> &data_list, Parameter param) { for (unsigned n1 = 0; n1 < nurbs_list.size (); n1++) data_list[n1].clear_boundary (); // for each nurbs for (unsigned n1 = 0; n1 < nurbs_list.size (); n1++) { // for (unsigned n1 = 0; n1 < 1; n1++) { ON_NurbsSurface *nurbs1 = &nurbs_list[n1]; // sample point list from nurbs1 vector_vec3d boundary1; vector_vec2d params1; sampleFromBoundary (nurbs1, boundary1, params1, param.samples); // for each other nurbs for (unsigned n2 = (n1 + 1); n2 < nurbs_list.size (); n2++) { ON_NurbsSurface *nurbs2 = &nurbs_list[n2]; // for all points in the point list for (unsigned i = 0; i < boundary1.size (); i++) { double error; Eigen::Vector3d p, tu, tv; Eigen::Vector3d p0 = boundary1[i]; Eigen::Vector2d params1, params2; switch (param.type) { case COMMON_BOUNDARY_POINT_MEAN: p = commonBoundaryPoint1 (*nurbs1, *nurbs2, params1, params2, p0, param.com_iter, error, param.accuracy); break; case COMMON_BOUNDARY_POINT_TANGENTS: p = commonBoundaryPoint2 (*nurbs1, *nurbs2, params1, params2, p0, param.com_iter, error, param.accuracy); break; case COMMON_BOUNDARY_POINT_PLANES: p = commonBoundaryPoint3 (*nurbs1, *nurbs2, params1, params2, p0, param.com_iter, error, param.accuracy); break; case CLOSEST_POINTS_INTERIOR: params1 = FittingSurface::findClosestElementMidPoint (*nurbs2, p0); FittingSurface::inverseMapping (*nurbs2, p0, params1, error, p, tu, tv, param.com_iter, param.accuracy, true); break; case CLOSEST_POINTS_BOUNDARY: FittingSurface::inverseMappingBoundary (*nurbs2, p0, error, p, tu, tv, param.com_iter, param.accuracy, true); break; } double dist = (p - p0).norm (); if (error < param.max_error && dist < param.max_dist) { data_list[n1].boundary.push_back (p); data_list[n2].boundary.push_back (p); } } } // for each other nurbs // nurbs fitting FittingSurface fit (&data_list[n1], nurbs_list[n1]); FittingSurface::Parameter paramFP (1.0, param.smoothness, 0.0, 1.0, param.smoothness, 0.0); std::vector<double> wBnd, wInt; for (unsigned i = 0; i < data_list[n1].boundary.size (); i++) data_list[n1].boundary_weight.push_back (param.boundary_weight); for (unsigned i = 0; i < data_list[n1].interior.size (); i++) data_list[n1].interior_weight.push_back (param.interior_weight); for (unsigned i = 0; i < param.fit_iter; i++) { fit.assemble (paramFP); fit.solve (); } nurbs_list[n1] = fit.m_nurbs; } // for each nurbs }
ON_NurbsSurface SequentialFitter::compute (bool assemble) { FittingSurface* fitting; ON_NurbsSurface nurbs; FittingSurface::Parameter paramFP (m_params.forceInterior, m_params.stiffnessInterior, 0.0, m_params.forceBoundary, m_params.stiffnessBoundary, 0.0); // int surfid = -1; // TomGine::tgRenderModel nurbs; // TomGine::tgRenderModel box; if (m_data.boundary.size () > 0) { // throw std::runtime_error("[SequentialFitter::compute] Error: empty boundary point-cloud.\n"); compute_quadfit (); nurbs = FittingSurface::initNurbs4Corners (m_params.order, m_corners[0], m_corners[1], m_corners[2], m_corners[3]); fitting = new FittingSurface (&m_data, nurbs); if (assemble) fitting->assemble (paramFP); compute_refinement (fitting); compute_boundary (fitting); } else { if (this->m_have_corners) { nurbs = FittingSurface::initNurbs4Corners (m_params.order, m_corners[0], m_corners[1], m_corners[2], m_corners[3]); fitting = new FittingSurface (&m_data, nurbs); if (assemble) fitting->assemble (paramFP); } else { fitting = new FittingSurface (m_params.order, &m_data); if (assemble) fitting->assemble (m_params.stiffnessInterior); int ncv0 = fitting->m_nurbs.m_cv_count[0]; int ncv1 = fitting->m_nurbs.m_cv_count[1]; fitting->m_nurbs.GetCV (0, 0, m_corners[0]); fitting->m_nurbs.GetCV (ncv0 - 1, 0, m_corners[1]); fitting->m_nurbs.GetCV (ncv0 - 1, ncv1 - 1, m_corners[2]); fitting->m_nurbs.GetCV (0, ncv1 - 1, m_corners[3]); Eigen::Vector3d v0 (m_corners[0].x, m_corners[0].y, m_corners[0].z); Eigen::Vector3d v1 (m_corners[1].x, m_corners[1].y, m_corners[1].z); Eigen::Vector3d v2 (m_corners[2].x, m_corners[2].y, m_corners[2].z); Eigen::Vector3d v3 (m_corners[3].x, m_corners[3].y, m_corners[3].z); if (is_back_facing (v0, v1, v2, v3)) { ON_3dPoint tmp[4]; tmp[0] = m_corners[0]; tmp[1] = m_corners[1]; tmp[2] = m_corners[2]; tmp[3] = m_corners[3]; m_corners[3] = tmp[0]; m_corners[2] = tmp[1]; m_corners[1] = tmp[2]; m_corners[0] = tmp[3]; delete (fitting); nurbs = FittingSurface::initNurbs4Corners (m_params.order, m_corners[0], m_corners[1], m_corners[2], m_corners[3]); fitting = new FittingSurface (&m_data, nurbs); if (assemble) fitting->assemble (paramFP); } for (int r = 0; r < m_params.refinement; r++) { fitting->refine (0); fitting->refine (1); } } } if (m_data.interior.size () > 0) compute_interior (fitting); // update error fitting->assemble (); m_nurbs = fitting->m_nurbs; delete (fitting); return m_nurbs; }