BOOL ON_Brep::Write( ON_BinaryArchive& file ) const { const ON_Brep* brep = this; ON_Brep* v2brep = 0; if ( file.Archive3dmVersion() <= 2 && !IsValidForV2() ) { v2brep = ON_Brep::New(*this); v2brep->MakeValidForV2(); brep = v2brep; } //BOOL rc = file.Write3dmChunkVersion(3,0); // serialization version //BOOL rc = file.Write3dmChunkVersion(3,1); // added meshes BOOL rc = file.Write3dmChunkVersion(3,2); // added m_is_solid // 2d curves if (rc) rc = brep->m_C2.Write(file); // 3d curves if (rc) rc = brep->m_C3.Write(file); // untrimmed surfaces if (rc) rc = brep->m_S.Write(file); // vertices if (rc) rc = brep->m_V.Write(file); // edges if (rc) rc = brep->m_E.Write(file); // trims if (rc) rc = brep->m_T.Write(file); // loops if (rc) rc = brep->m_L.Write(file); // faces if (rc) rc = brep->m_F.Write(file); // bounding box if (rc) rc = file.WritePoint( brep->m_bbox.m_min ); if (rc) rc = file.WritePoint( brep->m_bbox.m_max ); // end of chunk version 3.0 if (rc) { // added for chunk version 3.1 const int face_count = brep->m_F.Count(); int fi; unsigned char b; // write render meshes rc = file.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 0 ); if ( rc ) { for ( fi = 0; rc && fi < face_count; fi++ ) { const ON_Mesh* mesh = file.Save3dmRenderMeshes() ? brep->m_F[fi].m_render_mesh : 0; b = mesh ? 1 : 0; file.WriteChar(b); if (mesh) { rc = file.WriteObject(*mesh); } } if ( !file.EndWrite3dmChunk() ) { rc = false; } } // write analysis meshes rc = file.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 0 ); if ( rc ) { for ( fi = 0; rc && fi < face_count; fi++ ) { const ON_Mesh* mesh = file.Save3dmAnalysisMeshes() ? brep->m_F[fi].m_analysis_mesh : 0; b = mesh ? 1 : 0; file.WriteChar(b); if (mesh) { rc = file.WriteObject(*mesh); } } if ( !file.EndWrite3dmChunk() ) rc = false; } } // end of chunk version 3.1 // use value of "this" m_is_solid to avoid expensive // calculation on the v2brep if ( !file.WriteInt( m_is_solid ) ) rc = false; // end of chunk version 3.2 if ( 0 != v2brep ) delete v2brep; return rc; }
bool ON_Brep::IsValidForV2() const { bool rc = IsValidTopology()?true:false; if ( rc ) { int c2i, c3i, si, ti, li, ei, vi, fi, next_ti, lti, next_lti, loop_trim_count; ON_3dPoint P0, P1; const int c2_count = m_C2.Count(); const int c3_count = m_C3.Count(); const int s_count = m_S.Count(); const int vertex_count = m_V.Count(); const int edge_count = m_E.Count(); const int face_count = m_F.Count(); const int loop_count = m_L.Count(); const int trim_count = m_T.Count(); for ( c2i = 0; c2i < c2_count; c2i++ ) { // v2 3dm files expect NURBS curves if ( !ON_NurbsCurve::Cast(m_C2[c2i]) ) return false; } for ( c3i = 0; c3i < c3_count; c3i++ ) { // v2 3dm files expect NURBS curves if ( !ON_NurbsCurve::Cast(m_C3[c3i]) ) return false; } for ( si = 0; si < s_count; si++ ) { // v2 3dm files expect NURBS surfaces if ( !ON_NurbsSurface::Cast(m_S[si]) ) return false; } for ( vi = 0; vi < vertex_count; vi++ ) { const ON_BrepVertex& vertex = m_V[vi]; if ( vertex.m_vertex_index != vi ) return false; } for ( fi = 0; fi < face_count; fi++ ) { const ON_BrepFace& face = m_F[fi]; if ( face.m_face_index != fi ) return false; } for ( ti = 0; ti < trim_count; ti++ ) { if ( !IsValidForV2( m_T[ti] ) ) return false; } for ( ei = 0; ei < edge_count; ei++ ) { if ( !IsValidForV2(m_E[ei]) ) return false; } for ( li = 0; li < loop_count; li++ ) { const ON_BrepLoop& loop = m_L[li]; if ( loop.m_loop_index == -1 ) return false; loop_trim_count = loop.m_ti.Count(); for ( lti = 0; lti < loop_trim_count; lti++ ) { next_lti = (lti+1)%loop_trim_count; ti = loop.m_ti[lti]; next_ti = loop.m_ti[next_lti]; if ( ti < 0 || ti >= trim_count ) return false; if ( next_ti < 0 || next_ti >= trim_count ) return false; P0 = m_T[ti].PointAtEnd(); P1 = m_T[next_ti].PointAtStart(); if ( P0.DistanceTo(P1) > ON_ZERO_TOLERANCE ) return false; } } } return rc; }