std::vector<ON_NurbsCurve> completionSolver::smoothFinalTrajectory( std::vector<ON_NurbsCurve> finalNurbs ) { // get control points std::vector<std::vector<Point3f>> ctrlPointss ; for( int id=0; id<finalNurbs.size(); ++id ) ctrlPointss.push_back( ReconstructorUtility::convert2dProfileTo3d( ReconstructorUtility::getCvPts(finalNurbs[id]) , cutplanes[ id ], centers[ id ] )) ; for( int cvi=0; cvi<ReconstructorPara::cvNum; ++cvi ){ Curve3D traj ; for( int i=0; i<ctrlPointss.size(); ++i ) traj.push_back( ctrlPointss[i][cvi] ) ; Curve3D bspline, bezier; //if( completionSolverPara::smoothTrajactory ) // ReconstructorUtility::getBezier(traj,bspline,1000) ; //else // ReconstructorUtility::getUniformCubicBSpline( traj, bspline, 1000 ) ; if( completionSolverPara::smoothTrajactory ) ReconstructorUtility::getNurbs(traj,bspline, 1000, completionSolverPara::trajectoryNurbsDegree ) ; else{ ReconstructorUtility::getUniformCubicBSpline( traj, bspline, 1000 ) ; //bspline = traj ; } std::vector<std::vector<int>> nstId ; ReconstructorUtility::computeFlannKNN( bspline, traj, nstId, 1) ; for( int i=0; i<traj.size(); ++i ) ctrlPointss[i][cvi] = traj[i] = bspline[ nstId[i][0] ] ; } for( int id=0; id<finalNurbs.size(); ++id ) ReconstructorUtility::setCvOfNurbs(finalNurbs[id], ReconstructorUtility::convert3dProfileTo2d( ctrlPointss[id] , cutplanes[ id ], centers[ id ] )) ; return finalNurbs ; }
bool sweeper::generateSetting(){ std::cout<< "sweeper::generateSetting" <<std::endl; // find associated impSkel branches std::vector<Curve2D> impSkel_w2d ; for( int i=0; i<impSkel.size(); ++i ) impSkel_w2d.push_back( ReconstructorUtility::project3dPointsOntoScreen(impSkel[i]) ); Curve2D stroke_w2d = ReconstructorUtility::convertScreen2dToWorld2d( strokes.back() ) ; std::vector<Point2f> skeletalPts_w2d ; // by find nearest skeletal point std::vector<int2> idLable ; for( int i=0; i<impSkel_w2d.size(); ++i ) for( int j=0; j<impSkel_w2d[i].size() ; ++ j){ skeletalPts_w2d.push_back( impSkel_w2d[i][j] ) ; idLable.push_back( int2(i,j) ) ; } std::vector<int> asscoBrchId ; std::vector<std::vector<int>> nsts ; ReconstructorUtility::computeFlannKNN(skeletalPts_w2d, stroke_w2d, nsts,1 ) ; for( int i=0; i<stroke_w2d.size(); ++i ){ int2 BNid = idLable[nsts[i][0]] ; if( BNid[1] > impSkel[BNid[0]].size()/5 && BNid[1] < impSkel[BNid[0]].size()*4/5 ) asscoBrchId.push_back( BNid[0] ) ; } for( int i=0; i<asscoBrchId.size(); ++i ){ for( int j=i+1; j<asscoBrchId.size(); ++j ) if( asscoBrchId[i]==asscoBrchId[j]){ asscoBrchId.erase(asscoBrchId.begin()+j); j--; } } if( asscoBrchId.size() == 0 ) return false; // fit a bezier curve as the new branch Curve3D ctrpts = impSkel[asscoBrchId[0]]; if( asscoBrchId.size() > 1 ){ // determin direction of first branch Curve3D &b0 = impSkel[asscoBrchId[0]] ; Curve3D &b1 = impSkel[asscoBrchId[1]] ; double d0 = std::min( (b1[0] - b0[0]).Norm() , (b1.back() - b0[0] ).Norm() ); double d1 = std::min( (b1[0] - b0.back()).Norm() , (b1.back() - b0.back()).Norm() ); if( d0 < d1 ){ ctrpts.clear() ; for( int id=b0.size()-1; id>=0; --id ) ctrpts.push_back(b0[id] ) ; }else{ ctrpts.clear() ; for( int id=0; id<b0.size(); ++id ) ctrpts.push_back(b0[id] ) ; } } for( int i=1; i<asscoBrchId.size(); ++i ){ // determine direction of the rest branch Curve3D &bi = impSkel[asscoBrchId[i]] ; if( (bi[0] - ctrpts.back()).Norm() < (bi.back() - ctrpts.back()).Norm() ) for( int id=0; id<bi.size(); ++id ) ctrpts.push_back(bi[id] ) ; else for( int id=bi.size()-1; id>=0; --id ) ctrpts.push_back(bi[id] ) ; } Curve3D branch; //ReconstructorUtility::getBezier(ctrpts, branch, ctrpts.size() ) ; ReconstructorUtility::getNurbs(ctrpts, branch,100,20 ) ; if( branches.size() == strokes.size() ) branches.back() = branch ; else branches.push_back( branch ) ; // detect loop bool isLoop ; int n=branch.size() ; if( (branch[0] - branch.back()).Norm() < 0.05 && (branch[0] - branch[1] ) *(branch[n-1] - branch[n-2] ) < 0 ){ isLoop = true ; std::cout << "skeleton is loop " <<std::endl; ReconstructorUtility::getPeriodicNurbs(branch, branch, 100,20 ) ; } else{ isLoop = false ; std::cout << "skeleton is not loop " <<std::endl; } // ------------------ prepare the settings -------------- std::vector<Point3f> subpts ; std::vector<int> subptsMapId; //added by huajie,2014/8/19 subptsMapId.clear(); subpts.clear(); ptsSelected = std::vector<bool>(points.size(), false) ; for( int i=0; i<segLable.size(); ++i ){ bool found = false ; for( int j=0; j<asscoBrchId.size(); ++j ) if( asscoBrchId[j] == segLable[i] ) found = true ; if( found ){ subpts.push_back(points[i]) ; ptsSelected[i] = true ; } } ongoingSkel = skelpath( std::vector<Curve3D>(1,branch),false ) ; // [8/14/2014 Cao] ongoingSkel.brch0IsLoop = isLoop ; ongoingSkel.intialSegment( subpts ) ; ongoingSkel.calculateCutplanes() ; ongoingSkel.calculateProfiles() ; std::vector<Point3f> subpointsmp=subpts; ongoingSkel.addPointInJoints(points,subpts,ptsSelected,allJoints,nml); if(subpts.size() == subpointsmp.size()){ cout<<"not add in fact!~~~~~~~~~~~~~~~~~"<<endl; }else{ cout<<subpts.size()-subpointsmp.size()<<" Points added!"<<endl; cout<<points.size()<<" points at all!"<<endl; } ongoingSkel.brch0IsLoop = isLoop ; ongoingSkel.intialSegment( subpts) ; ongoingSkel.calculateCutplanes() ; ongoingSkel.calculateProfiles() ; //delete by huajie //if( !ReconstructorUtility::isTip(ongoingSkel, ctrpts[0]) || ReconstructorUtility::isMidNode(impSkel, ctrpts[0]) ){ // ongoingSkel.removeTips( strokes.back()[0] ) ; // std::cout << "first end is not tip" <<std::endl; //} //if( !ReconstructorUtility::isTip(ongoingSkel, ctrpts.back()) || ReconstructorUtility::isMidNode(impSkel, ctrpts.back()) ){ // ongoingSkel.removeTips( strokes.back().back() ) ; // std::cout << "last end is not tip" <<std::endl; //} if( !isLoop ) ongoingSkel.snapTips(points, normals); ongoingSkel.intialSegment( subpts ) ; ongoingSkel.calculateCutplanes() ; ongoingSkel.calculateProfiles() ; ongoingSkel.initAfterClaculateProfiles() ; return true ; }