Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 111 additions & 40 deletions example_test/example_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ static const ONX_ErrorCounter Internal_TestModelRead(

ONX_ErrorCounter error_counter = test.ErrorCounter();

const ONX_Model* source_model = test.SourceModel().get();
std::shared_ptr<ONX_Model> source_model_sp = test.SourceModel();
const ONX_Model* source_model = source_model_sp.get();
if (nullptr == source_model)
{
text_log.PopIndent();
Expand All @@ -156,18 +157,46 @@ static const ONX_ErrorCounter Internal_TestModelRead(

const bool bCompareTestFailed = ONX_ModelTest::Result::Fail == test.TestResult(ONX_ModelTest::Type::ReadWriteReadCompare);

if ( bVerbose || bCompareTestFailed )
if (bCompareTestFailed)
{
for (int i = 0; i < 2; i++)
// Dump the text used to generate the hashes that were different
// into 2 text files so a human can look at the diffs and decide
// what to do.

ON_wString source_model_hash_log_filename;
ON_SHA1_Hash source_model_hash;
ON_wString copy_model_hash_log_filename;
ON_SHA1_Hash copy_model_hash;
const bool bDumpedHashLogs = test.DumpHashLogs(
source_model_hash_log_filename,
source_model_hash,
copy_model_hash_log_filename,
copy_model_hash
);
if (bDumpedHashLogs)
{
if (0 == i)
test.DumpSourceModel();
else
test.DumpReadWriteReadModel();
if (false == bCompareTestFailed)
break;
bVerbose = false;
text_log.PushIndent();
text_log.PushIndent();
text_log.Print(L"Compare these hash logs to see what changed in the temporary file.\n");
text_log.PushIndent();
text_log.Print(L"Source model hash log:\n");
text_log.PushIndent();
text_log.Print(L"\"%ls\"\n", static_cast<const wchar_t*>(source_model_hash_log_filename));
text_log.PopIndent();
text_log.Print(L"Read-Write-Read model hash log:\n", static_cast<const wchar_t*>(copy_model_hash_log_filename));
text_log.PushIndent();
text_log.Print(L"\"%ls\"\n", static_cast<const wchar_t*>(copy_model_hash_log_filename));
text_log.PopIndent();
text_log.PopIndent();
text_log.PopIndent();
text_log.PopIndent();
}
}
else if ( bVerbose )
{
test.DumpSourceModel();
}

text_log.PrintNewLine();

Expand Down Expand Up @@ -404,14 +433,14 @@ static const ONX_ErrorCounter Internal_TestReadFolder(

if (nullptr == directory_path || 0 == directory_path[0])
{
text_log.Print("Empty directory name.\n");
text_log.Print("Empty folder name.\n");
}

ON_FileIterator fit;
if (false == fit.Initialize(directory_path))
{
text_log.Print(
"Invalid directory name: %s\n",
"Invalid folder name: %s\n",
directory_path
);
error_counter.IncrementFailureCount();
Expand All @@ -423,7 +452,7 @@ static const ONX_ErrorCounter Internal_TestReadFolder(
? ON_String(directory_path)
: test_context.TextLogPathFromFullPath(directory_path);
text_log.Print(
"Directory name: %s\n",
"Folder name: %s\n",
static_cast<const char*>(text_log_directory_name)
);
text_log.PushIndent();
Expand Down Expand Up @@ -523,7 +552,7 @@ static ONX_ErrorCounter Internal_Test(
{
if (ON_FileStream::Is3dmFile(full_path, false))
{
text_log.Print("Testing 3dm file: %s\n", static_cast<const char*>(full_path));
text_log.PrintNewLine(); // ("Testing 3dm file: %s\n", static_cast<const char*>(full_path));
err = Internal_TestFileRead(text_log, full_path, ON_String::EmptyString, bVerbose);
file_count++;
}
Expand All @@ -533,6 +562,7 @@ static ONX_ErrorCounter Internal_Test(
if ( max_directory_tree_depth > 0 )
{
text_log.Print("Testing 3dm files in folder: %s\n", static_cast<const char*>(full_path));
text_log.PrintNewLine();
Internal_CTestContext test_context;
directory_counter++;
test_context.SetInitialDirecory(full_path,directory_counter);
Expand Down Expand Up @@ -599,16 +629,27 @@ static ON_String Internal_DefaultOutFileName(
const ON_String exe_stem
)
{
ON_String default_file_name(exe_stem);
default_file_name.TrimLeftAndRight();
if (default_file_name.IsEmpty())
default_file_name = "example_test";
default_file_name += "_log";
const ON_String vN = ON_String::FormatToString("v%u", ON::VersionMajor());

ON_String file_name(exe_stem);
file_name.TrimLeftAndRight();
if (file_name.IsEmpty())
file_name = "example_test";
file_name += "_log";

const ON_String platform_id = Internal_PlatformId(false);
if (platform_id.IsNotEmpty())
default_file_name += ON_String(ON_String("_") + platform_id);
default_file_name += ".txt";
ON_String default_file_name = vN + file_name + ON_String(".txt");

const ON_wString desktop_folder = ON_FileSystemPath::PlatformPath(ON_FileSystemPath::PathId::DesktopDirectory);
if (desktop_folder.IsNotEmpty() && ON_FileSystem::IsDirectory(static_cast<const wchar_t*>(desktop_folder)))
{
const ON_wString wdefault_file_name(default_file_name);
const ON_wString desktop_default_file_name = ON_FileSystemPath::CombinePaths(
static_cast<const wchar_t*>(desktop_folder), false,
static_cast<const wchar_t*>(wdefault_file_name), true,
false);
if (desktop_default_file_name.IsNotEmpty())
default_file_name = ON_String(desktop_default_file_name);
}

return default_file_name;
}
Expand Down Expand Up @@ -829,24 +870,23 @@ static bool Internal_ParseArg_RECURSE(const ON_String arg, unsigned int& N)
}


static const ON_String Internal_ParseArg_PATH(const ON_String arg, unsigned int max_directory_tree_depth)
static const ON_String Internal_ParseArg_PATH(const ON_String arg, bool& bArgIsDirectory)
{
bArgIsDirectory = false;
ON_String arg_full_path = ON_FileSystemPath::ExpandUser(static_cast<const char*>(arg));
arg_full_path.TrimLeftAndRight();

if (ON_FileSystem::IsFile(arg_full_path))
return arg_full_path;

if (max_directory_tree_depth > 0)
if (arg_full_path.Length() != 1 || false == ON_FileSystemPath::IsDirectorySeparator(arg_full_path[0], true))
{
if (arg_full_path.Length() != 1 || false == ON_FileSystemPath::IsDirectorySeparator(arg_full_path[0], true))
{
const char dir_seps[3] = { ON_FileSystemPath::DirectorySeparatorAsChar, ON_FileSystemPath::AlternateDirectorySeparatorAsChar, 0 };
arg_full_path.TrimRight(dir_seps);
}
if (ON_FileSystem::IsDirectory(arg_full_path))
return arg_full_path;
const char dir_seps[3] = { ON_FileSystemPath::DirectorySeparatorAsChar, ON_FileSystemPath::AlternateDirectorySeparatorAsChar, 0 };
arg_full_path.TrimRight(dir_seps);
}
bArgIsDirectory = ON_FileSystem::IsDirectory(arg_full_path);
if (bArgIsDirectory)
return arg_full_path;

return ON_String::EmptyString;
}
Expand Down Expand Up @@ -922,10 +962,11 @@ int main( int argc, const char *argv[] )
unsigned int directory_arg_counter = 0;

bool bPrintIntroduction = true;
ON_String current_output_filename = ON_String::EmptyString;

for ( argi = 1; argi < argc; argi++ )
{
arg = argv[argi];
arg = (nullptr != argv) ? argv[argi] : ((const char*)nullptr);
arg.TrimLeftAndRight();
if (arg.IsEmpty())
continue;
Expand All @@ -952,14 +993,21 @@ int main( int argc, const char *argv[] )
}
if ( text_log_fp )
{
if (current_output_filename.IsNotEmpty())
{
print_to_stdout.Print("Results saved in %s\n", static_cast<const char*>(current_output_filename));
}
ON::CloseFile(text_log_fp);
text_log_fp = nullptr;
current_output_filename = ON_String::EmptyString;
}

text_log = &print_to_stdout;

if (output_file_name.IsEmpty() || output_file_name.EqualOrdinal("stdout", true))
{
continue;
}

if (output_file_name.EqualOrdinal("null", true) || output_file_name.EqualOrdinal("dev/null", true))
{
Expand All @@ -978,6 +1026,11 @@ int main( int argc, const char *argv[] )
text_log = new ON_TextLog(text_log_fp);
text_log->SetIndentSize(2);

current_output_filename = output_file_name;
if (current_output_filename.IsNotEmpty())
{
print_to_stdout.Print("Results will be saved in %s\n", static_cast<const char*>(current_output_filename));
}
continue;
}

Expand All @@ -999,15 +1052,33 @@ int main( int argc, const char *argv[] )
Internal_PrintIntroduction(example_test_exe_path, *text_log);
}

const ON_String arg_full_path = Internal_ParseArg_PATH(arg,maximum_directory_depth);
bool bArgIsDirectory = false;
const ON_String arg_full_path = Internal_ParseArg_PATH(arg, bArgIsDirectory);
if (arg_full_path.IsEmpty())
{
err += Internal_InvalidArg(arg, *text_log);
break;
}

const unsigned directory_recursion_depth = ((0 == maximum_directory_depth && bArgIsDirectory) ? 1 : maximum_directory_depth);

if (current_output_filename.IsNotEmpty())
{
if (bArgIsDirectory)
{
if (directory_recursion_depth > 1)
print_to_stdout.Print("Testing folder tree %s ...\n", static_cast<const char*>(arg_full_path));
else
print_to_stdout.Print("Testing folder %s ...\n", static_cast<const char*>(arg_full_path));
}
else
{
print_to_stdout.Print("Testing file %s ...\n", static_cast<const char*>(arg_full_path));
}
}

err += Internal_Test(
maximum_directory_depth,
directory_recursion_depth,
arg_full_path,
bVerbose,
*text_log,
Expand Down Expand Up @@ -1043,7 +1114,7 @@ int main( int argc, const char *argv[] )
text_log->Print(" Failures. ");
else if (err.ErrorCount() > 0) {
text_log->Print(" Errors:\n");
for (int vbli = 0; vbli < verbose_log.Count(); vbli++) {
for (unsigned vbli = 0; vbli < verbose_log.Count(); vbli++) {
text_log->Print(" !! ");
text_log->Print(verbose_log.Event(vbli).Description());
text_log->Print("\n");
Expand All @@ -1056,18 +1127,18 @@ int main( int argc, const char *argv[] )
err.Dump(*text_log);
text_log->PrintNewLine();

if ( text_log != &print_to_stdout && text_log != &ON_TextLog::Null )
{
delete text_log;
}

text_log = nullptr;

if ( text_log_fp )
{
if (current_output_filename.IsNotEmpty())
{
print_to_stdout.Print("Results saved in %s\n", static_cast<const char*>(current_output_filename));
}
// close the text text_log file
ON::CloseFile( text_log_fp );
text_log_fp = 0;
current_output_filename = ON_String::EmptyString;
}

// OPTIONAL: Call just before your application exits to clean
Expand Down
41 changes: 38 additions & 3 deletions opennurbs_3dm_attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs
#endif

// TODO: This really needs to be a member of ON_3dmObjectAttributes but that would break the SDK.
std::recursive_mutex g_mutex;

class ON_3dmObjectAttributesPrivate
{
public:
Expand Down Expand Up @@ -1076,6 +1079,7 @@ bool ON_3dmObjectAttributes::Internal_WriteV5( ON_BinaryArchive& file ) const
// not actually needed when running Rhino because the RDK decal UI directly updates
// the user data when changes are made. This is only needed when using ONX_Model and
// File3dm outside of Rhino, in case the programmer sets a decal property.
std::lock_guard<std::recursive_mutex> lg(g_mutex);
const unsigned int archive_3dm_version = file.Archive3dmVersion();
m_private->m_decals.UpdateUserData(archive_3dm_version);
}
Expand Down Expand Up @@ -2519,22 +2523,49 @@ void ON_3dmObjectAttributes::SetObjectFrame(const ON_COMPONENT_INDEX& ci, const

ON_MeshModifiers& ON_3dmObjectAttributes::MeshModifiers(void) const
{
std::lock_guard<std::recursive_mutex> lg(g_mutex);

if (nullptr == m_private)
m_private = new ON_3dmObjectAttributesPrivate(this);

return m_private->m_mesh_modifiers;
}

const ON_SimpleArray<ON_Decal*>& ON_3dmObjectAttributes::GetDecalArray(void) const
const ON_SimpleArray<ON_Decal*>& ON_3dmObjectAttributes::GetDecalArray(void) const // Deprecated.
{
std::vector<std::shared_ptr<ON_Decal>> decals;
GetDecalArray(decals);

static ON_SimpleArray<ON_Decal*> dummy;
dummy.Destroy();

for (const auto& decal_sp : decals)
{
dummy.Append(decal_sp.get());
}

return dummy;
}

void ON_3dmObjectAttributes::GetDecalArray(std::vector<std::shared_ptr<ON_Decal>>& array_out) const
{
std::lock_guard<std::recursive_mutex> lg(g_mutex);

if (nullptr == m_private)
m_private = new ON_3dmObjectAttributesPrivate(this);

return m_private->m_decals.GetDecalArray();
array_out = m_private->m_decals.GetDecalArray();
}

ON_Decal* ON_3dmObjectAttributes::AddDecal(void) // Deprecated.
{
return AddDecalEx().get();
}

ON_Decal* ON_3dmObjectAttributes::AddDecal(void)
const std::shared_ptr<ON_Decal> ON_3dmObjectAttributes::AddDecalEx(void)
{
std::lock_guard<std::recursive_mutex> lg(g_mutex);

if (nullptr == m_private)
m_private = new ON_3dmObjectAttributesPrivate(this);

Expand All @@ -2543,6 +2574,8 @@ ON_Decal* ON_3dmObjectAttributes::AddDecal(void)

bool ON_3dmObjectAttributes::RemoveDecal(ON_Decal& decal)
{
std::lock_guard<std::recursive_mutex> lg(g_mutex);

if (nullptr == m_private)
m_private = new ON_3dmObjectAttributesPrivate(this);

Expand All @@ -2551,6 +2584,8 @@ bool ON_3dmObjectAttributes::RemoveDecal(ON_Decal& decal)

void ON_3dmObjectAttributes::RemoveAllDecals(void)
{
std::lock_guard<std::recursive_mutex> lg(g_mutex);

if (nullptr == m_private)
m_private = new ON_3dmObjectAttributesPrivate(this);

Expand Down
Loading