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