/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include #include "mg/Interval.h" #include "mg/Box.h" #include "mg/Position.h" #include "mg/Curve.h" #include "mg/Surface.h" #include "mg/Tolerance.h" #include "topo/CPointsVec.h" #include "topo/Loop.h" #include "topo/Edge.h" #include "topo/LCisect_vector.h" #include "topo/LLisect_vector.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //Debug Function std::ostream& operator<< (std::ostream& out, const mgCONNECT_POINT& cpoint){ out<<"mgCONNECT_POINT::m_trim_loop="<<*(cpoint.m_trim_loop); if(cpoint.m_outin==mgCONNECT_POINT::coming_in){ out<<",coming_in"; }else{ out<<",going_out"; } return out; } std::ostream& operator<< (std::ostream& out, const mgCPointsVec& cpvec){ out<<"mgCPointsVec::"<0.){ if(m_outin==going_out) return true; return false; } } MGVector X=le1.eval(1); double angle1=X.angle2pai(deri1,mgZ_UVEC); double angle2=X.angle2pai(deri2,mgZ_UVEC); return angle1>angle2; } return le1eval_start_deriv(); }else{ return m_trim_loop->eval_end_deriv(); } } //obtain the next point of this connect point. //The next point may be in the same loop, or in a different loop. //function's return value is the mgCONNECT_POINT of the next point. mgCONNECT_POINT mgCONNECT_POINT::next_point( mgCPointsVec& cpointsVec ){ MGTrimLoop* tloop=trim_loop(); int loopid=tloop->end_loopid(); mgCPoints& cpoints=cpointsVec[loopid]; int id=cpoints.find_trim_loop(tloop,coming_in); if(is_coming_in()){ //The next point of the end point of tloop. return cpoints.next_point(id); }else{ //The next point of the start point of trim_loop //(that is the end point of tloop). return cpoints.m_cpoints[id]; } } //obtain the previous point of this connect point. //The previous point may be in the same loop, or in a different loop. //function's return value is the id of cpoints of the previous point. mgCONNECT_POINT mgCONNECT_POINT::prev_point( mgCPointsVec& cpointsVec ){ MGTrimLoop* tloop=trim_loop(); int loopid=tloop->start_loopid(); mgCPoints& cpoints=cpointsVec[loopid]; int id=cpoints.find_trim_loop(tloop,going_out); if(is_coming_in()){ //The previous point of the end point of trim_loop //(that is the start point of tloop). return cpoints.m_cpoints[id]; }else{ //The previous point of the start point of tloop. return cpoints.prev_point(id); } } //extract the loop whose start point is first_point. //Function's return value is: //0: no loop was extracted since first_point was null. //1: a loop was extracted into loop. int mgCPointsVec::extract_loop( mgCONNECT_POINT& first_point, std::unique_ptr& loop, //the loop will be output. std::deque& tloops//used MGTrimLoop to extract loop will be output. ){ if(first_point.is_null()) return 0; mgCONNECT_POINT cpoint, npoint; if(first_point.is_coming_in()){ cpoint=first_point; loop=std::unique_ptr(new MGLoop); }else{ loop=first_point.loop_clone(); tloops.push_back(first_point.trim_loop()); cpoint=first_point.next_point(*this); } //construct loop to the forward direction. int ntloops=(int)m_trim_loops.size(); for(int counter=0; counter loop2=trim_out_subloop(ts,te); loop->join(false,loop2); } if(npoint==first_point){ loop->make_close(); return 1; }else{ loop->join(false,npoint.loop_clone()); tloops.push_back(npoint.trim_loop()); cpoint=npoint.next_point(*this); } if(cpoint==first_point){ loop->make_close(); return 1; } } return 0;//This must not happen. } //get the id of m_cpoints that includes tloop int mgCPoints::find_trim_loop(const MGTrimLoop* tloop, mgCONNECT_POINT::OUTIN out_in)const{ int n=(int)m_cpoints.size(); for(int i=0; i& oloops,//When m_uv is not nul, the closed outerboundary loop //that includes m_uv is output and the return code ==1. //When m_uv is null, all the detected closed outerboundary loops will be output, //and the function's return value is 0. MGPvector& iloops//closed inner boundary loop that //includes uv is output when return code =0 or 1. ){ //std::cout< searched(nedge,NOT_YET); //NOT_YET: not searched yet for the network.edge(i), //SAME: searched for the same direction of the original edge, //OPPOSITE: searched for the opposite direction of the original //BOTH(=SAME+OPPOSITE): searched for the both directions. //Serach for the same direction. bool handled=true; while(handled){ handled=false; for(int i=0; i=BOTH)//If searched in the both directions. continue; std::unique_ptr loop2(new MGLoop); handled=true; const MGEdge* first_edge=network.edge(i);//save the 1st edge to judge loop to the 1st. bool first_was_same_direction; //True means the target loop has the same direction as the previous edge. if(ei_flag==OPPOSITE || ei_flag==NOT_YET){//If search was not done at the same first_was_same_direction=true; }else{//If search was not done at the opposite first_was_same_direction=false; } const MGEdge* edgei=first_edge; bool is_same_direction=first_was_same_direction; int edge_id=i; const MGEdge* next_edge=0; do{//Search is performed toward the loop direction. if(is_same_direction){ searched[edge_id]+=SAME; loop2->append(edgei->clone()); next_edge=edgei->aft_edge(); }else{ searched[edge_id]+=OPPOSITE; MGEdge* ei=edgei->clone(); ei->negate(); loop2->append(ei); next_edge=edgei->aft_edge(false);//aft edge at start point of the edge. } if(next_edge && next_edge!=first_edge){ if(is_same_direction){ if(edgei->is_connected_and_same_direction(false,*next_edge)) is_same_direction=true; else is_same_direction=false; }else{ if(edgei->is_connected_and_same_direction(true,*next_edge)) is_same_direction=false; else is_same_direction=true; } edgei=next_edge; edge_id=network.edge_num(edgei); } }while(next_edge!=0 && next_edge!=first_edge); if(next_edge==first_edge){ //std::cout<<*loop2<make_close(); if(no_uv()){ if(loop2->is_outer_boundary()){ oloops.push_back(loop2.release()); }else iloops.push_back(loop2.release()); }else if(loop2->inside(m_uv)){ if(loop2->is_outer_boundary()){ oloops.push_back(loop2.release()); return 1; }else iloops.push_back(loop2.release()); } }else{ assert(!next_edge); //When edge reached to the boundary of the original face, //opposite direction searching must be done. if(first_was_same_direction){ next_edge=first_edge->pre_edge(); }else{ next_edge=first_edge->pre_edge(false);//pre edge at the end point of 1st edge. } edgei=first_edge; is_same_direction=first_was_same_direction; int iEdge=0;//Counter to prevent non-stop loop. while(next_edge && iEdge++is_connected_and_same_direction(true,*next_edge)) is_same_direction=true; else is_same_direction=false; }else{ if(edgei->is_connected_and_same_direction(false,*next_edge)) is_same_direction=false; else is_same_direction=true; } edgei=next_edge; edge_id=network.edge_num(edgei); if(is_same_direction){ searched[edge_id]+=SAME; loop2->prepend(edgei->clone()); next_edge=edgei->pre_edge(); }else{ searched[edge_id]+=OPPOSITE; MGEdge* ei=edgei->clone(); ei->negate(); loop2->prepend(ei); next_edge=edgei->pre_edge(false);//pre edge at the end point of the edge. } } MGPosition uvS=loop2->start_point(); MGPosition uvE=loop2->end_point(); int inS=m_face.in_range_with_on(uvS), inE=m_face.in_range_with_on(uvE); if(inS>=0 && inS!=4) continue; if(inE>=0 && inE!=4) continue; int lidS=0; if(inS<0) lidS=-inS; int lidE=0; if(inE<0) lidE=-inE; double d; MGLEPoint leS=m_face.loop(int(lidS))->closest(uvS,d), leE=m_face.loop(int(lidE))->closest(uvE,d); //std::cout<& loop, //the loop that includes m_uv will be output //when return code=2. std::deque& used_tloops ){ int nboundaries=size(); for(int i=0; iinside(m_uv)){ for(k=0; kset_null(); continue;//if loop does not includes uv. } return 2; } } return 0; }