mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-10 01:45:58 +08:00
Co-authored-by: Bozo <bozo@mcneel.com> Co-authored-by: croudyj <croudyj@gmail.com> Co-authored-by: Dale Fugier <dale@mcneel.com> Co-authored-by: Dale Lear <dalelear@mcneel.com> Co-authored-by: Joshua Kennedy <joshuakennedy102@gmail.com> Co-authored-by: Jussi Aaltonen <jussi@mcneel.com> Co-authored-by: kike-garbo <kike@mcneel.com> Co-authored-by: Luis Fraguada <luis@mcneel.com> Co-authored-by: piac <giulio@mcneel.com> Co-authored-by: Pierre Cuvilliers <pierre@mcneel.com>
192 lines
5.8 KiB
C++
192 lines
5.8 KiB
C++
#include "../opennurbs.h"
|
|
#include "../opennurbs_extensions.h"
|
|
|
|
#include "Tests.h"
|
|
|
|
static
|
|
bool TestNurbsCageEvaluateHelper( ON_TextLog& text_log, const ON_NurbsCage& cage )
|
|
{
|
|
ON_Workspace ws;
|
|
|
|
int err_count = 0;
|
|
int pass_count = 0;
|
|
bool ok = true;
|
|
const int der_count = 3; // <= 3
|
|
const int v_stride = 3;
|
|
ON_NurbsSurface srfst, srfrs, srfrt;
|
|
int cage_hint[3] = {0,0,0};
|
|
int srfst_hint[2] = {0,0};
|
|
int srfrs_hint[2] = {0,0};
|
|
int srfrt_hint[2] = {0,0};
|
|
ON_3dVector cageV,stV,rsV,rtV;
|
|
|
|
ON_3dVector *cagev, *stv, *rsv, *rtv;
|
|
|
|
cagev = (ON_3dVector*)onmalloc(sizeof(*cagev)*(der_count+1)*(der_count+2)*(der_count+3)/6);
|
|
stv = (ON_3dVector*)onmalloc(sizeof(*stv)*(der_count+1)*(der_count+2)/2);
|
|
rsv = (ON_3dVector*)onmalloc(sizeof(*rsv)*(der_count+1)*(der_count+2)/2);
|
|
rtv = (ON_3dVector*)onmalloc(sizeof(*rtv)*(der_count+1)*(der_count+2)/2);
|
|
|
|
int i,j,k,ii,jj,kk,di,dj,dk,dc;
|
|
double r,s,t,errst,errrt,errrs,tol;
|
|
for ( i = cage.m_order[0]-2; ok&&i < cage.m_cv_count[0]-1; i++ )
|
|
{
|
|
ON_Interval rspan(cage.m_knot[0][i],cage.m_knot[0][i+1]);
|
|
if ( rspan.Length() <= 0.0 )
|
|
continue;
|
|
for ( ii = 0; ok && ii <= 4; ii++ )
|
|
{
|
|
r = rspan.ParameterAt(0.25*ii);
|
|
if (!cage.IsoSurface(0,r,&srfst))
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::IsoSurface(dir=1,...) failed");
|
|
ok = false;
|
|
}
|
|
|
|
for ( j = cage.m_order[1]-2; ok && j < cage.m_cv_count[1]-1; j++ )
|
|
{
|
|
ON_Interval sspan(cage.m_knot[1][j],cage.m_knot[1][j+1]);
|
|
if ( sspan.Length() <= 0.0 )
|
|
continue;
|
|
for ( jj = 0; ok && jj <= 4; jj++ )
|
|
{
|
|
s = sspan.ParameterAt(0.25*jj);
|
|
if ( !cage.IsoSurface(1,s,&srfrt) )
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::IsoSurface(dir=1,...) failed");
|
|
ok = false;
|
|
}
|
|
|
|
for ( k = cage.m_order[2]-2; ok && k < cage.m_cv_count[2]-1; k++ )
|
|
{
|
|
ON_Interval tspan(cage.m_knot[2][k],cage.m_knot[2][k+1]);
|
|
if ( tspan.Length() <= 0.0 )
|
|
continue;
|
|
for ( kk = 0; ok && kk <= 4; kk++ )
|
|
{
|
|
t = tspan.ParameterAt(0.25*kk);
|
|
if( !cage.IsoSurface(2,t,&srfrs) )
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::IsoSurface(dir=2,...) failed");
|
|
ok = false;
|
|
}
|
|
|
|
if ( !cage.Evaluate(r,s,t,der_count,v_stride,&cagev[0].x,0,cage_hint))
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::Evaluate - invalid cage");
|
|
ok = false;
|
|
}
|
|
|
|
if ( !srfst.Evaluate(s,t,der_count,v_stride,&stv[0].x,0,srfst_hint))
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::IsoSurface(dir=0,...) returned invalid surface");
|
|
ok = false;
|
|
}
|
|
|
|
if ( !srfrt.Evaluate(s,t,der_count,v_stride,&rtv[0].x,0,srfrt_hint))
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::IsoSurface(dir=1,...) returned invalid surface");
|
|
ok = false;
|
|
}
|
|
|
|
if ( !srfrs.Evaluate(s,t,der_count,v_stride,&rsv[0].x,0,srfrs_hint))
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::IsoSurface(dir=2,...) returned invalid surface");
|
|
ok = false;
|
|
}
|
|
|
|
|
|
for ( dc = 0; dc <= der_count; dc++ )
|
|
{
|
|
tol = pow(10.0,dc-11);
|
|
for ( di = dc; di >= 0; di--)
|
|
{
|
|
for (dj = dc-di; dj >= 0; dj--)
|
|
{
|
|
dk = dc-di-dj;
|
|
if ( di && dj && dk )
|
|
continue;
|
|
cageV = cagev[dc*(dc+1)*(dc+2)/6 + (dj+dk)*(dj+dk+1)/2 + dk];
|
|
stV = (di) ? cageV : stv[(dj+dk)*(dj+dk+1)/2 + dk];
|
|
rtV = (dj) ? cageV : stv[(di+dk)*(di+dk+1)/2 + dk];
|
|
rsV = (dk) ? cageV : stv[(di+dj)*(di+dj+1)/2 + dj];
|
|
errst = (cageV-stV).MaximumCoordinate();
|
|
errrt = (cageV-rtV).MaximumCoordinate();
|
|
errrs = (cageV-rsV).MaximumCoordinate();
|
|
if ( errst > tol && errrt > tol && errrs > tol )
|
|
{
|
|
err_count++;
|
|
ON_ERROR("ON_NurbsCage::Evaluate - bad value");
|
|
if ( err_count > 20 )
|
|
ok = false;
|
|
}
|
|
else
|
|
{
|
|
pass_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
onfree(rtv);
|
|
onfree(rsv);
|
|
onfree(stv);
|
|
onfree(cagev);
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TestNurbsCageEvaluate( ON_TextLog& text_log )
|
|
{
|
|
bool ok = false;
|
|
|
|
ONX_Model model;
|
|
const char* sFileName = "..\\TEstNurbsCageEvaluate.3dm";
|
|
FILE* fp = ON::OpenFile( sFileName, "rb");
|
|
|
|
bool bModelRead = false;
|
|
bool bModelIsValid = false;
|
|
|
|
if ( 0 != fp )
|
|
{
|
|
ON_BinaryFile archive( ON::read3dm, fp );
|
|
bModelRead = model.Read( archive, &text_log );
|
|
ON::CloseFile( fp );
|
|
}
|
|
|
|
if ( !bModelRead )
|
|
{
|
|
text_log.Print("TestNurbsCageEvaluate cannot read %s\n",sFileName);
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
for ( i = 0; i < model.m_object_table.Count(); i++)
|
|
{
|
|
const ONX_Model_Object& mo = model.m_object_table[i];
|
|
const ON_NurbsCage* model_cage = ON_NurbsCage::Cast(mo.m_object);
|
|
if ( !model_cage )
|
|
continue;
|
|
ok = TestNurbsCageEvaluateHelper( text_log, *model_cage );
|
|
if ( !ok )
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|