mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-20 01:06:01 +08:00
delete tests dir
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(ON_Test)
|
||||
|
||||
# GoogleTest requires at least C++14
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
URL https://github.com/google/googletest/archive/b10fad38c4026a29ea6561ab15fc4818170d1c10.zip
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory(../../opennurbs build_opennurbs)
|
||||
|
||||
add_executable(
|
||||
test_ClassSize
|
||||
test_ClassSize.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
test_ClassSize
|
||||
GTest::gtest_main
|
||||
OpenNURBS
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(test_ClassSize)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,289 +0,0 @@
|
||||
#if 0
|
||||
|
||||
#include "opennurbs.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BEGIN TestBase64 command
|
||||
//
|
||||
|
||||
class CCommandTestBase64 : public CRhinoTestCommand
|
||||
{
|
||||
public:
|
||||
CCommandTestBase64() {}
|
||||
~CCommandTestBase64() {}
|
||||
UUID CommandUUID()
|
||||
{
|
||||
// {2BE047C-CC30-4178-AFA5-136E79A4335C}
|
||||
static const GUID TestBase64Command_UUID =
|
||||
{ 0x2BE047C, 0xCC30, 0x4178, { 0xAF, 0xA5, 0x13, 0x6E, 0x79, 0xA4, 0x33, 0x5C } };
|
||||
return TestBase64Command_UUID;
|
||||
}
|
||||
const wchar_t* EnglishCommandName() { return RHINOSTRING_COMMAND_NAME(L"TestBase64"); }
|
||||
CRhinoCommand::result RunCommand( const CRhinoCommandContext& );
|
||||
};
|
||||
|
||||
// The one and only CCommandTestBase64 object
|
||||
static class CCommandTestBase64 theTestBase64Command;
|
||||
|
||||
class MyDecode : public ON_DecodeBase64
|
||||
{
|
||||
public:
|
||||
const unsigned char* m_buf;
|
||||
unsigned char* m_buf1;
|
||||
int m_buf_count;
|
||||
MyDecode(const unsigned char* buf, unsigned char* buf1);
|
||||
void Output();
|
||||
};
|
||||
|
||||
MyDecode::MyDecode(const unsigned char* buf, unsigned char* buf1) : m_buf(buf), m_buf1(buf1), m_buf_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MyDecode::Output()
|
||||
{
|
||||
memcpy(m_buf1+m_buf_count,m_output,m_output_count);
|
||||
m_buf_count += m_output_count;
|
||||
|
||||
//for( int i = 0; i < m_output_count; i++ )
|
||||
//{
|
||||
// m_buf1[m_buf_count] = m_output[i];
|
||||
// if ( m_buf[m_buf_count++] != m_output[i] )
|
||||
// {
|
||||
// m_buf_count--;
|
||||
// SetError();
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
class MyEncode : public ON_EncodeBase64
|
||||
{
|
||||
public:
|
||||
char* m_base64;
|
||||
int m_base64_count;
|
||||
MyEncode(char* p);
|
||||
void Output();
|
||||
};
|
||||
|
||||
MyEncode::MyEncode(char* p) : m_base64(p), m_base64_count(0) {}
|
||||
|
||||
void MyEncode::Output()
|
||||
{
|
||||
if ( m_base64_count + m_output_count <= 4000 )
|
||||
{
|
||||
memcpy(m_base64+m_base64_count,m_output,m_output_count);
|
||||
m_base64_count += m_output_count;
|
||||
m_base64[m_base64_count] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Test64(const char* s, const char* e64)
|
||||
{
|
||||
unsigned char buf[3000];
|
||||
char base64[4001];
|
||||
const int ec = ON_GetErrorCount();
|
||||
|
||||
const int buf_count = (int)strlen(s);
|
||||
if ( buf_count > 3000 )
|
||||
return false;
|
||||
|
||||
const int base64_count = 4*(buf_count/3) + ((buf_count%3)?4:0);
|
||||
|
||||
memset(buf,0,sizeof(buf));
|
||||
memset(base64,0,sizeof(base64));
|
||||
MyEncode encode(base64);
|
||||
MyDecode decode((unsigned char*)s,buf);
|
||||
|
||||
encode.Begin();
|
||||
encode.Encode(s,buf_count);
|
||||
encode.End();
|
||||
|
||||
if ( ec != ON_GetErrorCount() )
|
||||
return false;
|
||||
|
||||
if ( buf_count != encode.m_encode_count )
|
||||
return false;
|
||||
|
||||
if ( base64_count != encode.m_base64_count )
|
||||
return false;
|
||||
|
||||
if ( strcmp(base64,e64) )
|
||||
return false;
|
||||
|
||||
decode.Begin();
|
||||
decode.Decode(e64);
|
||||
decode.End();
|
||||
|
||||
if ( ec != ON_GetErrorCount() )
|
||||
return false;
|
||||
|
||||
if ( base64_count != decode.m_decode_count )
|
||||
return false;
|
||||
|
||||
if ( buf_count != decode.m_buf_count )
|
||||
return false;
|
||||
|
||||
if ( strcmp((const char*)buf,s) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CRhinoCommand::result CCommandTestBase64::RunCommand( const CRhinoCommandContext& context )
|
||||
{
|
||||
unsigned char buf[3000];
|
||||
unsigned char buf1[3000];
|
||||
char base64[4001];
|
||||
int ec = ON_GetErrorCount();
|
||||
int jjj;
|
||||
|
||||
memset(buf,0,sizeof(buf));
|
||||
memset(base64,0,sizeof(base64));
|
||||
MyEncode encode(base64);
|
||||
MyDecode decode(buf,buf1);
|
||||
|
||||
{
|
||||
bool b;
|
||||
b = Test64("This is a test", "VGhpcyBpcyBhIHRlc3Q=");
|
||||
if ( b)
|
||||
b = Test64("This is a test1", "VGhpcyBpcyBhIHRlc3Qx");
|
||||
if (b)
|
||||
b = Test64("This is a test12","VGhpcyBpcyBhIHRlc3QxMg==");
|
||||
if ( !b)
|
||||
{
|
||||
ON_ERROR("tests failed");
|
||||
}
|
||||
}
|
||||
|
||||
for ( int buf_count = 1; buf_count <= 64; buf_count++)
|
||||
{
|
||||
RhinoApp().Print("buf_count %d\n",buf_count);
|
||||
const int base64_count = 4*(buf_count/3) + ((buf_count%3)?4:0);
|
||||
|
||||
for ( int buf_index = 0; buf_index < buf_count; buf_index++ )
|
||||
for ( int buf_val = 0; buf_val < 256; buf_val++ )
|
||||
for ( int val_count = 1; val_count <= 5; val_count++ )
|
||||
{
|
||||
int ii=-99;
|
||||
ec = ON_GetErrorCount();
|
||||
for ( int attempt = 0; attempt <= 2; attempt++ )
|
||||
{
|
||||
if ( attempt )
|
||||
{
|
||||
int tryagain = 123;
|
||||
}
|
||||
|
||||
memset(buf,0,buf_count+6);
|
||||
memset(base64,0,base64_count);
|
||||
|
||||
for ( jjj = 0; jjj < val_count; jjj++ )
|
||||
buf[buf_index+jjj] = (buf_val+jjj)%256;
|
||||
|
||||
buf1[0] = buf[0] ? 0 : 0xFF;
|
||||
buf1[buf_count-1] = buf[buf_count-1] ? 0 : 0xFF;
|
||||
buf1[buf_count] = buf[buf_count];
|
||||
|
||||
encode.m_base64_count = 0;
|
||||
encode.Begin();
|
||||
encode.Encode(buf,buf_count);
|
||||
encode.End();
|
||||
|
||||
|
||||
if ( encode.m_encode_count != buf_count )
|
||||
{
|
||||
ON_ERROR("encode - encode.m_encode_count != buf_count");
|
||||
continue;
|
||||
}
|
||||
if ( encode.m_base64_count != base64_count )
|
||||
{
|
||||
ON_ERROR("encode - encode.m_base64_count != base64_count");
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( ii = 0; ii < base64_count; ii++ )
|
||||
{
|
||||
const char* ss;
|
||||
int sz;
|
||||
decode.m_buf_count = 0;
|
||||
decode.Begin();
|
||||
char c = base64[ii];
|
||||
|
||||
if ( ii > 0 )
|
||||
{
|
||||
base64[ii] = 0;
|
||||
ss = decode.Decode(base64);
|
||||
if ( !ss || decode.Error() )
|
||||
{
|
||||
ON_ERROR("decode - first block error");
|
||||
break;
|
||||
}
|
||||
sz = (int)(ss-base64);
|
||||
if ( sz != ii || decode.Error() )
|
||||
{
|
||||
ON_ERROR("decode - first block trauma");
|
||||
break;
|
||||
}
|
||||
base64[ii] = c;
|
||||
}
|
||||
|
||||
ss = decode.Decode(base64+ii);
|
||||
if ( !ss || decode.Error() )
|
||||
{
|
||||
ON_ERROR("decode - 2nd block error");
|
||||
break;
|
||||
}
|
||||
sz = (int)(ss-base64);
|
||||
if ( sz != base64_count || decode.Error() )
|
||||
{
|
||||
ON_ERROR("decode - 2nd block trauma");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !decode.End() )
|
||||
{
|
||||
ON_ERROR("decode - error");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( decode.m_decode_count != base64_count )
|
||||
{
|
||||
ON_ERROR("decode decode.m_decode_count != base64_count");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( memcmp(buf,buf1,buf_count+1) )
|
||||
{
|
||||
ON_ERROR("decode failure");
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
if ( ii > 8 && ii < base64_count-8 )
|
||||
{
|
||||
if ( ii < base64_count/2 )
|
||||
ii = base64_count/2;
|
||||
else
|
||||
ii = base64_count-8;
|
||||
}
|
||||
}
|
||||
if ( 0 == attempt && ec == ON_GetErrorCount() )
|
||||
{
|
||||
break; // no errors - no need to repeat
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return CRhinoCommand::success;
|
||||
}
|
||||
|
||||
//
|
||||
// END TestBase64 command
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
/* $Header: /src4/opennurbs/Tests/TestBooleanUnion.cpp 1 2/11/05 6:32a Dalelear $ */
|
||||
/* $NoKeywords: $ */
|
||||
|
||||
#include "Tests.h"
|
||||
|
||||
void TestBooleanUnion(
|
||||
const ON_Brep* brepA, const wchar_t* nameA
|
||||
const ON_Brep* brepB, const wchar_t* nameB
|
||||
)
|
||||
{
|
||||
// todo test this union
|
||||
}
|
||||
|
||||
void TestBooleanUnion( ON_TextLog& text_log )
|
||||
{
|
||||
TEST_HEADER(text_log,"TestBooleanUnion");
|
||||
|
||||
ONX_Model model;
|
||||
int i, pass;
|
||||
|
||||
double sample_start_distance = 0.0;
|
||||
double sample_stop_distance = 0.0;
|
||||
|
||||
const char* filename = "\\src4\\opennurbs\\Tests\\Input\\TestBooleanUnion.3dm";
|
||||
//const char* filename = "\\src4\\opennurbs\\Tests\\Input\\SmallTest.3dm";
|
||||
|
||||
ON_SimpleArray<const ON_Brep*> brep;
|
||||
ON_ClassArray<ON_wString> brep_name;
|
||||
|
||||
if ( model.Read( filename,&text_log) )
|
||||
{
|
||||
brep.Reserve(model.m_object_table.Count());
|
||||
brep_name.Reserve(model.m_object_table.Count());
|
||||
for ( i = 0; i < model.m_object_table.Count(); i++ )
|
||||
{
|
||||
const ON_Brep* b = ON_Brep::Cast(model.m_object_table[i].m_object);
|
||||
if ( b )
|
||||
{
|
||||
const wchar_t* name = model.m_object_table[i].m_attributes.m_name;
|
||||
if ( 0 == name || 0 == *name)
|
||||
{
|
||||
name = L"anonymous";
|
||||
}
|
||||
brep_name.AppendNew() = name;
|
||||
brep.Append(brep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *nameA, *nameB;
|
||||
const ON_Brep *brepA, *brepB;
|
||||
for ( i = 0; i < brep.Count(); i++ )
|
||||
{
|
||||
brepA = brep[i];
|
||||
nameA = brep_name[i];
|
||||
for ( j = i+1; j < brep.Count(); j++ )
|
||||
{
|
||||
brepB = brep[j];
|
||||
nameB = brep_name[j];
|
||||
TestBooleanUnion( brepA,nameA,brepB,nameB);
|
||||
TestBooleanUnion( brepB,nameB,brepA,nameA);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,709 +0,0 @@
|
||||
|
||||
|
||||
#include "Tests.h"
|
||||
|
||||
class CCCXTest
|
||||
{
|
||||
public:
|
||||
CCCXTest() : TLX0(), TLX1() { TLX0.SetCapacity(5); TLX1.SetCapacity(5);
|
||||
TLX2.SetCapacity(5); TLX3.SetCapacity(5);};
|
||||
ON_3dPoint P; // curve(t)
|
||||
|
||||
ON_SimpleArray<TL_CX_EVENT> TLX0;
|
||||
ON_SimpleArray<TL_CX_EVENT> TLX1;
|
||||
|
||||
ON_SimpleArray<TL_CX_EVENT> TLX2;
|
||||
ON_SimpleArray<TL_CX_EVENT> TLX3;
|
||||
|
||||
IwSolutionArray iwX0;
|
||||
IwSolutionArray iwX1;
|
||||
|
||||
int i0; // Indicies of crv on the array of tranlated curves
|
||||
int i1;
|
||||
|
||||
double t0; // these are the parameters of an intersection point
|
||||
double t1;
|
||||
double d; // == 0 if P = crv(t) and > 0 otherwise
|
||||
|
||||
double gregt;
|
||||
double tlt;
|
||||
double gooset;
|
||||
|
||||
double gregd;
|
||||
double tld;
|
||||
double goosed;
|
||||
};
|
||||
|
||||
class TestCurve{
|
||||
public:
|
||||
TestCurve( const ON_Curve& orig);
|
||||
TestCurve( );
|
||||
~TestCurve();
|
||||
|
||||
void SetCurve( const ON_Curve& orig);
|
||||
ON_Curve* crv;
|
||||
|
||||
void MakeOthers(); // Makes the Iwbs and TL_NURB and gets trees for all three.
|
||||
IwBSplineCurve* Iwbs;
|
||||
|
||||
int gnfrc; //getnurbform return code
|
||||
|
||||
TL_NURB Nurb;
|
||||
|
||||
double t0; // base parameter value
|
||||
};
|
||||
|
||||
TestCurve::TestCurve( const ON_Curve& orig){
|
||||
SetCurve( orig);
|
||||
gnfrc = 0;
|
||||
Iwbs = NULL;
|
||||
}
|
||||
|
||||
TestCurve::TestCurve(){
|
||||
crv = NULL;
|
||||
Iwbs = NULL;
|
||||
}
|
||||
|
||||
TestCurve::~TestCurve(){
|
||||
delete crv;
|
||||
delete Iwbs;
|
||||
}
|
||||
|
||||
void TestCurve::SetCurve( const ON_Curve& orig){
|
||||
if(crv){
|
||||
delete crv;
|
||||
delete Iwbs;
|
||||
Iwbs = NULL;
|
||||
}
|
||||
crv = orig.DuplicateCurve();
|
||||
}
|
||||
|
||||
|
||||
void TestCurve::MakeOthers(){
|
||||
memset(&Nurb,0,sizeof(Nurb));
|
||||
|
||||
ON_NurbsCurve nc;
|
||||
gnfrc = crv->GetNurbForm(nc);
|
||||
|
||||
if(gnfrc<1)
|
||||
return;
|
||||
|
||||
Nurb.dim = nc.m_dim;
|
||||
Nurb.is_rat = nc.m_is_rat;
|
||||
Nurb.order = nc.m_order;
|
||||
Nurb.cv_count = nc.m_cv_count;
|
||||
Nurb.cv = nc.m_cv;
|
||||
Nurb.knot = nc.m_knot;
|
||||
|
||||
|
||||
TL_Convert( Nurb, Iwbs );
|
||||
|
||||
// build GSLib curve tree
|
||||
IwCacheMgr::GetOrCreateObjectCache(IW_OC_CURVE,Iwbs);
|
||||
|
||||
// build Greg's curve tree
|
||||
crv->CurveTree();
|
||||
|
||||
}
|
||||
|
||||
// Get a family of translates of the curve that all go though a supplied Base Point
|
||||
// On input the array contains a single curve.
|
||||
// On output the aray contains a list of translates of the original that pass through the base point.
|
||||
void GetCurveTranslates( const ON_Curve& C0, ON_ClassArray< TestCurve>& C, ON_3dPoint BasePoint )
|
||||
{
|
||||
int Samples_per_span=7; //7 //4;
|
||||
const int MaxSamples=150; //150??
|
||||
const int MinSamples=35;
|
||||
|
||||
const int span_count = C0.SpanCount();
|
||||
if (span_count < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
double* span_vector = (double*)onmalloc((span_count+1)*sizeof(*span_vector));
|
||||
if ( !C0.GetSpanVector(span_vector))
|
||||
return;
|
||||
|
||||
int SpanGrouping = 1;
|
||||
int SpanRemainder = 0;
|
||||
if( span_count * Samples_per_span< MinSamples){
|
||||
Samples_per_span = MinSamples/span_count + 1;
|
||||
}
|
||||
|
||||
if( span_count * Samples_per_span> MaxSamples){
|
||||
int MaxSpans = MaxSamples/ Samples_per_span +1;
|
||||
SpanGrouping = span_count/MaxSpans;
|
||||
SpanRemainder = span_count - SpanGrouping*MaxSpans ;
|
||||
}
|
||||
|
||||
for (int i = 0; i < span_count; )
|
||||
{
|
||||
int j=(i==0)?0:1;
|
||||
ON_Interval span_domain(span_vector[i],span_vector[i+SpanGrouping]);
|
||||
i+=SpanGrouping;
|
||||
if((SpanRemainder--)>0)
|
||||
span_domain[1]= span_vector[++i];
|
||||
|
||||
for ( /* j already init'd*/ ; j <= Samples_per_span; j++ )
|
||||
|
||||
// TODO: use this to avoid knots
|
||||
// for ( int j = 1; j < Samples_per_span; j++ )
|
||||
{
|
||||
double t = span_domain.ParameterAt(((double)j)/((double)Samples_per_span));
|
||||
|
||||
ON_3dPoint P0 = C0.PointAt(t);
|
||||
ON_3dVector Del = BasePoint - P0;
|
||||
|
||||
TestCurve& Ctrans = C.AppendNew();
|
||||
Ctrans.SetCurve( C0);
|
||||
Ctrans.crv->Translate(Del);
|
||||
Ctrans.t0 = t;
|
||||
Ctrans.MakeOthers();
|
||||
}
|
||||
}
|
||||
|
||||
onfree(span_vector);
|
||||
}
|
||||
|
||||
void TestCCX( ON_TextLog& text_log,
|
||||
ON_ClassArray< TestCurve > & Crv0 ,
|
||||
ON_ClassArray< TestCurve > & Crv1,
|
||||
ON_3dPoint BasePoint)
|
||||
{
|
||||
double greg_time = 0.0;
|
||||
double goose_time = 0.0;
|
||||
double tl_time = 0.0;
|
||||
|
||||
ON_ClassArray<CCCXTest> CCX_Result;
|
||||
int N0 = Crv0.Count();
|
||||
int N1 = Crv1.Count();
|
||||
int N = N0 * N1;
|
||||
|
||||
CCX_Result.SetCapacity(N);
|
||||
CCX_Result.SetCount(N);
|
||||
|
||||
// Record expected results
|
||||
int i0, i1, i;
|
||||
for ( i0 = 0; i0 < N0 ; i0++ ){
|
||||
i = N1*i0;
|
||||
for ( i1 = 0; i1 < N1 ; i1++, i++ )
|
||||
{
|
||||
CCX_Result[i].i0 = i0;
|
||||
CCX_Result[i].i1 = i1;
|
||||
CCX_Result[i].t0 = Crv0[i0].t0;
|
||||
CCX_Result[i].t1 = Crv1[i1].t0;
|
||||
}
|
||||
}
|
||||
const double intersection_tolerance = .01;
|
||||
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// Speed Test
|
||||
//
|
||||
|
||||
// TL's curve/curve intersection
|
||||
{
|
||||
TEST_ElapsedTime();
|
||||
for ( i0 = 0; i0 < N0 ; i0++ ){
|
||||
i = N1*i0;
|
||||
for ( i1 = 0; i1 < N1 ; i1++, i++ )
|
||||
{
|
||||
TL_CCX( *Crv0[i0].crv, *Crv1[i1].crv, intersection_tolerance, CCX_Result[i].TLX0);
|
||||
TL_CCX( *Crv1[i1].crv, *Crv0[i0].crv, intersection_tolerance, CCX_Result[i].TLX1);
|
||||
}
|
||||
}
|
||||
tl_time = TEST_ElapsedTime();
|
||||
}
|
||||
|
||||
// Gregs new's curve/curve intersection
|
||||
#if 0
|
||||
{
|
||||
TEST_ElapsedTime();
|
||||
for ( i0 = 0; i0 < N0 ; i0++ ){
|
||||
i = N1*i0;
|
||||
for ( i1 = 0; i1 < N1 ; i1++, i++ )
|
||||
{
|
||||
DaleCCX( *Crv0[i0].crv, *Crv1[i1].crv, intersection_tolerance, CCX_Result[i].TLX2);
|
||||
DaleCCX( *Crv1[i1].crv, *Crv0[i0].crv, intersection_tolerance, CCX_Result[i].TLX3);
|
||||
}
|
||||
}
|
||||
greg_time = TEST_ElapsedTime();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get a GSLib curve
|
||||
{
|
||||
IwStatus iw_rc;
|
||||
IwPoint3d Q;
|
||||
|
||||
TEST_ElapsedTime();
|
||||
for ( i0 = 0; i0 < N0 ; i0++ ){
|
||||
i = N1*i0;
|
||||
for ( i1 = 0; i1 < N1 ; i1++, i++ ){
|
||||
|
||||
ON_Interval D= Crv0[i0].crv->Domain();
|
||||
IwExtent1d Dom0(D.m_t[0],D.m_t[1]);
|
||||
D= Crv1[i1].crv->Domain();
|
||||
IwExtent1d Dom1(D.m_t[0],D.m_t[1]);
|
||||
|
||||
iw_rc = Crv0[i0].Iwbs->GlobalCurveIntersect(
|
||||
Dom0,
|
||||
*Crv1[i1].Iwbs,
|
||||
Dom1,
|
||||
intersection_tolerance,
|
||||
CCX_Result[i].iwX0 );
|
||||
|
||||
if ( iw_rc == IW_SUCCESS && CCX_Result[i].iwX0.GetSize() > 0)
|
||||
{
|
||||
//rc = (sSolutions.GetSize() > 1 ) ? TL_SUCCESS+8 : TL_SUCCESS;
|
||||
//t = X.m_vStart[0];
|
||||
}
|
||||
else {
|
||||
TL_ERROR("GSLib GlobalCurveIntersect failed");
|
||||
}
|
||||
|
||||
iw_rc = Crv1[i1].Iwbs->GlobalCurveIntersect(
|
||||
Dom1,
|
||||
*Crv0[i0].Iwbs,
|
||||
Dom0,
|
||||
intersection_tolerance,
|
||||
CCX_Result[i].iwX1 );
|
||||
|
||||
if ( iw_rc == IW_SUCCESS && CCX_Result[i].iwX1.GetSize() > 0)
|
||||
{
|
||||
//rc = (sSolutions.GetSize() > 1 ) ? TL_SUCCESS+8 : TL_SUCCESS;
|
||||
//t = X.m_vStart[0];
|
||||
}
|
||||
else {
|
||||
TL_ERROR("GSLib GlobalCurveIntersect failed");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
goose_time = TEST_ElapsedTime();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// Accuracy Test
|
||||
//
|
||||
|
||||
|
||||
ON_Interval Dom[2];
|
||||
bool IsClosed[2];
|
||||
Dom[0]= Crv0[0].crv->Domain();
|
||||
Dom[1] = Crv1[0].crv->Domain();
|
||||
IsClosed[0]=Crv0[0].crv->IsClosed()!=0;
|
||||
IsClosed[1]=Crv1[0].crv->IsClosed()!=0;
|
||||
|
||||
double min_time = tl_time;
|
||||
|
||||
double tl_error3d =0;
|
||||
int tl_int_point_cnt=0;
|
||||
int tl_inoverlap_cnt=0;
|
||||
|
||||
double goose_error3d =0;
|
||||
int goose_int_point_cnt=0;
|
||||
int goose_inoverlap_cnt=0;
|
||||
|
||||
double greg_error3d =0;
|
||||
int greg_int_point_cnt=0;
|
||||
int greg_inoverlap_cnt=0;
|
||||
|
||||
for(i=0; i<CCX_Result.Count(); i++){
|
||||
CCCXTest& Test = CCX_Result[i];
|
||||
|
||||
// 3d error to BasePoint
|
||||
int j;
|
||||
int jbest0=-1;
|
||||
int jbest1=-1;
|
||||
double dist;
|
||||
double bestdist1 = ON_DBL_MAX;
|
||||
bool TLInOverlap0=false; // set true if the ideal intersection point is
|
||||
// contained in an overlap
|
||||
bool TLInOverlap1=false; // set true if the ideal intersection point is
|
||||
// contained in an overlap
|
||||
for( j=0; j<Test.TLX0.Count(); j++){
|
||||
if( Test.TLX0[j].type==TL_CCX_POINT){
|
||||
dist = BasePoint.DistanceTo( Test.TLX0[j].A[0]) +
|
||||
BasePoint.DistanceTo( Test.TLX0[j].A[1]);
|
||||
if(dist<bestdist1){
|
||||
bestdist1 = dist;
|
||||
jbest0 = j;
|
||||
}
|
||||
}
|
||||
else if(Test.TLX0[j].type==TL_CCX_OVERLAP){
|
||||
ON_Interval D0(Test.TLX0[j].a[0], Test.TLX0[j].a[1] );
|
||||
D0.m_t[0]-=(1e-6)*fabs(D0.m_t[0]); // fatten it up
|
||||
D0.m_t[1]+=(1e-6)*fabs(D0.m_t[1]); // fatten it up
|
||||
ON_Interval D1(Test.TLX0[j].b[0], Test.TLX0[j].b[1] );
|
||||
D1.MakeIncreasing();
|
||||
D1.m_t[0]-=(1e-6)*fabs(D1.m_t[0]); // fatten it up
|
||||
D1.m_t[1]+=(1e-6)*fabs(D1.m_t[1]); // fatten it up
|
||||
bool InD0 = D0.Includes(Test.t0);
|
||||
if(!InD0 && IsClosed[0] &&
|
||||
(Test.t0 == Dom[0][0] || Test.t0 == Dom[0][1])){
|
||||
InD0= D0.Includes(Dom[0][0]);
|
||||
InD0 = InD0 || D0.Includes(Dom[0][1]);
|
||||
}
|
||||
bool InD1 = D1.Includes(Test.t1);
|
||||
if(!InD1 && IsClosed[1] &&
|
||||
(Test.t1 == Dom[0][1] || Test.t1 == Dom[1][1])){
|
||||
InD1= D1.Includes(Dom[1][0]);
|
||||
InD1 = InD1 || D1.Includes(Dom[1][1]);
|
||||
}
|
||||
if( InD0 && InD1)
|
||||
TLInOverlap0 = true;
|
||||
}
|
||||
}
|
||||
double bestdist0 = bestdist1;
|
||||
|
||||
j=0;
|
||||
jbest1=-1;
|
||||
bestdist1 = ON_DBL_MAX;
|
||||
for( j=0; j<Test.TLX1.Count(); j++){
|
||||
if( Test.TLX1[j].type==TL_CCX_POINT){
|
||||
dist = BasePoint.DistanceTo( Test.TLX1[j].A[0]) +
|
||||
BasePoint.DistanceTo( Test.TLX1[j].A[1]);
|
||||
if(dist<bestdist1){
|
||||
bestdist1 = dist;
|
||||
jbest1 = j;
|
||||
}
|
||||
}
|
||||
else if( Test.TLX1[j].type==TL_CCX_OVERLAP ){
|
||||
ON_Interval D1(Test.TLX1[j].a[0], Test.TLX1[j].a[1] );
|
||||
D1.m_t[0]-=(1e-6)*fabs(D1.m_t[0]); // fatten it up
|
||||
D1.m_t[1]+=(1e-6)*fabs(D1.m_t[1]); // fatten it up
|
||||
ON_Interval D0(Test.TLX1[j].b[0], Test.TLX1[j].b[1] );
|
||||
D0.MakeIncreasing();
|
||||
D0.m_t[0]-=(1e-6)*fabs(D0.m_t[0]); // fatten it up
|
||||
D0.m_t[1]+=(1e-6)*fabs(D0.m_t[1]); // fatten it up
|
||||
bool InD0 = D0.Includes(Test.t0);
|
||||
if(!InD0 && IsClosed[0] &&
|
||||
(Test.t0 == Dom[0][0] || Test.t0 == Dom[0][1])){
|
||||
InD0= D0.Includes(Dom[0][0]);
|
||||
InD0 = InD0 || D0.Includes(Dom[0][1]);
|
||||
}
|
||||
bool InD1 = D1.Includes(Test.t1);
|
||||
if(!InD1 && IsClosed[1] &&
|
||||
(Test.t1 == Dom[0][1] || Test.t1 == Dom[1][1])){
|
||||
InD1= D1.Includes(Dom[1][0]);
|
||||
InD1 = InD1 || D1.Includes(Dom[1][1]);
|
||||
}
|
||||
if( InD0 && InD1)
|
||||
TLInOverlap1 = true;
|
||||
}
|
||||
}
|
||||
bool NoGoodResult = false;
|
||||
if(TLInOverlap0 )
|
||||
tl_inoverlap_cnt++;
|
||||
else if( jbest0>=0){
|
||||
tl_error3d += bestdist0;
|
||||
tl_int_point_cnt++;
|
||||
}
|
||||
else {
|
||||
NoGoodResult = true;
|
||||
}
|
||||
if(TLInOverlap1 )
|
||||
tl_inoverlap_cnt++;
|
||||
else if( jbest1>=0){
|
||||
tl_error3d += bestdist1;
|
||||
tl_int_point_cnt++;
|
||||
}
|
||||
else {
|
||||
NoGoodResult = true;
|
||||
}
|
||||
if(NoGoodResult){
|
||||
NoGoodResult = true; // break here
|
||||
}
|
||||
|
||||
|
||||
// Test accuracy of GregCCX results
|
||||
// 3d error to BasePoint
|
||||
jbest0=-1;
|
||||
jbest1=-1;
|
||||
bestdist1 = ON_DBL_MAX;
|
||||
bool GregInOverlap0=false; // set true if the ideal intersection point is
|
||||
// contained in an overlap
|
||||
bool GregInOverlap1=false; // set true if the ideal intersection point is
|
||||
// contained in an overlap
|
||||
for( j=0; j<Test.TLX2.Count(); j++){
|
||||
if( Test.TLX2[j].type==TL_CCX_POINT){
|
||||
dist = BasePoint.DistanceTo( Test.TLX2[j].A[0]) +
|
||||
BasePoint.DistanceTo( Test.TLX2[j].A[1]);
|
||||
if(dist<bestdist1){
|
||||
bestdist1 = dist;
|
||||
jbest0 = j;
|
||||
}
|
||||
}
|
||||
else if(Test.TLX2[j].type==TL_CCX_OVERLAP){
|
||||
ON_Interval D0(Test.TLX2[j].a[0], Test.TLX2[j].a[1] );
|
||||
D0.m_t[0]-=(1e-6)*fabs(D0.m_t[0]); // fatten it up
|
||||
D0.m_t[1]+=(1e-6)*fabs(D0.m_t[1]); // fatten it up
|
||||
ON_Interval D1(Test.TLX2[j].b[0], Test.TLX2[j].b[1] );
|
||||
D1.MakeIncreasing();
|
||||
D1.m_t[0]-=(1e-6)*fabs(D1.m_t[0]); // fatten it up
|
||||
D1.m_t[1]+=(1e-6)*fabs(D1.m_t[1]); // fatten it up
|
||||
bool InD0 = D0.Includes(Test.t0);
|
||||
if(!InD0 && IsClosed[0] &&
|
||||
(Test.t0 == Dom[0][0] || Test.t0 == Dom[0][1])){
|
||||
InD0= D0.Includes(Dom[0][0]);
|
||||
InD0 = InD0 || D0.Includes(Dom[0][1]);
|
||||
}
|
||||
bool InD1 = D1.Includes(Test.t1);
|
||||
if(!InD1 && IsClosed[1] &&
|
||||
(Test.t1 == Dom[0][1] || Test.t1 == Dom[1][1])){
|
||||
InD1= D1.Includes(Dom[1][0]);
|
||||
InD1 = InD1 || D1.Includes(Dom[1][1]);
|
||||
}
|
||||
if( InD0 && InD1)
|
||||
GregInOverlap0 = true;
|
||||
}
|
||||
}
|
||||
bestdist0 = bestdist1;
|
||||
|
||||
j=0;
|
||||
jbest1=-1;
|
||||
bestdist1 = ON_DBL_MAX;
|
||||
for( j=0; j<Test.TLX3.Count(); j++){
|
||||
if( Test.TLX3[j].type==TL_CCX_POINT){
|
||||
dist = BasePoint.DistanceTo( Test.TLX3[j].A[0]) +
|
||||
BasePoint.DistanceTo( Test.TLX3[j].A[1]);
|
||||
if(dist<bestdist1){
|
||||
bestdist1 = dist;
|
||||
jbest1 = j;
|
||||
}
|
||||
}
|
||||
else if( Test.TLX3[j].type==TL_CCX_OVERLAP ){
|
||||
ON_Interval D1(Test.TLX3[j].a[0], Test.TLX3[j].a[1] );
|
||||
D1.m_t[0]-=(1e-6)*fabs(D1.m_t[0]); // fatten it up
|
||||
D1.m_t[1]+=(1e-6)*fabs(D1.m_t[1]); // fatten it up
|
||||
ON_Interval D0(Test.TLX3[j].b[0], Test.TLX3[j].b[1] );
|
||||
D0.MakeIncreasing();
|
||||
D0.m_t[0]-=(1e-6)*fabs(D0.m_t[0]); // fatten it up
|
||||
D0.m_t[1]+=(1e-6)*fabs(D0.m_t[1]); // fatten it up
|
||||
bool InD0 = D0.Includes(Test.t0);
|
||||
if(!InD0 && IsClosed[0] &&
|
||||
(Test.t0 == Dom[0][0] || Test.t0 == Dom[0][1])){
|
||||
InD0= D0.Includes(Dom[0][0]);
|
||||
InD0 = InD0 || D0.Includes(Dom[0][1]);
|
||||
}
|
||||
bool InD1 = D1.Includes(Test.t1);
|
||||
if(!InD1 && IsClosed[1] &&
|
||||
(Test.t1 == Dom[0][1] || Test.t1 == Dom[1][1])){
|
||||
InD1= D1.Includes(Dom[1][0]);
|
||||
InD1 = InD1 || D1.Includes(Dom[1][1]);
|
||||
}
|
||||
if( InD0 && InD1)
|
||||
GregInOverlap1 = true;
|
||||
}
|
||||
}
|
||||
NoGoodResult = false;
|
||||
if(GregInOverlap0 )
|
||||
greg_inoverlap_cnt++;
|
||||
else if( jbest0>=0){
|
||||
greg_error3d += bestdist0;
|
||||
greg_int_point_cnt++;
|
||||
}
|
||||
else {
|
||||
NoGoodResult = true;
|
||||
}
|
||||
if(GregInOverlap1 )
|
||||
greg_inoverlap_cnt++;
|
||||
else if( jbest1>=0){
|
||||
greg_error3d += bestdist1;
|
||||
greg_int_point_cnt++;
|
||||
}
|
||||
else {
|
||||
NoGoodResult = true;
|
||||
}
|
||||
if(NoGoodResult){
|
||||
NoGoodResult = true; // break here
|
||||
}
|
||||
|
||||
bool GooseInOverlap0=false;
|
||||
bool GooseInOverlap1=false;
|
||||
|
||||
jbest0 = -1;
|
||||
bestdist0 = ON_DBL_MAX;
|
||||
dist = ON_DBL_MAX;
|
||||
int count = Test.iwX0.GetSize();
|
||||
for( j=0; j<count; j++){
|
||||
if( Test.iwX0[j].m_eSolutionType==IW_ST_SINGLE_VALUE){
|
||||
double t0 = Test.iwX0[j].m_vStart[0];
|
||||
double t1 = Test.iwX0[j].m_vStart[1];
|
||||
ON_3dPoint PA = Crv0[Test.i0].crv->PointAt(t0);
|
||||
ON_3dPoint PB = Crv1[Test.i1].crv->PointAt(t1);
|
||||
dist = BasePoint.DistanceTo( PA) +
|
||||
BasePoint.DistanceTo( PB);
|
||||
if(dist<bestdist0){
|
||||
bestdist0 = dist;
|
||||
jbest0 = j;
|
||||
}
|
||||
}
|
||||
else if(Test.iwX0[j].m_eSolutionType==IW_ST_RANGE_OF_VALUES){
|
||||
ON_Interval D0(Test.iwX0[j].m_vStart[0], Test.iwX0[j].m_vEnd[0] );
|
||||
D0.m_t[0]-=(1e-6)*fabs(D0.m_t[0]); // fatten it up
|
||||
D0.m_t[1]+=(1e-6)*fabs(D0.m_t[1]); // fatten it up
|
||||
ON_Interval D1(Test.iwX0[j].m_vStart[1], Test.iwX0[j].m_vEnd[1] );
|
||||
D1.MakeIncreasing();
|
||||
D1.m_t[0]-=(1e-6)*fabs(D1.m_t[0]); // fatten it up
|
||||
D1.m_t[1]+=(1e-6)*fabs(D1.m_t[1]); // fatten it up
|
||||
if( D0.Includes(Test.t0) && D1.Includes(Test.t1))
|
||||
GooseInOverlap0 = true;
|
||||
}
|
||||
}
|
||||
bestdist1 = ON_DBL_MAX;
|
||||
jbest1 = -1;
|
||||
dist = ON_DBL_MAX;
|
||||
count = Test.iwX1.GetSize();
|
||||
for( j=0; j<count; j++){
|
||||
if( Test.iwX1[j].m_eSolutionType==IW_ST_SINGLE_VALUE){
|
||||
double t0 = Test.iwX1[j].m_vStart[1];
|
||||
double t1 = Test.iwX1[j].m_vStart[0];
|
||||
ON_3dPoint PA = Crv0[Test.i0].crv->PointAt(t0);
|
||||
ON_3dPoint PB = Crv1[Test.i1].crv->PointAt(t1);
|
||||
dist = BasePoint.DistanceTo( PA) +
|
||||
BasePoint.DistanceTo( PB);
|
||||
if(dist<bestdist1){
|
||||
bestdist1 = dist;
|
||||
jbest1 = j;
|
||||
}
|
||||
}
|
||||
else if(Test.iwX1[j].m_eSolutionType==IW_ST_RANGE_OF_VALUES){
|
||||
ON_Interval D0(Test.iwX1[j].m_vStart[0], Test.iwX1[j].m_vEnd[0] );
|
||||
D0.m_t[0]-=(1e-6)*fabs(D0.m_t[0]); // fatten it up
|
||||
D0.m_t[1]+=(1e-6)*fabs(D0.m_t[1]); // fatten it up
|
||||
ON_Interval D1(Test.iwX1[j].m_vStart[1], Test.iwX1[j].m_vEnd[1] );
|
||||
D1.MakeIncreasing();
|
||||
D1.m_t[0]-=(1e-6)*fabs(D1.m_t[0]); // fatten it up
|
||||
D1.m_t[1]+=(1e-6)*fabs(D1.m_t[1]); // fatten it up
|
||||
if( D0.Includes(Test.t1) && D1.Includes(Test.t0))
|
||||
GooseInOverlap1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
NoGoodResult = false;
|
||||
if( GooseInOverlap0)
|
||||
goose_inoverlap_cnt++;
|
||||
else if(jbest0>=0){
|
||||
goose_error3d += bestdist0;
|
||||
goose_int_point_cnt++;
|
||||
}
|
||||
else
|
||||
NoGoodResult = true;
|
||||
|
||||
if( GooseInOverlap1)
|
||||
goose_inoverlap_cnt++;
|
||||
else if(jbest1>=0){
|
||||
goose_error3d += bestdist1;
|
||||
goose_int_point_cnt++;
|
||||
}
|
||||
else
|
||||
NoGoodResult = true;
|
||||
|
||||
|
||||
if(NoGoodResult){
|
||||
int jjj=7777; // break here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( goose_time < min_time )
|
||||
min_time = goose_time;
|
||||
if ( 0.0 == min_time )
|
||||
min_time = 1.0/((double)CLOCKS_PER_SEC);
|
||||
text_log.Print("Number of global curve curve intersection tests %d\n",N);
|
||||
text_log.Print("Code: Perfection TL Goose Greg\n");
|
||||
text_log.Print("Relative Time: 1.00X %5.2fX %5.2fX %5.2fX\n", tl_time/min_time, goose_time/min_time, greg_time/min_time);
|
||||
text_log.Print("Absolute Time: 0.0 secs %6.3f secs %6.3f secs %6.3f secs\n", tl_time, goose_time, greg_time);
|
||||
|
||||
text_log.Print("#Points/Overlap: %d/0 %d/%d %d/%d %d/%d \n", 2*N,
|
||||
tl_int_point_cnt, tl_inoverlap_cnt,
|
||||
goose_int_point_cnt, goose_inoverlap_cnt,
|
||||
greg_int_point_cnt, greg_inoverlap_cnt );
|
||||
if(tl_int_point_cnt>0 && goose_int_point_cnt>0 && greg_int_point_cnt>0)
|
||||
text_log.Print("Avg Error: 0.00 %.2g %.2g %.2g \n", tl_error3d/ tl_int_point_cnt,
|
||||
goose_error3d/goose_int_point_cnt ,
|
||||
greg_error3d/ greg_int_point_cnt );
|
||||
}
|
||||
|
||||
void TestCurveCurveIntersection( const ONX_Model& model, ON_TextLog& text_log )
|
||||
{
|
||||
TEST_HEADER(text_log,"TestCurveCurveIntersection");
|
||||
|
||||
int i;
|
||||
|
||||
double sample_start_distance = 0.0;
|
||||
double sample_stop_distance = 0.0;
|
||||
|
||||
ON_ClassArray< ON_ClassArray< TestCurve> > Crv;
|
||||
ON_ClassArray<ON_wString> Name; // Input curve names
|
||||
|
||||
// Base Point for all intersections
|
||||
ON_3dPoint BasePoint(23.74,-394,15);
|
||||
int ci=0;
|
||||
|
||||
if ( model.IsValid() )
|
||||
{
|
||||
for ( i = 0; i < model.m_object_table.Count(); i++ )
|
||||
{
|
||||
const ON_Curve* curve = ON_Curve::Cast(model.m_object_table[i].m_object);
|
||||
if ( curve )
|
||||
{
|
||||
const wchar_t* name = model.m_object_table[i].m_attributes.m_name;
|
||||
if ( 0 == name || 0 == *name)
|
||||
{
|
||||
name = L"anonymous";
|
||||
}
|
||||
Name.Append(name);
|
||||
|
||||
ON_ClassArray<TestCurve>& CrvFamily = Crv.AppendNew();
|
||||
|
||||
GetCurveTranslates(*curve, CrvFamily, BasePoint);
|
||||
ci++;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ON_SimpleArray<int> permute( Name.Count() );
|
||||
permute.SetCount( Name.Count());
|
||||
Name.Sort( ON::heap_sort, permute, ON_CompareIncreasing<ON_wString > );
|
||||
|
||||
for( int ci=0; ci<Name.Count(); ci++){
|
||||
ON_wString dump,string;
|
||||
ON_TextLog log(dump);
|
||||
Crv[permute[ci]][0].crv->Dump(log);
|
||||
|
||||
int si = dump.Find('\n');
|
||||
if(si>0){
|
||||
string = dump.Left(si);
|
||||
dump = dump.Right( dump.Length()-si-1);
|
||||
si = dump.Find('\n');
|
||||
if( si>0)
|
||||
string += dump.Left(si);
|
||||
}
|
||||
text_log.Print(L"Curve %d: name = %s, %s\n",ci, Name[permute[ci]],
|
||||
string);
|
||||
text_log.Print("\n");
|
||||
}
|
||||
|
||||
for(int i0=0; i0<Crv.Count()-1; i0+=2){
|
||||
|
||||
text_log.Print("Intersecting Curve %d with Curve %d.\n", i0,i0+1);
|
||||
|
||||
text_log.PushIndent();
|
||||
|
||||
text_log.Print("\n");
|
||||
|
||||
TestCCX( text_log, Crv[permute[i0]], Crv[permute[i0+1]], BasePoint );
|
||||
|
||||
text_log.PopIndent();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,816 +0,0 @@
|
||||
/* $Header: /src4/opennurbs/Tests/TestCurveSurfaceIntersection.cpp 21 6/16/05 3:40p Dalelear $ */
|
||||
/* $NoKeywords: $ */
|
||||
|
||||
#include "Tests.h"
|
||||
|
||||
static bool bPurify = false;
|
||||
|
||||
static double TestOverlapDistance(
|
||||
ON_Interval overlap_domain,
|
||||
const ON_Curve* curve,
|
||||
const ON_Surface* surface,
|
||||
int sample_count
|
||||
)
|
||||
{
|
||||
int n, j;
|
||||
double w, s, t, d;
|
||||
ON_2dPoint uv;
|
||||
ON_3dPoint C, S;
|
||||
w = 1.0;
|
||||
if (sample_count < 1 )
|
||||
sample_count = 1;
|
||||
|
||||
double maxd = 0.0;
|
||||
|
||||
for ( n = 2; sample_count > 0; n *= 2 )
|
||||
{
|
||||
w *= 0.5;
|
||||
for ( j = 1; j < n; j += 2 )
|
||||
{
|
||||
s = j;
|
||||
s *= w;
|
||||
t = overlap_domain.ParameterAt(s);
|
||||
C = curve->PointAt(t);
|
||||
uv.Set(ON_UNSET_VALUE,ON_UNSET_VALUE);
|
||||
surface->GetClosestPoint(C,&uv.x,&uv.y);
|
||||
S = surface->PointAt(uv.x,uv.y);
|
||||
d = C.DistanceTo(S);
|
||||
if ( d > maxd )
|
||||
{
|
||||
maxd = d;
|
||||
}
|
||||
sample_count--;
|
||||
}
|
||||
}
|
||||
|
||||
return maxd;
|
||||
}
|
||||
|
||||
static
|
||||
int GetGooseCurveSurfaceIntersection(
|
||||
const ON_Curve* curve,
|
||||
const ON_Surface* surface,
|
||||
const IwBSplineCurve* goose_curve,
|
||||
const IwBSplineSurface* goose_surface,
|
||||
double intersection_tolerance,
|
||||
double overlap_tolerance,
|
||||
double test_tolerance,
|
||||
ON_SimpleArray<ON_X_EVENT>& goose_x
|
||||
)
|
||||
{
|
||||
if ( !goose_curve || !goose_surface )
|
||||
return 1;
|
||||
|
||||
ON_3dPoint Cpt[2], Spt[2];
|
||||
int bogus_events_from_old_csx = 0;
|
||||
IwSolutionArray G( 100 );
|
||||
goose_surface->GlobalCurveIntersect(
|
||||
goose_surface->GetNaturalUVDomain(),
|
||||
*goose_curve,
|
||||
goose_curve->GetNaturalInterval(),
|
||||
intersection_tolerance,
|
||||
G
|
||||
);
|
||||
|
||||
unsigned int gi;
|
||||
int i;
|
||||
double d;
|
||||
for ( gi = 0; gi < G.GetSize(); gi++ )
|
||||
{
|
||||
int closest_i = -1;
|
||||
double closest_d = 1.0e300;
|
||||
|
||||
IwSolution& g = G[gi];
|
||||
|
||||
ON_X_EVENT goose_event;
|
||||
IwSolutionType iw_xtype = g.m_eSolutionType;
|
||||
IwPoint3d iwpt;
|
||||
if ( iw_xtype == IW_ST_RANGE_OF_VALUES && g.m_vStart[0] >= g.m_vEnd[0] )
|
||||
{
|
||||
iw_xtype = IW_ST_SINGLE_VALUE;
|
||||
g.m_vEnd[0] = g.m_vStart[0];
|
||||
g.m_vEnd[1] = g.m_vStart[1];
|
||||
g.m_vEnd[2] = g.m_vStart[2];
|
||||
}
|
||||
|
||||
switch ( iw_xtype )
|
||||
{
|
||||
case IW_ST_SINGLE_VALUE:
|
||||
// isolated intersection point
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
|
||||
goose_event.m_a[0] = goose_event.m_a[1] = g.m_vStart[0];
|
||||
goose_event.m_b[0] = goose_event.m_b[2] = g.m_vStart[1];
|
||||
goose_event.m_b[1] = goose_event.m_b[3] = g.m_vStart[2];
|
||||
|
||||
goose_curve->EvaluatePoint(goose_event.m_a[0],iwpt);
|
||||
goose_event.m_A[0].Set(iwpt.x,iwpt.y,iwpt.z);
|
||||
goose_event.m_A[1] = goose_event.m_A[0];
|
||||
|
||||
goose_surface->EvaluatePoint(IwPoint2d(goose_event.m_b[0],goose_event.m_b[1]),iwpt);
|
||||
goose_event.m_B[0].Set(iwpt.x,iwpt.y,iwpt.z);
|
||||
goose_event.m_B[1] = goose_event.m_B[0];
|
||||
break;
|
||||
|
||||
case IW_ST_RANGE_OF_VALUES:
|
||||
// overlap region
|
||||
goose_event.m_type = ON_X_EVENT::csx_overlap;
|
||||
|
||||
goose_event.m_a[0] = g.m_vStart[0];
|
||||
goose_event.m_a[1] = g.m_vEnd[0];
|
||||
goose_event.m_b[0] = g.m_vStart[1];
|
||||
goose_event.m_b[1] = g.m_vStart[2];
|
||||
goose_event.m_b[2] = g.m_vEnd[1];
|
||||
goose_event.m_b[3] = g.m_vEnd[2];
|
||||
|
||||
goose_curve->EvaluatePoint(goose_event.m_a[0],iwpt);
|
||||
goose_event.m_A[0].Set(iwpt.x,iwpt.y,iwpt.z);
|
||||
goose_curve->EvaluatePoint(goose_event.m_a[1],iwpt);
|
||||
goose_event.m_A[1].Set(iwpt.x,iwpt.y,iwpt.z);
|
||||
|
||||
goose_surface->EvaluatePoint(IwPoint2d(goose_event.m_b[0],goose_event.m_b[1]),iwpt);
|
||||
goose_event.m_B[0].Set(iwpt.x,iwpt.y,iwpt.z);
|
||||
goose_surface->EvaluatePoint(IwPoint2d(goose_event.m_b[2],goose_event.m_b[3]),iwpt);
|
||||
goose_event.m_B[1].Set(iwpt.x,iwpt.y,iwpt.z);
|
||||
break;
|
||||
}
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
if ( i && ON_X_EVENT::csx_overlap != goose_event.m_type )
|
||||
{
|
||||
goose_event.m_a[1] = goose_event.m_a[0];
|
||||
goose_event.m_b[2] = goose_event.m_b[0];
|
||||
goose_event.m_b[3] = goose_event.m_b[1];
|
||||
goose_event.m_nodeA_t[1] = goose_event.m_nodeA_t[0];
|
||||
goose_event.m_nodeB_t[2] = goose_event.m_nodeB_t[0];
|
||||
goose_event.m_nodeB_t[3] = goose_event.m_nodeB_t[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
goose_event.m_nodeA_t[i] = goose_event.m_a[i];
|
||||
curve->GetCurveParameterFromNurbFormParameter(goose_event.m_a[i],&goose_event.m_a[i]);
|
||||
goose_event.m_nodeB_t[2*i] = goose_event.m_b[2*i];
|
||||
goose_event.m_nodeB_t[2*i+1] = goose_event.m_b[2*i+1];
|
||||
surface->GetSurfaceParameterFromNurbFormParameter(goose_event.m_b[2*i],goose_event.m_b[2*i+1],&goose_event.m_b[2*i],&goose_event.m_b[2*i+1]);
|
||||
if ( i && goose_event.m_a[1] <= goose_event.m_a[0] )
|
||||
{
|
||||
// micro overlap??
|
||||
bogus_events_from_old_csx++;
|
||||
ON_X_EVENT::CopyEventPart(goose_event,0,goose_event,1);
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d = goose_event.m_A[0].DistanceTo(goose_event.m_B[0]);
|
||||
if ( d > test_tolerance )
|
||||
{
|
||||
bogus_events_from_old_csx++;
|
||||
ON_X_EVENT::CopyEventPart(goose_event,1,goose_event,0);
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
}
|
||||
|
||||
d = goose_event.m_A[1].DistanceTo(goose_event.m_B[1]);
|
||||
if ( d > test_tolerance )
|
||||
{
|
||||
bogus_events_from_old_csx++;
|
||||
if ( goose_event.m_a[0] == goose_event.m_a[1] )
|
||||
continue;
|
||||
ON_X_EVENT::CopyEventPart(goose_event,0,goose_event,1);
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
}
|
||||
|
||||
// validate goose_event
|
||||
Cpt[0] = curve->PointAt(goose_event.m_a[0]);
|
||||
Spt[0] = surface->PointAt(goose_event.m_b[0],goose_event.m_b[1]);
|
||||
Cpt[1] = curve->PointAt(goose_event.m_a[1]);
|
||||
Spt[1] = surface->PointAt(goose_event.m_b[2],goose_event.m_b[3]);
|
||||
d = Cpt[0].DistanceTo(Spt[0]);
|
||||
if ( d > test_tolerance )
|
||||
{
|
||||
bogus_events_from_old_csx++;
|
||||
ON_X_EVENT::CopyEventPart(goose_event,1,goose_event,0);
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
Cpt[0] = Cpt[1];
|
||||
Spt[0] = Spt[1];
|
||||
}
|
||||
|
||||
d = Cpt[1].DistanceTo(Spt[1]);
|
||||
if ( d > test_tolerance )
|
||||
{
|
||||
bogus_events_from_old_csx++;
|
||||
if ( goose_event.m_a[0] == goose_event.m_a[1] )
|
||||
continue;
|
||||
ON_X_EVENT::CopyEventPart(goose_event,0,goose_event,1);
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
}
|
||||
|
||||
if ( ON_X_EVENT::csx_overlap == goose_event.m_type )
|
||||
{
|
||||
d = TestOverlapDistance(ON_Interval(goose_event.m_a[0],goose_event.m_a[1]),
|
||||
curve,surface,120);
|
||||
if ( d > test_tolerance )
|
||||
{
|
||||
bogus_events_from_old_csx++;
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
ON_X_EVENT& e0 = goose_x.AppendNew();
|
||||
e0 = goose_event;
|
||||
ON_X_EVENT::CopyEventPart( e0, 0, e0, 1 );
|
||||
e0.m_type = ON_X_EVENT::csx_point;
|
||||
ON_X_EVENT::CopyEventPart( goose_event, 1, goose_event, 0 );
|
||||
goose_event.m_type = ON_X_EVENT::csx_point;
|
||||
}
|
||||
}
|
||||
|
||||
goose_x.Append(goose_event);
|
||||
}
|
||||
|
||||
return bogus_events_from_old_csx;
|
||||
}
|
||||
|
||||
static int TestCSXCompareWithGoose(
|
||||
ON_TextLog& text_log,
|
||||
CTestCurve& test_curve,
|
||||
CTestSurface& test_surface,
|
||||
const ON_SimpleArray<ON_X_EVENT>& x,
|
||||
int overlap_sample_count,
|
||||
double intersection_tolerance,
|
||||
double overlap_tolerance
|
||||
)
|
||||
{
|
||||
int gi;
|
||||
int j, xi;
|
||||
double d;
|
||||
|
||||
int missed_event_count = 0;
|
||||
|
||||
intersection_tolerance = ON_X_EVENT::IntersectionTolerance(intersection_tolerance);
|
||||
overlap_tolerance = ON_X_EVENT::OverlapTolerance(intersection_tolerance,overlap_tolerance);
|
||||
// testing accuracy
|
||||
const double test_tolerance = 1.01*intersection_tolerance;
|
||||
|
||||
const ON_Curve* curve = test_curve.m_curve;
|
||||
const ON_Surface* surface = test_surface.m_surface;
|
||||
const IwBSplineCurve* goose_curve = test_curve.GooseCurve();
|
||||
const IwBSplineSurface* goose_surface = test_surface.GooseSurface();
|
||||
|
||||
|
||||
ON_SimpleArray<ON_X_EVENT> goose_x(16 + x.Count());
|
||||
int bogus_events_from_old_csx = GetGooseCurveSurfaceIntersection(
|
||||
curve,surface,goose_curve,goose_surface,
|
||||
intersection_tolerance,overlap_tolerance,test_tolerance,
|
||||
goose_x
|
||||
);
|
||||
|
||||
for ( gi = 0; gi < goose_x.Count(); gi++ )
|
||||
{
|
||||
ON_X_EVENT& goose_event = goose_x[gi];
|
||||
for ( j = 0; j < 2; j++ )
|
||||
{
|
||||
if ( j && ON_X_EVENT::csx_overlap != goose_event.m_type)
|
||||
break;
|
||||
|
||||
double closest_d = 1.0e300;
|
||||
int closest_i = -1;
|
||||
|
||||
// find the csx event that is closest to goose_event.m_A[j]
|
||||
for ( xi = 0; xi < x.Count() && closest_d > test_tolerance; xi++ )
|
||||
{
|
||||
const ON_X_EVENT& e = x[xi];
|
||||
d = goose_event.m_A[j].DistanceTo(e.m_A[0]);
|
||||
if ( d < closest_d )
|
||||
{
|
||||
closest_d = d;
|
||||
closest_i = xi;
|
||||
}
|
||||
|
||||
if ( ON_X_EVENT::csx_overlap == e.m_type )
|
||||
{
|
||||
if ( d <= test_tolerance && 0 == j && goose_event.m_a[0] < e.m_a[0] )
|
||||
{
|
||||
goose_event.m_a[0] = e.m_a[0];
|
||||
}
|
||||
|
||||
d = goose_event.m_A[j].DistanceTo(e.m_A[1]);
|
||||
if ( d < closest_d )
|
||||
{
|
||||
closest_d = d;
|
||||
closest_i = xi;
|
||||
}
|
||||
if ( d <= test_tolerance && 1 == j && goose_event.m_a[1] > e.m_a[1] )
|
||||
{
|
||||
goose_event.m_a[1] = e.m_a[1];
|
||||
}
|
||||
|
||||
if ( e.m_a[0] <= goose_event.m_a[j] && goose_event.m_a[j] <= e.m_a[1] )
|
||||
{
|
||||
// goose event is inside an overlap region
|
||||
d = test_tolerance;
|
||||
if ( d < closest_d )
|
||||
{
|
||||
closest_d = d;
|
||||
closest_i = xi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( closest_d > test_tolerance )
|
||||
{
|
||||
ON_ERROR("ON_Curve::IntersectSurface() missed a point");
|
||||
text_log.Print("ERROR: Missed an intersection event at curve(%g) = ",goose_event.m_a[j]);
|
||||
text_log.Print(goose_event.m_A[j]);
|
||||
text_log.Print("\n");
|
||||
missed_event_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ON_X_EVENT::csx_overlap == goose_event.m_type && goose_event.m_a[0] < goose_event.m_a[1] )
|
||||
{
|
||||
// make sure we found this overlap
|
||||
for ( xi = 0; xi < x.Count(); xi++ )
|
||||
{
|
||||
const ON_X_EVENT& e = x[xi];
|
||||
if ( e.m_a[0] <= goose_event.m_a[0] && goose_event.m_a[1] <= e.m_a[1] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( goose_event.m_a[1] - goose_event.m_a[0] <= 1.0e-3
|
||||
&& e.m_A[0].DistanceTo( goose_event.m_A[0] ) <= test_tolerance
|
||||
&& e.m_A[0].DistanceTo( goose_event.m_A[1] ) <= test_tolerance
|
||||
&& e.m_A[0].DistanceTo( curve->PointAt(0.5*(goose_event.m_a[0]+goose_event.m_a[1])) ) <= test_tolerance
|
||||
)
|
||||
{
|
||||
// bogus goose micro overlap
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( xi >= x.Count() )
|
||||
{
|
||||
ON_ERROR("ON_Curve::IntersectSurface() missed an overlap.");
|
||||
text_log.Print("ERROR: Missed an itersection event on curve(%g to %g) = \n",goose_event.m_a[0],goose_event.m_a[1]);
|
||||
text_log.PushIndent();
|
||||
text_log.Print(goose_event.m_A[0]); text_log.Print(" to ");
|
||||
text_log.Print(goose_event.m_A[1]);
|
||||
text_log.PopIndent();
|
||||
text_log.Print("\n");
|
||||
missed_event_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bogus_events_from_old_csx > 0 )
|
||||
{
|
||||
ON_WARNING("Old TL_CSX had bogus events - make sure TestCSXCompareWithGoose() is working right.");
|
||||
text_log.Print("ALERT Old TL_CSX had bogus events - make sure TestCSXCompareWithGoose() is working right.\n\n");
|
||||
}
|
||||
|
||||
return missed_event_count;
|
||||
}
|
||||
|
||||
static int TestCSX( ON_TextLog& text_log,
|
||||
CTestCurve& test_curve,
|
||||
CTestSurface& test_surface,
|
||||
int* missed_event_count
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
const ON_Curve* curve = test_curve.m_curve;
|
||||
|
||||
const ON_Surface* surface = test_surface.m_surface;
|
||||
|
||||
*missed_event_count = 0;
|
||||
|
||||
const int overlap_sample_count = bPurify ? 3 : 255;
|
||||
|
||||
const double intersection_tolerance = 0.0;
|
||||
const double overlap_tolerance = 0.0;
|
||||
|
||||
const ON_CurveTree* ctree = curve->CurveTree();
|
||||
if ( !ctree )
|
||||
{
|
||||
text_log.Print("ERROR - curve->CurveTree() = NULL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const ON_SurfaceTree* stree = surface->SurfaceTree();
|
||||
if ( !stree )
|
||||
{
|
||||
text_log.Print("ERROR - surface->SurfaceTree() = NULL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ON_SimpleArray<ON_X_EVENT> x(16);
|
||||
curve->IntersectSurface(surface,x,intersection_tolerance,overlap_tolerance);
|
||||
|
||||
text_log.Print("%d curve-surface intersection events.\n",x.Count());
|
||||
text_log.PushIndent();
|
||||
|
||||
// dump intersection information
|
||||
ON_String saved_double_format;
|
||||
text_log.GetDoubleFormat(saved_double_format);
|
||||
text_log.SetDoubleFormat("%g"); // so diffs don't flag minute changes
|
||||
for ( i = 0; i < x.Count(); i++ )
|
||||
{
|
||||
text_log.Print("xevent[%d]:\n",i);
|
||||
text_log.PushIndent();
|
||||
x[i].Dump(text_log);
|
||||
text_log.PopIndent();
|
||||
}
|
||||
text_log.SetDoubleFormat(saved_double_format);
|
||||
|
||||
// data structure validation
|
||||
if ( x.Count() > 0 )
|
||||
{
|
||||
text_log.Print("Validating intersection events ...\n");
|
||||
text_log.PushIndent();
|
||||
bool bIsValid = ON_X_EVENT::IsValidList(
|
||||
x.Count(),
|
||||
x.Array(),
|
||||
&text_log,
|
||||
intersection_tolerance,
|
||||
overlap_tolerance,
|
||||
curve,0,
|
||||
0,0,
|
||||
surface,0,0
|
||||
);
|
||||
text_log.PopIndent();
|
||||
if ( bIsValid )
|
||||
{
|
||||
text_log.Print("... Event is list valid.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bPurify )
|
||||
{
|
||||
// Compare results with goose to see if there are any missed events.
|
||||
// (This really slow's down the purify tests - so its skipped in purify builds.)
|
||||
i = TestCSXCompareWithGoose(
|
||||
text_log,
|
||||
test_curve,
|
||||
test_surface,
|
||||
x,
|
||||
overlap_sample_count,
|
||||
intersection_tolerance,
|
||||
overlap_tolerance
|
||||
);
|
||||
|
||||
*missed_event_count = *missed_event_count + i;
|
||||
}
|
||||
|
||||
text_log.PopIndent();
|
||||
|
||||
return x.Count();
|
||||
}
|
||||
|
||||
// tool for saving problem cases in file that has a single curve and surface.
|
||||
bool SaveCSXTest( const char* filename,
|
||||
const ON_Curve* curve,
|
||||
const ON_Surface* surface
|
||||
)
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
if ( curve && surface && filename && filename[0] )
|
||||
{
|
||||
ONX_Model model;
|
||||
|
||||
ONX_Model_Object& curve_object = model.m_object_table.AppendNew();
|
||||
curve_object.m_object = curve;
|
||||
curve_object.m_bDeleteObject = false;
|
||||
|
||||
ONX_Model_Object& surface_object = model.m_object_table.AppendNew();
|
||||
surface_object.m_object = surface;
|
||||
surface_object.m_bDeleteObject = false;
|
||||
|
||||
model.Polish();
|
||||
rc = model.Write(filename);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void TestCurveSurfaceIntersectionListObjects( CTestModel& model, ON_TextLog& text_log )
|
||||
{
|
||||
const int curve_count = model.m_curves.Count();
|
||||
const int surface_count = model.m_surfaces.Count();
|
||||
|
||||
int i;
|
||||
|
||||
const wchar_t* name;
|
||||
ON_UUID curve_uuid, surface_uuid;
|
||||
|
||||
text_log.Print("%d curves:\n",curve_count);
|
||||
text_log.PushIndent();
|
||||
for ( i = 0; i < curve_count; i++ )
|
||||
{
|
||||
CTestCurve& C = model.m_curves[i];
|
||||
curve_uuid = C.m_uuid;
|
||||
name = C.m_name;
|
||||
if ( !name || !name[0] )
|
||||
name = L"anonymous curve";
|
||||
const ON_NurbsCurve& nurbs_curve = C.NurbsCurve();
|
||||
text_log.Print("curve[%d] %s\n",i,C.m_curve->ClassId()->ClassName());
|
||||
text_log.PushIndent();
|
||||
text_log.Print("id: "); text_log.Print(curve_uuid); text_log.Print("\n");
|
||||
text_log.Print(L"name: %s\n",name);
|
||||
text_log.Print("degree = %d, %s, CV count=%d\n",
|
||||
nurbs_curve.m_order-1,
|
||||
(nurbs_curve.m_is_rat ? L"rational" : L"non-rational"),
|
||||
nurbs_curve.m_cv_count
|
||||
);
|
||||
text_log.PopIndent();
|
||||
}
|
||||
text_log.PopIndent();
|
||||
|
||||
|
||||
text_log.Print("\n");
|
||||
text_log.Print("%d surfaces:\n",surface_count);
|
||||
text_log.PushIndent();
|
||||
for ( i = 0; i < surface_count; i++ )
|
||||
{
|
||||
CTestSurface& S = model.m_surfaces[i];
|
||||
surface_uuid = S.m_uuid;
|
||||
name = S.m_name;
|
||||
if ( !name || !name[0] )
|
||||
name = L"anonymous surface";
|
||||
const ON_NurbsSurface& nurbs_surface = S.NurbsSurface();
|
||||
text_log.Print("surface[%d] %s\n",i,S.m_surface->ClassId()->ClassName());
|
||||
text_log.PushIndent();
|
||||
text_log.Print("id: "); text_log.Print(surface_uuid); text_log.Print("\n");
|
||||
text_log.Print(L"name: %s\n",name);
|
||||
text_log.Print(L"degree = (%d,%d), %s, CV count=(%d,%d)\n",
|
||||
nurbs_surface.m_order[0]-1,nurbs_surface.m_order[1]-1,
|
||||
(nurbs_surface.m_is_rat ? L"rational" : L"non-rational"),
|
||||
nurbs_surface.m_cv_count[0],nurbs_surface.m_cv_count[1]
|
||||
);
|
||||
text_log.PopIndent();
|
||||
|
||||
}
|
||||
text_log.PopIndent();
|
||||
}
|
||||
|
||||
|
||||
static int TestCurveSurfaceIntersectionAccuracy( CTestModel& model, ON_TextLog& text_log )
|
||||
{
|
||||
const int curve_count = model.m_curves.Count();
|
||||
const int surface_count = model.m_surfaces.Count();
|
||||
|
||||
ON_UUID curve_uuid, surface_uuid;
|
||||
|
||||
int total_missed_event_count = 0;
|
||||
int missed_event_count;
|
||||
|
||||
int i, j;
|
||||
|
||||
bool bSaveExample = false;
|
||||
|
||||
int event_count = 0;
|
||||
|
||||
|
||||
int bad_curve_index = -1;
|
||||
int bad_surface_index = -1;
|
||||
|
||||
// intersect every curve with every surface
|
||||
for ( i = ( bad_curve_index>=0 ? bad_curve_index : 0); i < curve_count; i++ )
|
||||
{
|
||||
CTestCurve& test_curve = model.m_curves[i];
|
||||
curve_uuid = test_curve.m_uuid;
|
||||
|
||||
for ( j = (bad_surface_index>=0 ? bad_surface_index : 0); j < surface_count; j++ )
|
||||
{
|
||||
CTestSurface& test_surface = model.m_surfaces[j];
|
||||
surface_uuid = test_surface.m_uuid;
|
||||
|
||||
if ( bad_curve_index != -1 && bad_surface_index != -1 )
|
||||
{
|
||||
// use debugger to set bSaveExample = true
|
||||
ON_String filename;
|
||||
filename.Format("C:\\csx_bug_%03d_%03d.3dm",bad_curve_index,bad_surface_index);
|
||||
SaveCSXTest( filename.Array(), test_curve.m_curve, test_surface.m_surface );
|
||||
printf("Saved curve[%d] and surface[%d] in %s\n",i,j,filename.Array());
|
||||
}
|
||||
|
||||
text_log.Print("curve[%d] ",i); text_log.Print(curve_uuid); text_log.Print("\n");
|
||||
text_log.Print("surface[%d] ",j); text_log.Print(surface_uuid); text_log.Print("\n");
|
||||
text_log.PushIndent();
|
||||
missed_event_count = 0;
|
||||
event_count += TestCSX( text_log, test_curve, test_surface, &missed_event_count );
|
||||
total_missed_event_count += missed_event_count;
|
||||
text_log.PopIndent();
|
||||
text_log.Print("\n");
|
||||
|
||||
if ( bad_surface_index == j )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( bad_curve_index == i )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return total_missed_event_count;
|
||||
}
|
||||
|
||||
static void TestCurveSurfaceIntersectionSpeed( CTestModel& model, ON_TextLog& text_log )
|
||||
{
|
||||
const int curve_count = model.m_curves.Count();
|
||||
const int surface_count = model.m_surfaces.Count();
|
||||
|
||||
int i, j;
|
||||
|
||||
// pre-build GSLib trees
|
||||
int c_count = 0;
|
||||
for( i = 0; i < curve_count; i++ )
|
||||
{
|
||||
CTestCurve& C = model.m_curves[i];
|
||||
const IwBSplineCurve* goose_curve = C.GooseCurve();
|
||||
if ( goose_curve )
|
||||
{
|
||||
IwCacheMgr::GetOrCreateObjectCache(IW_OC_CURVE,goose_curve);
|
||||
c_count++;
|
||||
}
|
||||
}
|
||||
|
||||
int s_count = 0;
|
||||
for ( j = 0; j < surface_count; j++ )
|
||||
{
|
||||
CTestSurface& S = model.m_surfaces[j];
|
||||
const IwBSplineSurface* goose_surface = S.GooseSurface();
|
||||
if (goose_surface )
|
||||
{
|
||||
s_count++;
|
||||
IwCacheMgr::GetOrCreateObjectCache(IW_OC_SURFACE,goose_surface);
|
||||
}
|
||||
}
|
||||
|
||||
double intersection_tolerance = 0.001;
|
||||
double dale_time = 0.0;
|
||||
double goose_time = 0.0;
|
||||
double min_time = 0.0;
|
||||
double delta_time;
|
||||
|
||||
int n_count = 0;
|
||||
int dale_event_count = 0;
|
||||
int goose_event_count = 0;
|
||||
|
||||
if ( c_count > 0 && s_count > 0 )
|
||||
{
|
||||
n_count = 1;
|
||||
#if !defined(ON_DEBUG)
|
||||
while ( n_count*c_count*s_count < 20000 )
|
||||
{
|
||||
n_count++;
|
||||
}
|
||||
#endif
|
||||
int n, test;
|
||||
|
||||
// test 0 = dale, 1 = goose
|
||||
for ( test = 0; test < 2; test++ )
|
||||
{
|
||||
if ( 1==test && model.m_bPurify )
|
||||
{
|
||||
n_count = 1;
|
||||
goose_time = dale_time = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
TEST_ElapsedTime();
|
||||
for ( n = 0; n < n_count; n++ )
|
||||
{
|
||||
for( i = 0; i < curve_count; i++ )
|
||||
{
|
||||
CTestCurve& C = model.m_curves[i];
|
||||
const ON_Curve* curve = C.m_curve;
|
||||
const IwBSplineCurve* goose_curve = C.m_goose_curve;
|
||||
if ( 0 == goose_curve )
|
||||
continue;
|
||||
|
||||
for ( j = 0; j < surface_count; j++ )
|
||||
{
|
||||
CTestSurface& S = model.m_surfaces[j];
|
||||
const ON_Surface* surface = S.m_surface;
|
||||
const IwBSplineSurface* goose_surface = S.m_goose_surface;
|
||||
if ( 0 == goose_surface )
|
||||
continue;
|
||||
|
||||
if (test)
|
||||
{
|
||||
// goose
|
||||
IwSolutionArray x(16);
|
||||
goose_surface->GlobalCurveIntersect(
|
||||
goose_surface->GetNaturalUVDomain(),
|
||||
*goose_curve,
|
||||
goose_curve->GetNaturalInterval(),
|
||||
intersection_tolerance,
|
||||
x
|
||||
);
|
||||
if ( !n )
|
||||
goose_event_count += x.GetSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
// dale
|
||||
ON_SimpleArray<ON_X_EVENT> x(16);
|
||||
curve->IntersectSurface( surface, x, intersection_tolerance );
|
||||
if ( !n )
|
||||
dale_event_count += x.Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delta_time = TEST_ElapsedTime();
|
||||
|
||||
switch(test)
|
||||
{
|
||||
case 0:
|
||||
dale_time = delta_time;
|
||||
break;
|
||||
case 1:
|
||||
goose_time = delta_time;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
min_time = (dale_time < goose_time) ? dale_time : goose_time;
|
||||
if ( min_time <= 0.0 )
|
||||
min_time = 1.0;
|
||||
|
||||
text_log.Print("%d repetitions of %d intersection tests.\n",n_count,c_count*s_count);
|
||||
text_log.Print("Test Dale Goose\n");
|
||||
if ( model.m_bPurify )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
text_log.Print("Seconds %6.2f %6.2f\n",dale_time,goose_time);
|
||||
text_log.Print("Relative %5.2fX %5.2fX\n",dale_time/min_time,goose_time/min_time);
|
||||
}
|
||||
text_log.Print("Events %5d %5d\n",dale_event_count,goose_event_count);
|
||||
}
|
||||
|
||||
void TestCurveSurfaceIntersection( CTestModel& model, ON_TextLog& text_log )
|
||||
{
|
||||
TEST_HEADER(text_log,"TestCurveSurfaceIntersection");
|
||||
|
||||
bool bListObjects = true;
|
||||
bool bAccuracyTests = true;
|
||||
bool bSpeedTests = true;
|
||||
|
||||
bPurify = model.m_bPurify;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
bSpeedTests = false;
|
||||
#endif;
|
||||
|
||||
int total_missed_event_count = 0;
|
||||
|
||||
if ( bListObjects && !bPurify )
|
||||
{
|
||||
text_log.Print("\n");
|
||||
text_log.Print("\n");
|
||||
text_log.Print("Curve-Surfaces Intersection Objects:\n");
|
||||
text_log.Print("\n");
|
||||
text_log.PushIndent();
|
||||
TestCurveSurfaceIntersectionListObjects( model, text_log );
|
||||
text_log.PopIndent();
|
||||
}
|
||||
|
||||
if ( bAccuracyTests )
|
||||
{
|
||||
text_log.Print("\n");
|
||||
text_log.Print("\n");
|
||||
text_log.Print("Curve-Surface Intersection Accuracy Tests:\n");
|
||||
text_log.Print("\n");
|
||||
text_log.PushIndent();
|
||||
total_missed_event_count = TestCurveSurfaceIntersectionAccuracy( model, text_log );
|
||||
text_log.PopIndent();
|
||||
}
|
||||
|
||||
if ( bSpeedTests && !bPurify )
|
||||
{
|
||||
text_log.Print("\n");
|
||||
text_log.Print("\n");
|
||||
text_log.Print("Curve-Surface Intersection Speed Tests:\n");
|
||||
text_log.Print("\n");
|
||||
text_log.PushIndent();
|
||||
TestCurveSurfaceIntersectionSpeed(model,text_log );
|
||||
text_log.PopIndent();
|
||||
}
|
||||
|
||||
if ( total_missed_event_count > 0 )
|
||||
{
|
||||
text_log.Print(
|
||||
"Opennurbs may have missed up to %d intersection events \n"
|
||||
"and these potential misses are counted as errors below.\n",
|
||||
total_missed_event_count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include "Tests.h"
|
||||
@@ -1,451 +0,0 @@
|
||||
#include "../opennurbs.h"
|
||||
#include "Tests.h"
|
||||
|
||||
class CF
|
||||
{
|
||||
public:
|
||||
CF() {r = ON_UNSET_VALUE; s = ON_UNSET_VALUE; t = ON_UNSET_VALUE;}
|
||||
double r, s, t;
|
||||
double f[6]; // = x/wr
|
||||
double g[6]; // = y/ws
|
||||
double h[6]; // = z/wt
|
||||
double x[6];
|
||||
double y[6];
|
||||
double z[6];
|
||||
double wr[6];
|
||||
double ws[6];
|
||||
double wt[6];
|
||||
};
|
||||
|
||||
class CV
|
||||
{
|
||||
public:
|
||||
double F, X, W;
|
||||
};
|
||||
|
||||
static class CV func(double r, double s, double t,
|
||||
ON_3dex ijk)
|
||||
{
|
||||
static CF ev;
|
||||
if ( r != ev.r )
|
||||
{
|
||||
ev.x[0] = tan(r);
|
||||
ev.x[1] = 1.0+ev.x[0]*ev.x[0];
|
||||
ev.x[2] = 2.0*ev.x[0]*ev.x[1];
|
||||
ev.x[3] = 2.0*(ev.x[1]*ev.x[1] + ev.x[0]*ev.x[2]);
|
||||
ev.x[4] = 2.0*(3.0*ev.x[1]*ev.x[2] + ev.x[0]*ev.x[3]);
|
||||
ev.x[5] = 2.0*(3.0*ev.x[2]*ev.x[2] + 4.0*ev.x[1]*ev.x[3] + ev.x[0]*ev.x[4]);
|
||||
ev.r = r;
|
||||
|
||||
ev.wr[0] = 1.0/cos(r);
|
||||
ev.wr[1] = ev.wr[0]*ev.x[0];
|
||||
ev.wr[2] = ev.wr[1]*ev.x[0] + ev.wr[0]*ev.x[1];
|
||||
ev.wr[3] = ev.wr[2]*ev.x[0] + 2.0*ev.wr[1]*ev.x[1] + ev.wr[0]*ev.x[2];
|
||||
ev.wr[4] = ev.wr[3]*ev.x[0] + 3.0*ev.wr[2]*ev.x[1] + 3.0*ev.wr[1]*ev.x[2] + ev.wr[0]*ev.x[3];
|
||||
ev.wr[5] = ev.wr[4]*ev.x[0] + 4.0*ev.wr[3]*ev.x[1] + 6.0*ev.wr[2]*ev.x[2] + 4.0*ev.wr[1]*ev.x[3] + ev.wr[0]*ev.x[4];
|
||||
|
||||
ev.f[0] = sin(r);
|
||||
ev.f[1] = cos(r);
|
||||
ev.f[2] = -ev.f[0];
|
||||
ev.f[3] = -ev.f[1];
|
||||
ev.f[4] = -ev.f[2];
|
||||
ev.f[5] = -ev.f[3];
|
||||
}
|
||||
|
||||
if ( s != ev.s )
|
||||
{
|
||||
ev.y[0] = exp(3.0*s);
|
||||
ev.y[1] = 3.0*ev.y[0];
|
||||
ev.y[2] = 9.0*ev.y[0];
|
||||
ev.y[3] = 27.0*ev.y[0];
|
||||
ev.y[4] = 81.0*ev.y[0];
|
||||
ev.y[5] = 243.0*ev.y[0];
|
||||
|
||||
ev.ws[0] = exp(2.0*s);
|
||||
ev.ws[1] = 2.0*ev.ws[0];
|
||||
ev.ws[2] = 4.0*ev.ws[0];
|
||||
ev.ws[3] = 8.0*ev.ws[0];
|
||||
ev.ws[4] = 16.0*ev.ws[0];
|
||||
ev.ws[5] = 32.0*ev.ws[0];
|
||||
|
||||
ev.g[0] = exp(s);
|
||||
ev.g[1] = ev.g[0];
|
||||
ev.g[2] = ev.g[0];
|
||||
ev.g[3] = ev.g[0];
|
||||
ev.g[4] = ev.g[0];
|
||||
ev.g[5] = ev.g[0];
|
||||
ev.s = s;
|
||||
}
|
||||
|
||||
if ( t != ev.t )
|
||||
{
|
||||
double t2 = t*t;
|
||||
double t3 = t*t2;
|
||||
double t4 = t*t3;
|
||||
double t5 = t*t4;
|
||||
double t6 = t*t5;
|
||||
double t7 = t*t6;
|
||||
|
||||
ev.z[0] = t7;
|
||||
ev.z[1] = 7.0*t6;
|
||||
ev.z[2] = 42.0*t5;
|
||||
ev.z[3] = 210.0*t4;
|
||||
ev.z[4] = 840.0*t3;
|
||||
ev.z[5] = 2520.0*t2;
|
||||
|
||||
ev.wt[0] = t5;
|
||||
ev.wt[1] = 5.0*t4;
|
||||
ev.wt[2] = 20.0*t3;
|
||||
ev.wt[3] = 60.0*t2;
|
||||
ev.wt[4] = 120.0*t;
|
||||
ev.wt[5] = 120.0;
|
||||
|
||||
ev.h[0] = t2;
|
||||
ev.h[1] = 2.0*t;
|
||||
ev.h[2] = 2.0;
|
||||
ev.h[3] = 0.0;
|
||||
ev.h[4] = 0.0;
|
||||
ev.h[5] = 0.0;
|
||||
ev.t = t;
|
||||
}
|
||||
|
||||
|
||||
CV V;
|
||||
V.X = ev.x[ijk.i]*ev.y[ijk.j]*ev.z[ijk.k];
|
||||
V.W = ev.wr[ijk.i]*ev.ws[ijk.j]*ev.wt[ijk.k];
|
||||
V.F = ev.f[ijk.i]*ev.g[ijk.j]*ev.h[ijk.k];
|
||||
|
||||
return V;
|
||||
}
|
||||
|
||||
struct TEST_INPUT
|
||||
{
|
||||
int err_count;
|
||||
int pass_count;
|
||||
double der_tol[6];
|
||||
int der_count; // 0 <= der_count <= 5
|
||||
int dim; // dim > 0
|
||||
int n; // 0 <= n < dim
|
||||
int v_stride; // dim < v_stride <= 7
|
||||
double v[6*7*8*7]; // >= (dc+1)*(dc+2)*(dc+3)&v_stride dc = max der_count, vs = max v_stride
|
||||
double a[6*7*8]; // >= (dc+1)*(dc+2)*(dc+3)
|
||||
ON_3dex ijk[6*7*8]; // >= (dc+1)*(dc+2)*(dc+3)
|
||||
|
||||
double maxe1;
|
||||
double maxe2;
|
||||
double maxe3;
|
||||
};
|
||||
|
||||
static void TestQR1(double r, double s, double t,
|
||||
int coord,
|
||||
TEST_INPUT& TI
|
||||
)
|
||||
{
|
||||
CV V;
|
||||
double e;
|
||||
|
||||
int err_count = 0;
|
||||
|
||||
int ii = (coord==0)?1:0;
|
||||
int jj = (coord==1)?1:0;
|
||||
int kk = (coord==2)?1:0;
|
||||
|
||||
int dc;
|
||||
|
||||
for (dc = 0; dc <= TI.der_count; dc++ )
|
||||
{
|
||||
TI.ijk[dc].i = ii*dc;
|
||||
TI.ijk[dc].j = jj*dc;
|
||||
TI.ijk[dc].k = kk*dc;
|
||||
V = func(r,s,t, TI.ijk[dc]);
|
||||
TI.v[dc*TI.v_stride+TI.n] = V.X;
|
||||
TI.v[dc*TI.v_stride+TI.dim] = V.W;
|
||||
TI.a[dc] = V.F;
|
||||
}
|
||||
|
||||
if ( !ON_EvaluateQuotientRule(TI.dim,TI.der_count,TI.v_stride,TI.v) )
|
||||
{
|
||||
ON_ERROR("ON_EvaluateQuotientRule - error");
|
||||
TI.err_count += (TI.der_count+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( dc = 0; dc <= TI.der_count; dc++ )
|
||||
{
|
||||
e = fabs(TI.a[dc] - TI.v[dc*TI.v_stride+TI.n]);
|
||||
if ( e > TI.der_tol[dc] && e > ON_SQRT_EPSILON*fabs(TI.a[dc]) )
|
||||
{
|
||||
ON_ERROR("ON_EvaluateQuotientRule - error");
|
||||
TI.err_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( e > TI.maxe1 )
|
||||
TI.maxe1 = e;
|
||||
TI.pass_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void TestQR2(double r, double s, double t,
|
||||
int coord,
|
||||
TEST_INPUT& TI
|
||||
)
|
||||
{
|
||||
CV V;
|
||||
double e;
|
||||
|
||||
int imax = (coord==0)?0:1;
|
||||
int jmax = (coord==1)?0:1;
|
||||
int kmax = (coord==2)?0:1;
|
||||
|
||||
int i=0;
|
||||
int j=0;
|
||||
int k=0;
|
||||
int mmax=0;
|
||||
int m,der_count;
|
||||
|
||||
for ( der_count = 0; der_count <= TI.der_count; der_count++ )
|
||||
{
|
||||
for (m = 0; m <= der_count; m++ )
|
||||
{
|
||||
if ( 0 == coord )
|
||||
{
|
||||
TI.ijk[mmax].i = 0;
|
||||
TI.ijk[mmax].j = der_count-m;
|
||||
TI.ijk[mmax].k = m;
|
||||
}
|
||||
else if ( 1 == coord )
|
||||
{
|
||||
TI.ijk[mmax].i = der_count-m;
|
||||
TI.ijk[mmax].j = 0;
|
||||
TI.ijk[mmax].k = m;
|
||||
}
|
||||
else
|
||||
{
|
||||
TI.ijk[mmax].i = der_count-m;
|
||||
TI.ijk[mmax].j = m;
|
||||
TI.ijk[mmax].k = 0;
|
||||
}
|
||||
V = func(r,s,t, TI.ijk[mmax]);
|
||||
TI.v[mmax*TI.v_stride+TI.n] = V.X;
|
||||
TI.v[mmax*TI.v_stride+TI.dim] = V.W;
|
||||
TI.a[mmax] = V.F;
|
||||
mmax++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ON_EvaluateQuotientRule2(TI.dim,TI.der_count,TI.v_stride,TI.v) )
|
||||
{
|
||||
ON_ERROR("ON_EvaluateQuotientRule2 - error");
|
||||
TI.err_count += mmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( m = 0; m < mmax; m++ )
|
||||
{
|
||||
e = fabs(TI.a[m] - TI.v[m*TI.v_stride+TI.n]);
|
||||
der_count = TI.ijk[m].i+TI.ijk[m].j+TI.ijk[m].k;
|
||||
if ( e > TI.der_tol[der_count] && e > ON_SQRT_EPSILON*fabs(TI.a[m]) )
|
||||
{
|
||||
ON_ERROR("ON_EvaluateQuotientRule2 - error");
|
||||
TI.err_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( e > TI.maxe2 )
|
||||
TI.maxe2 = e;
|
||||
TI.pass_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void TestQR3(double r, double s, double t,
|
||||
TEST_INPUT& TI
|
||||
)
|
||||
{
|
||||
CV V;
|
||||
double e;
|
||||
|
||||
int i=0;
|
||||
int j=0;
|
||||
int k=0;
|
||||
int mmax=0;
|
||||
int m,der_count;
|
||||
|
||||
for ( der_count = 0; der_count <= TI.der_count; der_count++ )
|
||||
{
|
||||
for ( i = der_count; i >= 0; i-- )
|
||||
{
|
||||
for ( j = der_count-i; j >= 0; j-- )
|
||||
{
|
||||
k = der_count-i-j;
|
||||
TI.ijk[mmax].i = i;
|
||||
TI.ijk[mmax].j = j;
|
||||
TI.ijk[mmax].k = k;
|
||||
V = func(r,s,t, TI.ijk[mmax]);
|
||||
TI.v[mmax*TI.v_stride+TI.n] = V.X;
|
||||
TI.v[mmax*TI.v_stride+TI.dim] = V.W;
|
||||
TI.a[mmax] = V.F;
|
||||
mmax++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ON_EvaluateQuotientRule3(TI.dim,TI.der_count,TI.v_stride,TI.v) )
|
||||
{
|
||||
ON_ERROR("ON_EvaluateQuotientRule3 - error");
|
||||
TI.err_count += mmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( m = 0; m < mmax; m++ )
|
||||
{
|
||||
e = fabs(TI.a[m] - TI.v[m*TI.v_stride+TI.n]);
|
||||
der_count = TI.ijk[m].i+TI.ijk[m].j+TI.ijk[m].k;
|
||||
if ( e > TI.der_tol[der_count] && e > ON_SQRT_EPSILON*fabs(TI.a[m]) )
|
||||
{
|
||||
ON_ERROR("ON_EvaluateQuotientRule3 - error");
|
||||
TI.err_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( e > TI.maxe3 )
|
||||
TI.maxe3 = e;
|
||||
TI.pass_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TestQuotientRule( ON_TextLog& text_log )
|
||||
{
|
||||
|
||||
double r,s,t;
|
||||
struct TEST_INPUT TI;
|
||||
|
||||
memset(&TI,0,sizeof(TI));
|
||||
TI.der_tol[0] = 1.0e-12;
|
||||
TI.der_tol[1] = 1.0e-11;
|
||||
TI.der_tol[2] = 1.0e-10;
|
||||
TI.der_tol[3] = 1.0e-9;
|
||||
TI.der_tol[4] = 1.0e-8;
|
||||
TI.der_tol[5] = 5.0e-7;
|
||||
|
||||
TI.der_count = 0;
|
||||
TI.dim = 1;
|
||||
TI.n = 0;
|
||||
TI.v_stride = TI.dim+1;
|
||||
bool ok = true;
|
||||
for (TI.der_count=0; TI.der_count<=5 && ok; TI.der_count++)
|
||||
for (TI.dim = 1; TI.dim <= 4 && ok; TI.dim++ )
|
||||
for (TI.n= 0; TI.n < TI.dim && ok; TI.n++)
|
||||
for (TI.v_stride=TI.dim+1; TI.v_stride<=7 && ok; TI.v_stride++)
|
||||
{
|
||||
memset(TI.v,0,sizeof(TI.v));
|
||||
|
||||
// one paramter tests
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( r = -ON_PI/3.0; r <= ON_PI/3.0 && ok; r += ON_PI/120.0)
|
||||
{
|
||||
TestQR1(r,s,t,0,TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( s = -2.0; s <= 2.0 && ok; s += 0.1 )
|
||||
{
|
||||
TestQR1(r,s,t,1,TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( t = 0.1; t < 2.5 && ok; t += 0.1 )
|
||||
{
|
||||
TestQR1(r,s,t,2,TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// two paramter tests
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( r = -ON_PI/3.0; r <= ON_PI/3.0 && ok; r += ON_PI/120.0)
|
||||
{
|
||||
for ( s = -2.0; s <= 2.0 && ok; s += 0.1 )
|
||||
{
|
||||
TestQR2(r,s,t, 2, TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( r = -ON_PI/3.0; r <= ON_PI/3.0 && ok; r += ON_PI/120.0)
|
||||
{
|
||||
for ( t = 0.1; t < 2.5 && ok; t += 0.1 )
|
||||
{
|
||||
TestQR2(r,s,t, 1, TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( s = -2.0; s <= 2.0 && ok; s += 0.1 )
|
||||
{
|
||||
for ( t = 0.1; t < 2.5 && ok; t += 0.1 )
|
||||
{
|
||||
TestQR2(r,s,t, 1, TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
// three paramter tests
|
||||
r = 0.25*ON_PI;
|
||||
s = 0.0;
|
||||
t = 1.0;
|
||||
|
||||
for ( r = -ON_PI/3.0; r <= ON_PI/3.0 && ok; r += ON_PI/120.0)
|
||||
{
|
||||
for ( s = -2.0; s <= 2.0 && ok; s += 0.1 )
|
||||
{
|
||||
for ( t = 0.1; t < 2.5 && ok; t += 0.1 )
|
||||
{
|
||||
TestQR3(r,s,t, TI);
|
||||
if (TI.err_count > 100 )
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text_log.Print("pass_count = %d err_count = %d maxe1 = %g maxe2 = %g maxe3 = %g\n",
|
||||
TI.pass_count,TI.err_count,TI.maxe1,TI.maxe2,TI.maxe3);
|
||||
|
||||
return (TI.err_count == 0);
|
||||
}
|
||||
@@ -1,647 +0,0 @@
|
||||
#include "Tests.h"
|
||||
|
||||
|
||||
static const bool bPurify = false;
|
||||
static const bool bDoCurves = true;
|
||||
static const bool bDoSurfaces = true;
|
||||
|
||||
bool TestCurveTree(ON_TextLog& text_log, const ON_Curve* curve )
|
||||
{
|
||||
if ( !curve )
|
||||
{
|
||||
text_log.Print("Curve pointer is NULL.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const ON_CurveTree* tree = curve->CurveTree();
|
||||
if ( !tree )
|
||||
{
|
||||
text_log.Print("CurveTree() returned NULL.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rc = tree->IsValid( &text_log, curve );
|
||||
if ( !rc )
|
||||
{
|
||||
text_log.Print("Curve tree is not valid\n");
|
||||
}
|
||||
|
||||
if ( tree != tree->m_root )
|
||||
{
|
||||
// As of 29 March, I want tree to be = tree->m_root.
|
||||
// and I'd like to get rid of the m_root field, but
|
||||
// I don't know if that will work for making
|
||||
// auxillary tree's over a set of trees.
|
||||
text_log.Print("Curve tree != tree->m_root - please tell Dale Lear.\n");
|
||||
}
|
||||
|
||||
const int span_count = curve->SpanCount();
|
||||
ON_SimpleArray<double> t(10*(span_count+1));
|
||||
t.SetCount(span_count+1);
|
||||
curve->GetSpanVector(t.Array());
|
||||
int i;
|
||||
for ( i = 0; i < span_count; i++ )
|
||||
{
|
||||
t.Append(0.5*(t[i]+t[i+1]));
|
||||
}
|
||||
|
||||
|
||||
ON_CurveTreeNode* leaf = tree->FirstLeaf();
|
||||
int leaf_count=0;
|
||||
double maxar = 0.0;
|
||||
double maxr = 0.0;
|
||||
double maxlen = 0.0;
|
||||
double longest = 0.0;
|
||||
double thickest = 0.0;
|
||||
double shortest = fabs(ON_UNSET_VALUE);
|
||||
ON_Line axis;
|
||||
int notmonocount = 0;
|
||||
while (leaf)
|
||||
{
|
||||
if ( t.Search( leaf->m_domain[0] ) < 0 )
|
||||
t.Append(leaf->m_domain[0]);
|
||||
t.Append( leaf->m_domain.ParameterAt(0.2) );
|
||||
t.Append( leaf->m_domain.ParameterAt(0.7) );
|
||||
if( !leaf->m_bez->m_leafbox.m_bMono )
|
||||
notmonocount++;
|
||||
axis.from = leaf->m_bez->PointAt(0.0);
|
||||
axis.to = leaf->m_bez->PointAt(1.0);
|
||||
double len = axis.Length();
|
||||
if (len > longest )
|
||||
longest = len;
|
||||
if ( len < shortest )
|
||||
shortest = len;
|
||||
if ( leaf->m_bez->m_leafbox.m_r > thickest )
|
||||
thickest = leaf->m_bez->m_leafbox.m_r;
|
||||
if ( leaf->m_bez->m_leafbox.m_r > maxar*len )
|
||||
{
|
||||
maxar = leaf->m_bez->m_leafbox.m_r/len;
|
||||
maxlen = len;
|
||||
maxr = leaf->m_bez->m_leafbox.m_r;
|
||||
}
|
||||
leaf_count++;
|
||||
leaf = leaf->NextLeaf();
|
||||
}
|
||||
if ( notmonocount > 0 )
|
||||
{
|
||||
text_log.Print("ON_CurveTree: %d spans, %d leaves (%d are not monotone).\n",span_count,leaf_count,notmonocount);
|
||||
}
|
||||
else
|
||||
{
|
||||
text_log.Print("ON_CurveTree: %d spans, %d leaves (all are monotone).\n",span_count,leaf_count);
|
||||
}
|
||||
|
||||
text_log.PushIndent();
|
||||
text_log.Print("Shortest: %g\n",shortest);
|
||||
text_log.Print("Longest: %g\n",longest);
|
||||
text_log.Print("Thickest: radius = %g\n",thickest);
|
||||
text_log.Print("Fattest: rad/len = %g (rad = %g, len = %g)\n",maxar,maxr,maxlen);
|
||||
text_log.PopIndent();
|
||||
|
||||
// test evaluation
|
||||
const bool bAdjustParameter = tree->AdjustParameter();
|
||||
double x, y, d0, d1, tol0, tol1;
|
||||
ON_3dVector X[2], Y[2], Xerr[2], Yerr[2];
|
||||
double xerr, yerr, d0err=0.0, d1err=0.0;
|
||||
int error_count = 0;
|
||||
int test_count = 0;
|
||||
int hint = 0;
|
||||
int side = 0;
|
||||
const ON_CurveTreeNode* evaluation_node;
|
||||
if ( 2 == curve->Dimension() )
|
||||
{
|
||||
X[0].z = X[1].z = Y[0].z = Y[1].z = 0.0;
|
||||
}
|
||||
for ( i = 0; i < t.Count(); i++ )
|
||||
{
|
||||
x = y = t[i];
|
||||
if ( i > span_count && bAdjustParameter)
|
||||
{
|
||||
// NOTE - the curve paramter = nurbs form paramter
|
||||
// at all span vector values.
|
||||
curve->GetCurveParameterFromNurbFormParameter(x,&y);
|
||||
}
|
||||
for ( side = -1; side < 1; side++ )
|
||||
{
|
||||
test_count++;
|
||||
X[0].x = -99.0;
|
||||
Y[0].x = 99.0;
|
||||
curve->Evaluate(y,1,3,&Y[0].x,side,&hint);
|
||||
evaluation_node = tree->Evaluate(x,1,3,&X[0].x,side);
|
||||
if ( !evaluation_node )
|
||||
{
|
||||
error_count++;
|
||||
ON_ERROR("TestCurveTree() - tree failed to evaluate.");
|
||||
d0err = 1.0e100;
|
||||
d1err = 1.0e100;
|
||||
xerr = x;
|
||||
yerr = y;
|
||||
Xerr[0] = ON_UNSET_POINT;
|
||||
Xerr[1] = ON_UNSET_POINT;
|
||||
Yerr[0] = Y[0];
|
||||
Yerr[1] = Y[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( side < 0 && x == evaluation_node->m_domain[0] )
|
||||
{
|
||||
// x should be at the start of the curve's domain
|
||||
// and there shouldn't be any leaves before this one.
|
||||
if ( evaluation_node->PrevLeaf() || x != t[0] )
|
||||
{
|
||||
ON_ERROR("TestCurveTree() - evaluation used wrong node");
|
||||
}
|
||||
}
|
||||
else if ( side > 0 && x == evaluation_node->m_domain[1] )
|
||||
{
|
||||
// x should be at the end of the curve's domain
|
||||
// and there shouldn't be any leaves after this one.
|
||||
if ( evaluation_node->NextLeaf() || x != t[span_count] )
|
||||
{
|
||||
ON_ERROR("TestCurveTree() - evaluation used wrong node");
|
||||
}
|
||||
}
|
||||
|
||||
if ( bAdjustParameter )
|
||||
{
|
||||
// Different parameterizations result in derivatives
|
||||
// with different lengths.
|
||||
X[1].Unitize();
|
||||
Y[1].Unitize();
|
||||
}
|
||||
tol0 = ON_ZERO_TOLERANCE + ON_SQRT_EPSILON*Y[0].MaximumCoordinate();
|
||||
tol1 = ON_ZERO_TOLERANCE + ON_SQRT_EPSILON*Y[1].MaximumCoordinate();
|
||||
d0 = (X[0]-Y[0]).Length();
|
||||
d1 = (X[1]-Y[1]).Length();
|
||||
if ( d0 > tol0 || d1 > tol1 )
|
||||
{
|
||||
rc = false;
|
||||
error_count++;
|
||||
if ( d0 > d0err || (d1 > d1err && d0err < 0.01) )
|
||||
{
|
||||
if ( d0 > d0err) d0err = d0;
|
||||
if ( d1 > d1err) d1err = d1;
|
||||
xerr = x;
|
||||
yerr = y;
|
||||
Xerr[0] = X[0];
|
||||
Xerr[1] = X[1];
|
||||
Yerr[0] = Y[0];
|
||||
Yerr[1] = Y[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
text_log.PushIndent();
|
||||
if ( error_count > 0 )
|
||||
{
|
||||
ON_ERROR("TestCurveTree() - tree failed evaluation test.");
|
||||
text_log.Print("Evaluation test at %d points had %d errors.\n",test_count,error_count);
|
||||
text_log.PushIndent();
|
||||
text_log.Print("curve(%g) = (%g,%g,%g)\n",yerr,Y[0].x,Y[0].y,Y[0].z);
|
||||
text_log.Print("tree(%g) = (%g,%g,%g)\n",xerr,X[0].x,X[0].y,X[0].z);
|
||||
text_log.Print("curve D = (%g,%g,%g)\n",Y[1].x,Y[1].y,Y[1].z);
|
||||
text_log.Print("tree D = (%g,%g,%g)\n",X[1].x,X[1].y,X[1].z);
|
||||
text_log.PopIndent();
|
||||
}
|
||||
else
|
||||
{
|
||||
text_log.Print("Evaluation test at %d points was successful.\n",test_count);
|
||||
}
|
||||
text_log.PopIndent();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
bool TestSurfaceTree(ON_TextLog& text_log, const ON_Surface* surface )
|
||||
{
|
||||
if ( !surface )
|
||||
{
|
||||
text_log.Print("Surface pointer is NULL.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const ON_SurfaceTree* tree = surface->SurfaceTree();
|
||||
if ( !tree )
|
||||
{
|
||||
text_log.Print("SurfaceTree() returned NULL.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rc = tree->IsValid( &text_log, surface );
|
||||
if ( !rc )
|
||||
{
|
||||
text_log.Print("Surface tree is not valid.\n");
|
||||
}
|
||||
|
||||
int i;
|
||||
const int span_count0 = surface->SpanCount(0);
|
||||
ON_SimpleArray<double> s(10*(span_count0 + 1));
|
||||
s.SetCount(span_count0+1);
|
||||
surface->GetSpanVector( 0, s.Array() );
|
||||
for ( i = 0; i < span_count0; i++ )
|
||||
{
|
||||
s.Append(0.5*(s[i]+s[i+1]));
|
||||
}
|
||||
|
||||
int j;
|
||||
const int span_count1 = surface->SpanCount(1);
|
||||
ON_SimpleArray<double> t(10*(span_count1 + 1));
|
||||
t.SetCount(span_count1+1);
|
||||
surface->GetSpanVector( 1, t.Array() );
|
||||
for ( j = 0; j < span_count1; j++ )
|
||||
{
|
||||
t.Append(0.5*(t[j]+t[j+1]));
|
||||
}
|
||||
|
||||
const int span_count = span_count0*span_count1;
|
||||
|
||||
ON_SurfaceTreeNode* leaf = tree->FirstLeaf();
|
||||
int leaf_count=0;
|
||||
double maxar = 0.0;
|
||||
double maxr = 0.0;
|
||||
double maxlen = 0.0;
|
||||
double longest = 0.0;
|
||||
double thickest = 0.0;
|
||||
double shortest = fabs(ON_UNSET_VALUE);
|
||||
ON_3dPoint C[4];
|
||||
int notmonocount = 0;
|
||||
while (leaf)
|
||||
{
|
||||
if ( s.Search(leaf->m_domain[0][0]) < 0 )
|
||||
s.Append(leaf->m_domain[0][0]);
|
||||
if ( s.Search(leaf->m_domain[0].ParameterAt(0.3)) < 0 )
|
||||
s.Append(leaf->m_domain[0].ParameterAt(0.3));
|
||||
if ( s.Search(leaf->m_domain[0].ParameterAt(0.8)) < 0 )
|
||||
s.Append(leaf->m_domain[0].ParameterAt(0.8));
|
||||
|
||||
if ( t.Search(leaf->m_domain[1][0]) < 0 )
|
||||
t.Append(leaf->m_domain[1][0]);
|
||||
if ( t.Search(leaf->m_domain[1].ParameterAt(0.2)) < 0 )
|
||||
t.Append(leaf->m_domain[1].ParameterAt(0.2));
|
||||
if ( t.Search(leaf->m_domain[1].ParameterAt(0.7)) < 0 )
|
||||
t.Append(leaf->m_domain[1].ParameterAt(0.7));
|
||||
|
||||
|
||||
if( !leaf->m_bez->m_leafbox.m_bMono )
|
||||
notmonocount++;
|
||||
C[0] = leaf->m_bez->PointAt(0.0,0.0);
|
||||
C[1] = leaf->m_bez->PointAt(1.0,0.0);
|
||||
C[2] = leaf->m_bez->PointAt(1.0,1.0);
|
||||
C[3] = leaf->m_bez->PointAt(0.0,1.0);
|
||||
|
||||
double len = C[3].DistanceTo(C[0]);
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
double x = C[i].DistanceTo(C[i+1]);
|
||||
if ( x > len )
|
||||
len = x;
|
||||
}
|
||||
|
||||
if (len > longest )
|
||||
longest = len;
|
||||
|
||||
if ( len < shortest )
|
||||
shortest = len;
|
||||
|
||||
if ( leaf->m_bez->m_leafbox.Height() > thickest )
|
||||
thickest = leaf->m_bez->m_leafbox.Height();
|
||||
|
||||
if ( leaf->m_bez->m_leafbox.Height() > maxar*len )
|
||||
{
|
||||
maxlen = len;
|
||||
maxr = leaf->m_bez->m_leafbox.Height();
|
||||
maxar = maxr/len;
|
||||
}
|
||||
leaf_count++;
|
||||
leaf = leaf->NextLeaf();
|
||||
}
|
||||
|
||||
if ( notmonocount > 0 )
|
||||
{
|
||||
text_log.Print("ON_SurfaceTree: %d spans, %d leaves (%d are not monotone).\n",span_count,leaf_count,notmonocount);
|
||||
}
|
||||
else
|
||||
{
|
||||
text_log.Print("ON_SurfaceTree: %d spans, %d leaves (all are monotone).\n",span_count,leaf_count);
|
||||
}
|
||||
|
||||
text_log.PushIndent();
|
||||
text_log.Print("Shortest: %g\n",shortest);
|
||||
text_log.Print("Longest: %g\n",longest);
|
||||
text_log.Print("Thickest: height = %g\n",thickest);
|
||||
text_log.Print("Fattest: ht/len = %g (ht = %g, len = %g)\n",maxar,maxr,maxlen);
|
||||
text_log.PopIndent();
|
||||
|
||||
// test evaluation
|
||||
const bool bAdjustParameter = tree->AdjustParameter();
|
||||
ON_2dPoint x,y;
|
||||
double d0, ds, dt, tol0, tol1, tol2;
|
||||
ON_3dVector X[3], Y[3], Xerr[3], Yerr[3];
|
||||
ON_2dVector xerr, yerr;
|
||||
double d0err=0.0, d1err=0.0;
|
||||
int error_count = 0;
|
||||
int test_count = 0;
|
||||
int hint[2] ={0,0};
|
||||
int quadrant = 0;
|
||||
const ON_SurfaceTreeNode* evaluation_node;
|
||||
for ( i = 0; i < s.Count(); i++ )
|
||||
{
|
||||
x.x = y.x = s[i];
|
||||
for ( j = 0; j < t.Count(); j++ )
|
||||
{
|
||||
x.y = y.y = t[j];
|
||||
if (( i > span_count0 || j > span_count1) && bAdjustParameter)
|
||||
{
|
||||
// NOTE - the surface paramter = nurbs form paramter
|
||||
// at all span vector values.
|
||||
surface->GetSurfaceParameterFromNurbFormParameter(s[i],t[j],&y.x,&y.y);
|
||||
}
|
||||
|
||||
for (quadrant = 0; quadrant <= 4; quadrant++ )
|
||||
{
|
||||
test_count++;
|
||||
X[0].x = -99.0;
|
||||
Y[0].x = 99.0;
|
||||
surface->Evaluate(y.x,y.y,1,3,&Y[0].x,quadrant,hint);
|
||||
evaluation_node = tree->Evaluate(x.x,x.y,1,3,&X[0].x,quadrant);
|
||||
if ( !evaluation_node )
|
||||
{
|
||||
error_count++;
|
||||
ON_ERROR("TestSuraceTree() - tree failed to evaluate.");
|
||||
d0err = 1.0e100;
|
||||
d1err = 1.0e100;
|
||||
xerr = x;
|
||||
yerr = y;
|
||||
Xerr[0] = ON_UNSET_POINT;
|
||||
Xerr[1] = ON_UNSET_POINT;
|
||||
Xerr[2] = ON_UNSET_POINT;
|
||||
Yerr[0] = Y[0];
|
||||
Yerr[1] = Y[1];
|
||||
Yerr[2] = Y[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( x.x == evaluation_node->m_domain[0][0] && x.x > s[0] )
|
||||
{
|
||||
if ( 2 == quadrant || 3 == quadrant )
|
||||
{
|
||||
ON_ERROR("TestSuraceTree() ON_SurfaceTreeNode::Evaluate() used the wrong node.");
|
||||
}
|
||||
}
|
||||
else if ( x.x == evaluation_node->m_domain[0][1] && x.x < s[span_count0] )
|
||||
{
|
||||
if ( 1 == quadrant || 4 == quadrant )
|
||||
{
|
||||
ON_ERROR("TestSuraceTree() ON_SurfaceTreeNode::Evaluate() used the wrong node.");
|
||||
}
|
||||
}
|
||||
|
||||
if ( x.y == evaluation_node->m_domain[1][0] && x.y > t[0] )
|
||||
{
|
||||
if ( 3 == quadrant || 4 == quadrant )
|
||||
{
|
||||
ON_ERROR("TestSuraceTree() ON_SurfaceTreeNode::Evaluate() used the wrong node.");
|
||||
}
|
||||
}
|
||||
else if ( x.y == evaluation_node->m_domain[1][1] && x.y < t[span_count1] )
|
||||
{
|
||||
if ( 1 == quadrant || 2 == quadrant )
|
||||
{
|
||||
ON_ERROR("TestSuraceTree() ON_SurfaceTreeNode::Evaluate() used the wrong node.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( bAdjustParameter )
|
||||
{
|
||||
// Different parameterizations result in derivatives
|
||||
// with different lengths.
|
||||
if ( X[1].Length() <= ON_ZERO_TOLERANCE && Y[1].Length() <= ON_ZERO_TOLERANCE )
|
||||
{
|
||||
// singular point
|
||||
// Probably a place where the revolute hits the axis in a surface of revolution
|
||||
X[1].Zero();
|
||||
Y[1].Zero();
|
||||
}
|
||||
else
|
||||
{
|
||||
X[1].Unitize();
|
||||
Y[1].Unitize();
|
||||
}
|
||||
if ( X[2].Length() <= ON_ZERO_TOLERANCE && Y[2].Length() <= ON_ZERO_TOLERANCE )
|
||||
{
|
||||
// singular point
|
||||
// Probably a place where the revolute hits the axis in a surface of revolution.
|
||||
X[2].Zero();
|
||||
Y[2].Zero();
|
||||
}
|
||||
else
|
||||
{
|
||||
X[2].Unitize();
|
||||
Y[2].Unitize();
|
||||
}
|
||||
}
|
||||
tol0 = ON_ZERO_TOLERANCE + ON_SQRT_EPSILON*Y[0].MaximumCoordinate();
|
||||
tol1 = ON_ZERO_TOLERANCE + ON_SQRT_EPSILON*Y[1].MaximumCoordinate();
|
||||
tol2 = ON_ZERO_TOLERANCE + ON_SQRT_EPSILON*Y[2].MaximumCoordinate();
|
||||
d0 = (X[0]-Y[0]).Length();
|
||||
ds = (X[1]-Y[1]).Length();
|
||||
dt = (X[2]-Y[2]).Length();
|
||||
if ( d0 > tol0 || ds > tol1 || dt > tol2 )
|
||||
{
|
||||
rc = false;
|
||||
error_count++;
|
||||
if ( d0 > d0err || (ds > d1err && d0err < 0.01) || (dt > d1err && d0err < 0.01) )
|
||||
{
|
||||
if ( d0 > d0err) d0err = d0;
|
||||
if ( ds > d1err) d1err = ds;
|
||||
if ( dt > d1err) d1err = dt;
|
||||
xerr = x;
|
||||
yerr = y;
|
||||
Xerr[0] = X[0];
|
||||
Xerr[1] = X[1];
|
||||
Xerr[2] = X[2];
|
||||
Yerr[0] = Y[0];
|
||||
Yerr[1] = Y[1];
|
||||
Yerr[2] = Y[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text_log.PushIndent();
|
||||
if ( error_count > 0 )
|
||||
{
|
||||
ON_ERROR("TestSurfaceTree() - tree failed evaluation test.");
|
||||
text_log.Print("Evaluation test at %d points had %d errors.\n",test_count,error_count);
|
||||
text_log.PushIndent();
|
||||
text_log.Print("surface(%g,%g) = (%g,%g,%g)\n",yerr.x,yerr.y,Y[0].x,Y[0].y,Y[0].z);
|
||||
text_log.Print("tree(%g,%g) = (%g,%g,%g)\n",xerr.x,xerr.y,X[0].x,X[0].y,X[0].z);
|
||||
text_log.Print("curve Ds = (%g,%g,%g)\n",Y[1].x,Y[1].y,Y[1].z);
|
||||
text_log.Print("tree Ds = (%g,%g,%g)\n",X[1].x,X[1].y,X[1].z);
|
||||
text_log.Print("curve Dt = (%g,%g,%g)\n",Y[2].x,Y[2].y,Y[2].z);
|
||||
text_log.Print("tree Dt = (%g,%g,%g)\n",X[2].x,X[2].y,X[2].z);
|
||||
text_log.PopIndent();
|
||||
}
|
||||
else
|
||||
{
|
||||
text_log.Print("Evaluation test at %d points was successful.\n",test_count);
|
||||
}
|
||||
text_log.PopIndent();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static
|
||||
void TestCurveTreeHelper( ON_TextLog& text_log, const ON_Curve* curve, const wchar_t* name )
|
||||
{
|
||||
TL_NurbsCurve nurbs_curve;
|
||||
|
||||
if ( curve )
|
||||
{
|
||||
if ( 0 == name || 0 == *name)
|
||||
{
|
||||
name = L"anonymous";
|
||||
}
|
||||
|
||||
curve->GetNurbForm(nurbs_curve);
|
||||
|
||||
text_log.Print(L"Curve class = %S, name = %s\n",
|
||||
curve->ClassId()->ClassName(),
|
||||
name
|
||||
);
|
||||
text_log.PushIndent();
|
||||
text_log.Print(L"degree = %d, %s, CV count=%d\n",
|
||||
nurbs_curve.m_order-1,
|
||||
(nurbs_curve.m_is_rat ? L"rational" : L"non-rational"),
|
||||
nurbs_curve.m_cv_count
|
||||
);
|
||||
TestCurveTree( text_log, curve );
|
||||
text_log.PopIndent();
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void TestSurfaceTreeHelper( ON_TextLog& text_log, const ON_Surface* surface, const wchar_t* name )
|
||||
{
|
||||
TL_NurbsSurface nurbs_surface;
|
||||
|
||||
if ( surface )
|
||||
{
|
||||
if ( 0 == name || 0 == *name)
|
||||
{
|
||||
name = L"anonymous";
|
||||
}
|
||||
surface->GetNurbForm(nurbs_surface);
|
||||
|
||||
text_log.Print(L"Surface class = %S, name = %s\n",
|
||||
surface->ClassId()->ClassName(),
|
||||
name
|
||||
);
|
||||
text_log.PushIndent();
|
||||
text_log.Print(L"degree = (%d,%d), %s, CV count= (%d,%d)\n",
|
||||
nurbs_surface.m_order[0]-1,
|
||||
nurbs_surface.m_order[1]-1,
|
||||
(nurbs_surface.m_is_rat ? L"rational" : L"non-rational"),
|
||||
nurbs_surface.m_cv_count[0],
|
||||
nurbs_surface.m_cv_count[1]
|
||||
);
|
||||
TestSurfaceTree( text_log, surface );
|
||||
text_log.PopIndent();
|
||||
}
|
||||
}
|
||||
|
||||
void TestTree( const ONX_Model& model, ON_TextLog& text_log )
|
||||
{
|
||||
TEST_HEADER(text_log,"TestClosestPoint");
|
||||
int i, k;
|
||||
|
||||
ON_wString name;
|
||||
const wchar_t* attributes_name;
|
||||
|
||||
// first do curves
|
||||
if (bDoCurves)
|
||||
{
|
||||
for ( i = 0; i < model.m_object_table.Count(); i++ )
|
||||
{
|
||||
const ON_Curve* curve = ON_Curve::Cast(model.m_object_table[i].m_object);
|
||||
if ( curve )
|
||||
{
|
||||
attributes_name = model.m_object_table[i].m_attributes.m_name;
|
||||
TestCurveTreeHelper(text_log,curve,attributes_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const ON_Brep* brep = ON_Brep::Cast(model.m_object_table[i].m_object);
|
||||
if ( brep )
|
||||
{
|
||||
for ( k = 0; k < brep->m_C3.Count(); k++ )
|
||||
{
|
||||
curve = brep->m_C3[k];
|
||||
if ( curve )
|
||||
{
|
||||
attributes_name = model.m_object_table[i].m_attributes.m_name;
|
||||
if ( !attributes_name )
|
||||
attributes_name = L"anonymous";
|
||||
name.Format(L"%s - brep.m_C3[%d]",attributes_name,k);
|
||||
TestCurveTreeHelper(text_log,curve,name);
|
||||
}
|
||||
}
|
||||
|
||||
for ( k = 0; k < brep->m_C2.Count(); k++ )
|
||||
{
|
||||
curve = brep->m_C2[k];
|
||||
if ( curve )
|
||||
{
|
||||
attributes_name = model.m_object_table[i].m_attributes.m_name;
|
||||
if ( !attributes_name )
|
||||
attributes_name = L"anonymous";
|
||||
name.Format(L"%s - brep.m_C2[%d]",attributes_name,k);
|
||||
TestCurveTreeHelper(text_log,curve,name);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// then do surfaces
|
||||
if ( bDoSurfaces )
|
||||
{
|
||||
for ( i = 0; i < model.m_object_table.Count(); i++ )
|
||||
{
|
||||
const ON_Surface* surface = ON_Surface::Cast(model.m_object_table[i].m_object);
|
||||
if ( surface )
|
||||
{
|
||||
attributes_name = model.m_object_table[i].m_attributes.m_name;
|
||||
TestSurfaceTreeHelper(text_log,surface,attributes_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
const ON_Brep* brep = ON_Brep::Cast(model.m_object_table[i].m_object);
|
||||
if ( brep )
|
||||
{
|
||||
for ( k = 0; k < brep->m_S.Count(); k++ )
|
||||
{
|
||||
surface = brep->m_S[k];
|
||||
if ( surface )
|
||||
{
|
||||
attributes_name = model.m_object_table[i].m_attributes.m_name;
|
||||
if ( !attributes_name )
|
||||
attributes_name = L"anonymous";
|
||||
name.Format(L"%s - brep.m_S[%d]",attributes_name,k);
|
||||
|
||||
TestSurfaceTreeHelper(text_log,surface,model.m_object_table[i].m_attributes.m_name);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
/* $Header: /src4/opennurbs/Tests/TestZLib.cpp 3 2/24/06 9:46p Dalelear $ */
|
||||
/* $NoKeywords: $ */
|
||||
|
||||
#include "Tests.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
static
|
||||
bool TestZLibCompressionHelper2(
|
||||
const wchar_t* filename,
|
||||
__int64 filesize,
|
||||
ON_TextLog& text_log
|
||||
)
|
||||
{
|
||||
ON_Workspace ws;
|
||||
|
||||
if ( 0 == filename )
|
||||
return false;
|
||||
|
||||
if ( filesize > 0xFFFFFFF0 )
|
||||
{
|
||||
text_log.Print("Huge file - cannot compress this\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Allocate inbuffer[] and read filename into inbuffer[]
|
||||
//
|
||||
const size_t insz = (size_t)filesize;
|
||||
void* inbuffer = ws.GetMemory( insz );
|
||||
|
||||
if ( 0 == inbuffer )
|
||||
{
|
||||
text_log.Print("onmalloc( %u ) returned NULL\n",insz);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* fp = _wfopen(filename,L"rb");
|
||||
if ( !fp )
|
||||
{
|
||||
ON_ERROR("Unable to read file\n");
|
||||
text_log.Print(L"ERROR: wfopen(%s,L\"rb\") failed\n",filename);
|
||||
return false;
|
||||
}
|
||||
size_t freadsz = fread(inbuffer,1,insz,fp);
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
if ( freadsz != insz )
|
||||
{
|
||||
text_log.Print(L"ERROR: fread(inbuffer,1,%u,%s) = %u\n",insz,filename,freadsz);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Compress inbuffer[] and save compressed informtion in zlibtest.tmp
|
||||
//
|
||||
const wchar_t* tempfile = L"C:\\Temp\\zlibtest.tmp";
|
||||
|
||||
fp = ON::OpenFile(tempfile,L"wb");
|
||||
if ( !fp )
|
||||
{
|
||||
ON_ERROR("Unable to write temp file\n");
|
||||
text_log.Print(L"ERROR: ON::OpenFile(%s,L\"wb\") failed\n",tempfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bWriteOk = false;
|
||||
{
|
||||
ON_BinaryFile file( ON::write, fp );
|
||||
bWriteOk = file.WriteCompressedBuffer( insz, inbuffer );
|
||||
}
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
if ( !bWriteOk )
|
||||
{
|
||||
text_log.Print(L"ERROR: WriteCompressedBuffer(%u,...) failed\n",insz);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Read zlibtest.tmp uncompress its contents into outbuffer[]
|
||||
//
|
||||
size_t outsz = 0;
|
||||
void* outbuffer = 0;
|
||||
|
||||
fp = ON::OpenFile(tempfile,L"rb");
|
||||
if ( !fp )
|
||||
{
|
||||
ON_ERROR("Unable to read temp file\n");
|
||||
text_log.Print(L"ERROR: ON::OpenFile(%s,L\"rb\") failed\n",tempfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
int bFailedCRC = true;
|
||||
bool bReadOk = false;
|
||||
{
|
||||
ON_BinaryFile file( ON::read, fp );
|
||||
bReadOk = file.ReadCompressedBufferSize( &outsz );
|
||||
if (bReadOk && outsz == insz)
|
||||
{
|
||||
outbuffer = ws.GetMemory(outsz);
|
||||
if ( 0 == outbuffer )
|
||||
{
|
||||
text_log.Print("onmalloc( %u ) returned NULL\n",outsz);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bReadOk = file.ReadCompressedBuffer( outsz, outbuffer, &bFailedCRC );
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
if ( !bReadOk )
|
||||
{
|
||||
text_log.Print(L"ERROR: ReadCompressedBuffer(%u,...) failed\n",outsz);
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Compare inbuffer[] and outbuffer[]
|
||||
//
|
||||
if ( insz != outsz || memcmp(inbuffer,outbuffer,insz) || bFailedCRC )
|
||||
{
|
||||
ON_ERROR("TestZLibCompressionHelper2 compression failure");
|
||||
text_log.Print("ERROR: %s compression failure\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void TestZLibCompressionHelper1(
|
||||
const wchar_t* filespec,
|
||||
ON_TextLog& text_log,
|
||||
int& file_counter,
|
||||
int recursion_counter
|
||||
)
|
||||
{
|
||||
const int max_file_count = 0x7FFFFFF0;
|
||||
if ( file_counter > max_file_count )
|
||||
return;
|
||||
|
||||
if ( recursion_counter > 32 )
|
||||
{
|
||||
ON_ERROR("TestZLibCompressionHelper1 recursion_counter > 32");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 0 == recursion_counter && (0 == filespec || 0 == filespec[0]) )
|
||||
{
|
||||
filespec = L"C:\\Documents and Settings\\dalelear\\My Documents";
|
||||
}
|
||||
|
||||
bool bRecurse = false;
|
||||
struct __stat64 fs;
|
||||
|
||||
ON_wString wildcard = filespec;
|
||||
ON_wString path;
|
||||
if ( 0 == recursion_counter )
|
||||
{
|
||||
wildcard.TrimRight(L"/\\");
|
||||
}
|
||||
if ( !wildcard.IsEmpty() )
|
||||
{
|
||||
memset(&fs,0,sizeof(fs));
|
||||
if ( 0 == _wstat64( wildcard, &fs ) )
|
||||
{
|
||||
if ( 0 != (_S_IFDIR & fs.st_mode) )
|
||||
{
|
||||
bRecurse = true;
|
||||
path = wildcard;
|
||||
path += '\\';
|
||||
wildcard = path;
|
||||
wildcard += '*';
|
||||
filespec = wildcard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct _wfinddata64_t fi;
|
||||
memset(&fi,0,sizeof(fi));
|
||||
INT_PTR h = _wfindfirst64( filespec, &fi );
|
||||
if ( -1 == h )
|
||||
{
|
||||
text_log.Print(L"ERROR: Compression test found nothing in %s\n",filespec);
|
||||
return;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
while ( 0 == rc && file_counter < max_file_count )
|
||||
{
|
||||
if ( 0 != fi.name[0]
|
||||
&& (fi.name[0] != '.' || (0 != fi.name[1] && wcscmp(fi.name,L"..")))
|
||||
)
|
||||
{
|
||||
// fi.name is not empty and is not "." or ".."
|
||||
ON_wString fullpath = path;
|
||||
fullpath += fi.name;
|
||||
memset(&fs,0,sizeof(fs));
|
||||
if ( 0 == _wstat64( fullpath, &fs ) )
|
||||
{
|
||||
bool bIsDir = (0 != (_S_IFDIR & fs.st_mode));
|
||||
bool bIsFile = (false == bIsDir && (0 != (_S_IFREG & fs.st_mode)));
|
||||
if ( bIsDir && bRecurse )
|
||||
{
|
||||
// recurse through subdirectory
|
||||
TestZLibCompressionHelper1(fullpath,text_log,file_counter,recursion_counter+1);
|
||||
}
|
||||
else if ( bIsFile && fs.st_size > 0)
|
||||
{
|
||||
// use file for a compression test
|
||||
if ( !TestZLibCompressionHelper2(fullpath,fs.st_size,text_log) )
|
||||
{
|
||||
text_log.Print(L"ERROR: %s compression test failed\n",fullpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
file_counter++;
|
||||
if ( 0 == (file_counter % 1000) )
|
||||
{
|
||||
text_log.Print(L"%6d files tested\n",file_counter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rc = _wfindnext64( h, &fi );
|
||||
}
|
||||
|
||||
_findclose(h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TestZLibCompression(
|
||||
const wchar_t* filespec,
|
||||
ON_TextLog& text_log
|
||||
)
|
||||
{
|
||||
int file_counter = 0;
|
||||
TestZLibCompressionHelper1(filespec,text_log,file_counter,0);
|
||||
}
|
||||
|
||||
1090
tests/Tests.cpp
1090
tests/Tests.cpp
File diff suppressed because it is too large
Load Diff
257
tests/Tests.h
257
tests/Tests.h
@@ -1,257 +0,0 @@
|
||||
#pragma once
|
||||
#if !defined(OPENNURBS_TESTS_INC_)
|
||||
|
||||
#if !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
// Visual Studio 2005 issues a C4996 warning for lots of
|
||||
// standard C runtime functions that take string pointers.
|
||||
// The _CRT_SECURE_NO_DEPRECATE suppresses these warnings.
|
||||
#endif
|
||||
|
||||
#pragma warning( push )
|
||||
#include "../opennurbs.h"
|
||||
#pragma warning( pop )
|
||||
|
||||
#pragma warning( push )
|
||||
//#include <signal.h>
|
||||
//#include <time.h>
|
||||
#pragma warning( pop )
|
||||
|
||||
#pragma warning( push )
|
||||
#include "../../tl/tl.h"
|
||||
#include "../../tl/tl_array.h"
|
||||
#include "../../tl/tl_gslib.h"
|
||||
#include "../../tl/tl_init.h"
|
||||
#include "../../tl/tl_brep.h"
|
||||
#include "../../tl/tl_nurbscurve.h"
|
||||
#include "../../tl/tl_nurbssurface.h"
|
||||
#include "../../tl/tl_tree.h"
|
||||
#include "../../tl/tl_optimize.h"
|
||||
|
||||
#pragma warning( pop )
|
||||
|
||||
|
||||
#define TL_GSLIB_INTERFACE_CODE
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4267 )
|
||||
#pragma warning( disable : 4313 )
|
||||
#include "../../tl/tl_gslib_inc.h"
|
||||
#pragma warning( pop )
|
||||
#undef TL_GSLIB_INTERFACE_CODE
|
||||
|
||||
|
||||
#if defined(_DEBUG)
|
||||
|
||||
#pragma comment(lib, "../../tl/DebugStaticLib/tl_staticlibd.lib")
|
||||
#pragma comment(lib, "../../gslib/DebugStaticLib/gslib_staticlibd.lib")
|
||||
#pragma comment(lib, "../DebugStaticLib/opennurbs_staticd.lib")
|
||||
#pragma comment(lib, "../zlib/Debug/zlib_d.lib")
|
||||
#pragma comment(lib, "msvcrtd.lib")
|
||||
|
||||
#pragma comment(linker, "/disallowlib:msvcrt.lib")
|
||||
|
||||
#else
|
||||
|
||||
#pragma comment(lib, "../../tl/ReleaseStaticLib/tl_staticlib.lib")
|
||||
#pragma comment(lib, "../../gslib/ReleaseStaticLib/gslib_staticlib.lib")
|
||||
#pragma comment(lib, "../ReleaseStaticLib/opennurbs_static.lib")
|
||||
#pragma comment(lib, "../zlib/Release/zlib.lib")
|
||||
#pragma comment(lib, "msvcrt.lib")
|
||||
|
||||
#pragma comment(linker, "/disallowlib:msvcrtd.lib")
|
||||
|
||||
#endif
|
||||
|
||||
#pragma comment(linker, "/disallowlib:libcd.lib")
|
||||
#pragma comment(linker, "/disallowlib:libcmtd.lib")
|
||||
#pragma comment(linker, "/disallowlib:libc.lib")
|
||||
#pragma comment(linker, "/disallowlib:libcmt.lib")
|
||||
|
||||
#pragma comment(linker, "/disallowlib:mfco42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcd42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcn42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42u.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42u.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfco42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcd42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcn42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42u.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42u.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfco42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcd42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcn42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42u.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42u.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfco42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcd42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcn42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42d.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfc42ud.lib")
|
||||
#pragma comment(linker, "/disallowlib:mfcs42ud.lib")
|
||||
|
||||
#pragma comment(linker, "/disallowlib:nafxcwd.lib")
|
||||
#pragma comment(linker, "/disallowlib:nafxcw.lib")
|
||||
#pragma comment(linker, "/disallowlib:uafxcwd.lib")
|
||||
#pragma comment(linker, "/disallowlib:uafxcw.lib")
|
||||
|
||||
// Prohibit any future inclusion of CRTDBG.H by defining _INC_CRTDBG.
|
||||
#if defined(_INC_CRTDBG)
|
||||
#error Never include CRTDBG.H in these tests. It breaks purify.
|
||||
#endif
|
||||
#define _INC_CRTDBG
|
||||
|
||||
|
||||
class CTestObject
|
||||
{
|
||||
public:
|
||||
CTestObject();
|
||||
~CTestObject();
|
||||
|
||||
void Destroy();
|
||||
|
||||
int m_model_object_index; // ONX_Model m_object_table[] index
|
||||
ON_UUID m_uuid; // 3dm parent object uuid
|
||||
ON_wString m_name; // 3dm parent object name
|
||||
ON_COMPONENT_INDEX m_ci; // index of object in parent
|
||||
};
|
||||
|
||||
class CTestCurve : public CTestObject
|
||||
{
|
||||
public:
|
||||
CTestCurve();
|
||||
~CTestCurve();
|
||||
|
||||
void Destroy();
|
||||
|
||||
const ON_Curve* m_curve;
|
||||
|
||||
// True if curve and NURBS parameterizations differ
|
||||
bool m_bAdjustNurbsParameter;
|
||||
|
||||
const TL_NurbsCurve& NurbsCurve();
|
||||
|
||||
const class IwBSplineCurve* GooseCurve();
|
||||
|
||||
|
||||
TL_NurbsCurve m_nurbs_curve;
|
||||
TL_NURB m_nurbcrv;
|
||||
|
||||
class IwBSplineCurve* m_goose_curve;
|
||||
};
|
||||
|
||||
class CTestSurface : public CTestObject
|
||||
{
|
||||
public:
|
||||
CTestSurface();
|
||||
~CTestSurface();
|
||||
|
||||
void Destroy();
|
||||
|
||||
const ON_Surface* m_surface;
|
||||
|
||||
// True if surface and NURBS parameterizations differ
|
||||
bool m_bAdjustNurbsParameter;
|
||||
|
||||
const TL_NurbsSurface& NurbsSurface();
|
||||
|
||||
const class IwBSplineSurface* GooseSurface();
|
||||
|
||||
|
||||
// call NurbsSurface() to get this surface
|
||||
TL_NurbsSurface m_nurbs_surface;
|
||||
TL_NURBSRF m_nurbsrf;
|
||||
|
||||
// call GooseSurface() to get this surface
|
||||
class IwBSplineSurface* m_goose_surface;
|
||||
};
|
||||
|
||||
class CTestBrep : public CTestObject
|
||||
{
|
||||
public:
|
||||
CTestBrep();
|
||||
~CTestBrep();
|
||||
|
||||
const TL_Brep* m_brep;
|
||||
};
|
||||
|
||||
class CTestModel : public ONX_Model
|
||||
{
|
||||
public:
|
||||
CTestModel();
|
||||
|
||||
// Digs through the model and harvests curves, surfaces,
|
||||
// and breps for testing and puts them in the m_curves[],
|
||||
// m_surfaces[], m_breps[] arrays.
|
||||
void GetTestObjects( bool bEdgesAreCurve, bool bTrimsAreCurves );
|
||||
|
||||
ON_ClassArray<CTestCurve> m_curves;
|
||||
ON_ClassArray<CTestSurface> m_surfaces;
|
||||
ON_ClassArray<CTestBrep> m_breps;
|
||||
|
||||
bool m_bPurify; // true if tests should be limited because purify is running.
|
||||
};
|
||||
|
||||
|
||||
double TEST_ElapsedTime();
|
||||
//#define ON_TEST_DECL(func) ON_TEST_BeginTest(test_results,#func); test_results->ok = func(*test_results->m_text_log); ON_TEST_EndTest(test_results);
|
||||
|
||||
#define TEST_HEADER(text_log,function_name) TestPrintFunctionHeader( text_log, function_name, __FILE__, __DATE__ " " __TIME__ );
|
||||
|
||||
void TestPrintHeader(
|
||||
ON_TextLog& text_log,
|
||||
int argc,
|
||||
const char* argv[]
|
||||
);
|
||||
|
||||
void TestPrintFunctionHeader(
|
||||
ON_TextLog& text_log,
|
||||
const char* function_name,
|
||||
const char* file_name,
|
||||
const char* compile_time
|
||||
);
|
||||
|
||||
void TestTree( const ONX_Model& model, ON_TextLog& text_log );
|
||||
void TestClosestPoint( const ONX_Model& model,
|
||||
ON_TextLog& text_log,
|
||||
bool bDoCurves,
|
||||
bool bDoSurfaces,
|
||||
bool bDoMeshes );
|
||||
void TestCurveCurveIntersection(const ONX_Model& model, ON_TextLog& text_log );
|
||||
void TestCurveSurfaceIntersection( CTestModel& model, ON_TextLog& text_log );
|
||||
void TestZLibCompression(
|
||||
const wchar_t* filespec,
|
||||
ON_TextLog& text_log
|
||||
);
|
||||
|
||||
|
||||
// quick-n-dirty ccx for testing curve tree
|
||||
void DaleCCX( const ON_Curve& curveA,
|
||||
const ON_Curve& curveB,
|
||||
double tol3d,
|
||||
ON_SimpleArray<TL_CX_EVENT>& ccx
|
||||
);
|
||||
|
||||
|
||||
// new FAST! ccx
|
||||
void GregCCX( const ON_Curve& curveA,
|
||||
const ON_Curve& curveB,
|
||||
double tol3d,
|
||||
ON_SimpleArray<TL_CX_EVENT>& ccx
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -1,249 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Tests"
|
||||
ProjectGUID="{E42570C0-4CFB-4FA1-85D5-7EC3BAAF65CA}"
|
||||
RootNamespace="Tests"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\gslib\inc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Tests.h"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="Rpcrt4.lib"
|
||||
OutputFile="$(OutDir)/Tests.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/Tests.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\gslib\inc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Tests.h"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Rpcrt4.lib"
|
||||
OutputFile="$(OutDir)/Tests.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\TestClosestPoint.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\TestCurveCurveIntersection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\TestCurveSurfaceIntersection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\TestPrecompiledHeader.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
PrecompiledHeaderThrough="Tests.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
PrecompiledHeaderThrough="Tests.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Tests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\TestTree.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\TestZLib.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Tests.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user