Files
opennurbs/opennurbs_brep_v2valid.cpp
2024-02-15 08:00:36 -08:00

219 lines
5.9 KiB
C++

//
// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved.
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
// McNeel & Associates.
//
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
//
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
//
////////////////////////////////////////////////////////////////
#include "opennurbs.h"
#if !defined(ON_COMPILING_OPENNURBS)
// This check is included in all opennurbs source .c and .cpp files to insure
// ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled.
// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined
// and the opennurbs .h files alter what is declared and how it is declared.
#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs
#endif
bool ON_Brep::IsValidForV2( const ON_BrepTrim& trim ) const
{
int ti = trim.m_trim_index;
if ( ti < 0 || ti >= m_T.Count() )
return false;
if ( &trim != &m_T[ti] )
return false;
if ( trim.ProxyCurveIsReversed() )
return false;
if ( trim.Domain() != trim.ProxyCurveDomain() )
return false;
const ON_Curve * curve = trim.TrimCurveOf();
if ( curve != trim.ProxyCurve() )
return false;
const ON_NurbsCurve* nurbs_curve = ON_NurbsCurve::Cast(curve);
if ( 0 == nurbs_curve )
return false;
if ( !nurbs_curve->IsClamped(2) )
return false;
if ( nurbs_curve->m_dim != 2 )
return false;
if ( nurbs_curve->m_is_rat )
{
// 2 June 2003 Dale Lear - RR 8809 fix
// V2 likes end weights to be 1.0
if ( nurbs_curve->m_cv[2] != 1.0 || nurbs_curve->CV(nurbs_curve->m_cv_count-1)[2] != 1.0 )
{
return false;
}
}
if ( nurbs_curve->m_cv_count >= 4
&& 0 == ON_ComparePoint( nurbs_curve->m_dim, nurbs_curve->m_is_rat, nurbs_curve->m_cv, nurbs_curve->CV(nurbs_curve->m_cv_count-1) )
)
{
// 14 April 2003 Dale Lear
// RR 8843 - V2 wants ends of this trim farther apart
if ( trim.m_vi[0] != trim.m_vi[1] )
{
const ON_BrepLoop* loop = Loop(trim.m_li);
if ( 0 != loop && loop->m_ti.Count() > 1 )
return false;
}
}
if ( curve->Domain() != trim.Domain() )
return false;
return true;
}
bool ON_Brep::IsValidForV2( const ON_BrepEdge& edge ) const
{
int ei = edge.m_edge_index;
if ( ei < 0 || ei >= m_E.Count() )
return false;
if ( &edge != &m_E[ei] )
return false;
if ( edge.ProxyCurveIsReversed() )
return false;
if ( edge.Domain() != edge.ProxyCurveDomain() )
return false;
const ON_Curve * curve = edge.EdgeCurveOf();
if ( curve != edge.ProxyCurve() )
return false;
const ON_NurbsCurve* nurbs_curve = ON_NurbsCurve::Cast(curve);
if ( 0 == nurbs_curve )
return false;
if ( !nurbs_curve->IsClamped(2) )
return false;
if ( nurbs_curve->m_dim != 3 )
return false;
if ( nurbs_curve->m_is_rat )
{
// 2 June 2003 Dale Lear - RR 8809 fix
// V2 likes end weights to be 1.0
if ( nurbs_curve->m_cv[3] != 1.0 || nurbs_curve->CV(nurbs_curve->m_cv_count-1)[3] != 1.0 )
{
return false;
}
}
if ( curve->Domain() != edge.Domain() )
return false;
// 14 April 2003 Dale Lear
// RR 8808 - V2 requires edges to be strictly closed/open
if ( nurbs_curve->m_cv_count >= 4
&& 0 == ON_ComparePoint( nurbs_curve->m_dim, nurbs_curve->m_is_rat, nurbs_curve->m_cv, nurbs_curve->CV(nurbs_curve->m_cv_count-1) )
)
{
if ( edge.m_vi[0] != edge.m_vi[1] )
return false;
}
else if (edge.m_vi[0] == edge.m_vi[1] )
{
return false;
}
return true;
}
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;
}