static bool ChangeTrimVertex( ON_Brep& brep, ON_BrepTrim& trim, int trim_end, int old_vi, int new_vi, bool bUpdateEdge, bool bUpdateMates ) { // used by ON_Brep::ReplaceSurface() to change trim ends if ( trim_end != 0 && trim_end != 1 ) return false; if ( trim.m_vi[trim_end] != old_vi ) return false; if ( old_vi == new_vi ) return true; trim.m_vi[trim_end] = new_vi; ON_BrepVertex* v = brep.Vertex(old_vi); if ( v ) v->m_tolerance = ON_UNSET_VALUE; v = brep.Vertex(new_vi); if ( v ) v->m_tolerance = ON_UNSET_VALUE; bool rc = true; if ( bUpdateEdge ) { ON_BrepEdge* edge = brep.Edge(trim.m_ei); if ( 0 == edge ) return true; int edge_end = trim.m_bRev3d ? 1-trim_end : trim_end; rc = ChangeEdgeVertex( brep, *edge, edge_end, old_vi, new_vi, bUpdateMates ); } return true; }
static bool SplitSeam( ON_Brep& brep, ON_BrepTrim& trimA, ON_BrepTrim& trimB, ON_BrepTrim& prevtrimB, ON_BrepTrim& nexttrimB, int vcount0 // number of verts before singular fixups ) { if ( trimA.m_trim_index == trimB.m_trim_index ) return false; if ( trimA.m_trim_index == prevtrimB.m_trim_index ) return false; if ( trimA.m_trim_index == nexttrimB.m_trim_index ) return false; if ( trimB.m_trim_index == prevtrimB.m_trim_index ) return false; if ( trimB.m_trim_index == nexttrimB.m_trim_index ) return false; if ( prevtrimB.m_trim_index == nexttrimB.m_trim_index ) return false; if ( trimA.m_type != ON_BrepTrim::seam ) return false; if ( trimB.m_type != ON_BrepTrim::seam ) return false; if ( trimA.m_ei != trimB.m_ei ) return false; if ( trimA.m_vi[0] != trimB.m_vi[1] && trimA.m_vi[0] < vcount0 && trimB.m_vi[1] < vcount0 ) return false; if ( trimA.m_vi[1] != trimB.m_vi[0] && trimA.m_vi[1] < vcount0 && trimB.m_vi[0] < vcount0 ) return false; if ( prevtrimB.m_vi[1] != trimB.m_vi[0] && prevtrimB.m_vi[1] < vcount0 && trimB.m_vi[0] < vcount0 ) return false; if ( nexttrimB.m_vi[0] != trimB.m_vi[1] && prevtrimB.m_vi[0] < vcount0 && trimB.m_vi[1] < vcount0 ) return false; if ( trimA.m_li != trimB.m_li ) return false; if ( trimA.m_li != prevtrimB.m_li ) return false; if ( trimA.m_li != nexttrimB.m_li ) return false; if ( trimA.m_bRev3d == trimB.m_bRev3d ) return false; const ON_Surface* srf = trimA.SurfaceOf(); if ( 0 == srf ) return false; ON_BrepEdge* edgeA = brep.Edge(trimA.m_ei); if ( 0 == edgeA ) return false; if ( edgeA->m_ti.Count() != 2 ) return false; if ( edgeA->m_ti[0] != trimA.m_trim_index && edgeA->m_ti[1] != trimA.m_trim_index ) return false; if ( edgeA->m_ti[0] != trimB.m_trim_index && edgeA->m_ti[1] != trimB.m_trim_index ) return false; // reserve space now so the vA0 and vA1 pointers // will be valid if m_V[] is grown. brep.m_V.Reserve( brep.m_V.Count()+2 ); ON_BrepVertex* vA0 = brep.Vertex(trimA.m_vi[0]); if ( 0 == vA0 ) return false; ON_BrepVertex* vA1 = brep.Vertex(trimA.m_vi[1]); if ( 0 == vA1 ) return false; // looks like we have a valid seam to blow apart // get a new 3d curve for trimB ON_Curve* cB3 = PushUpIsoTrim( brep, trimB ); if ( 0 == cB3 ) return false; int c3i = brep.AddEdgeCurve(cB3); vA0->m_tolerance = ON_UNSET_VALUE; vA1->m_tolerance = ON_UNSET_VALUE; // make new vertices for trimB ON_BrepVertex* vB0 = 0; ON_BrepVertex* vB1 = 0; ON_3dPoint PA, PB; bool bSame = false; if (brep.GetTrim3dStart(trimB.m_trim_index, PB) && brep.GetTrim3dEnd(trimA.m_trim_index, PA)) bSame = PB.DistanceTo(PA) < ON_ZERO_TOLERANCE; if (bSame || trimB.m_vi[0] != trimA.m_vi[1] ) { // sing fixups have already blown apart this end vB0 = brep.Vertex( trimB.m_vi[0] ); } bSame = false; if (brep.GetTrim3dStart(trimA.m_trim_index, PA) && brep.GetTrim3dEnd(trimB.m_trim_index, PB)) bSame = PB.DistanceTo(PA) < ON_ZERO_TOLERANCE; if (bSame || trimB.m_vi[1] != trimA.m_vi[0] ) { // sing fixups have already blown apart this end vB1 = brep.Vertex( trimB.m_vi[1] ); } if ( 0 == vB0 ) { ON_BrepVertex& v = brep.NewVertex(); vB0 = &v; trimB.m_vi[0] = vB0->m_vertex_index; } if ( 0 == vB1 ) { ON_BrepVertex& v = brep.NewVertex(); vB1 = &v; trimB.m_vi[1] = vB1->m_vertex_index; } // disconnect edgeA and trimB trimB.m_ei = -1; if ( edgeA->m_ti[0] == trimB.m_trim_index ) edgeA->m_ti.Remove(0); else if ( edgeA->m_ti[1] == trimB.m_trim_index ) edgeA->m_ti.Remove(1); ChangeTrimVertex( brep, trimB, 0, vA1->m_vertex_index, vB0->m_vertex_index, true, true ); ChangeTrimVertex( brep, trimB, 1, vA0->m_vertex_index, vB1->m_vertex_index, true, true ); ChangeTrimVertex( brep, prevtrimB, 1, vA1->m_vertex_index, vB0->m_vertex_index, true, true ); ChangeTrimVertex( brep, nexttrimB, 0, vA0->m_vertex_index, vB1->m_vertex_index, true, true ); // make a new edgeB and connect it to trimB ON_BrepEdge& edgeB = brep.NewEdge( *vB0, *vB1, c3i ); edgeA = 0; // pointer may be invalid after m_E[] grows edgeB.m_ti.Append(trimB.m_trim_index); trimB.m_ei = edgeB.m_edge_index; trimB.m_bRev3d = false; trimA.m_type = ON_BrepTrim::boundary; trimB.m_type = ON_BrepTrim::boundary; return true; }
static bool ChangeTrimSingToBdry( ON_Brep& brep, ON_BrepTrim& trim, ON_BrepTrim* nexttrim ) { if ( trim.m_vi[0] != trim.m_vi[1] ) return false; if ( trim.m_type != ON_BrepTrim::singular ) return false; if ( trim.m_ei >= 0 ) return false; const ON_Surface* srf = trim.SurfaceOf(); if ( 0 == srf ) return false; brep.m_V.Reserve( brep.m_V.Count() + 1 ); ON_BrepVertex* v0 = brep.Vertex(trim.m_vi[0]); if ( 0 == v0 ) return false; // get new 3d curve ON_Curve* c3 = PushUpIsoTrim( brep, trim ); if ( 0 == c3 ) return false; // valid singular trim can be changed to non-singular trim // create new vertex for end of this trim v0->m_tolerance = ON_UNSET_VALUE; ON_BrepVertex* v1 = 0; if ( c3->IsClosed() ) { // 3d edge is closed so start and end vertex are still the same. v1 = v0; } else { // new 3d edge is not closed, so the single singular vertex // needs to be "split" into two vertices. brep.NewVertex(); v1 = brep.m_V.Last(); } trim.m_vi[1] = v1->m_vertex_index; // update the start of the next trim to use new vertex if ( nexttrim && nexttrim->m_trim_index != trim.m_trim_index ) { ChangeTrimVertex( brep, *nexttrim, 0, v0->m_vertex_index, v1->m_vertex_index, true, true ); } // make a new edge int ci = brep.AddEdgeCurve(c3); c3 = 0; ON_BrepEdge& edge = brep.NewEdge(*v0,*v1,ci); edge.m_tolerance = 0.0; // hook trim to new edge trim.m_type = ON_BrepTrim::boundary; trim.m_bRev3d = false; trim.m_ei = edge.m_edge_index; edge.m_ti.Append(trim.m_trim_index); return true; }
static bool ChangeTrimBdryToSing( ON_Brep& brep, ON_BrepTrim& trim, ON_BrepTrim* prevtrim, ON_BrepTrim* nexttrim ) { if ( trim.m_vi[0] == trim.m_vi[1] ) return false; if ( trim.m_type == ON_BrepTrim::singular ) return false; if ( trim.m_ei < 0 ) return false; int vi0 = trim.m_vi[0]; int vi1 = trim.m_vi[1]; int sing_vi = vi0; ON_BrepVertex* v0 = brep.Vertex(vi0); if ( v0 ) v0->m_tolerance = ON_UNSET_VALUE; ON_BrepVertex* v1 = brep.Vertex(vi1); if ( v1 ) v1->m_tolerance = ON_UNSET_VALUE; ON_BrepEdge* edge = brep.Edge(trim.m_ei); if ( edge ) { for ( int eti = 0; eti < edge->m_ti.Count(); eti++ ) { if ( edge->m_ti[eti] == trim.m_trim_index ) { edge->m_ti.Remove(eti); break; } } trim.m_ei = -1; if ( 0 == edge->m_ti.Count() ) { brep.DeleteEdge( *edge, true ); } else if ( 1 == edge->m_ti.Count() && ON_BrepTrim::seam == trim.m_type ) { // change neighbor trim type ON_BrepTrim* other_trim = brep.Trim(edge->m_ti[0]); if ( 0 != other_trim && ON_BrepTrim::seam == other_trim->m_type ) { other_trim->m_type = ON_BrepTrim::boundary; int j = (trim.m_bRev3d == other_trim->m_bRev3d) ? 0 : 1; if ( trim.m_vi[0] == other_trim->m_vi[j] && trim.m_vi[1] == other_trim->m_vi[1-j] ) { // we need a new singular vertex sing_vi = brep.NewVertex(ON_UNSET_POINT).m_vertex_index; } } } } trim.m_vi[0] = sing_vi; trim.m_vi[1] = sing_vi; trim.m_type = ON_BrepTrim::singular; trim.m_bRev3d = false; if ( nexttrim ) ChangeTrimVertex( brep,*nexttrim,0,vi1,sing_vi,true,true); if ( prevtrim ) ChangeTrimVertex( brep,*prevtrim,1,vi0,sing_vi,true,true); return true; }
static bool ChangeEdgeVertex( ON_Brep& brep, ON_BrepEdge& edge, int edge_end, int old_vi, int new_vi, bool bUpdateTrims ) { // used by ON_Brep::ReplaceSurface() to change edge ends if ( edge_end != 0 && edge_end != 1 ) return false; if ( edge.m_vi[edge_end] != old_vi ) return false; if ( old_vi == new_vi ) return true; ON_BrepVertex* old_v = brep.Vertex(old_vi); if ( old_vi >= 0 && 0 == old_v ) return false; if ( old_v ) old_v->m_tolerance = ON_UNSET_VALUE; ON_BrepVertex* new_v = brep.Vertex(new_vi); if ( new_vi >= 0 && 0 == new_v ) return false; if ( new_v ) old_v->m_tolerance = ON_UNSET_VALUE; // disconnect edge from old vertex if ( old_vi >= 0 ) { for ( int vei = 0; vei < old_v->m_ei.Count(); vei++ ) { if ( old_v->m_ei[vei] == edge.m_edge_index ) { old_v->m_ei.Remove(vei); break; } } } edge.m_vi[edge_end] = new_vi; new_v->m_ei.Append(edge.m_edge_index); if ( bUpdateTrims ) { for ( int eti = 0; eti < edge.m_ti.Count(); eti++ ) { ON_BrepTrim* trim = brep.Trim(edge.m_ti[eti]); if ( 0 == trim ) continue; int trim_end = trim->m_bRev3d ? 1-edge_end : edge_end; if ( trim->m_vi[trim_end] == old_vi ) trim->m_vi[trim_end] = new_vi; } } return true; }