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 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; }