mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-02 20:47:00 +08:00
Add source code for rhino 6.8 release
This commit is contained in:
430
example_read/example_read.cpp
Normal file
430
example_read/example_read.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
/* $NoKeywords: $ */
|
||||
/*
|
||||
//
|
||||
// Copyright (c) 1993-2011 Robert McNeel & Associates. All rights reserved.
|
||||
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
||||
// McNeel & Assoicates.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
||||
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
||||
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
||||
//
|
||||
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// example_read.cpp
|
||||
//
|
||||
// Example program using the Rhino file IO toolkit. The program reads in
|
||||
// a Rhino 3dm model file and describes its contents. The program is a
|
||||
// console application that takes a filename as a command line argument.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "../opennurbs_public_examples.h"
|
||||
|
||||
#include "../example_userdata/example_ud.h"
|
||||
|
||||
static bool Dump3dmFileHelper(
|
||||
const wchar_t* sFileName, // full name of file
|
||||
ON_TextLog& dump
|
||||
)
|
||||
{
|
||||
dump.Print("====== FILENAME: %ls\n",sFileName);
|
||||
ON_Workspace ws;
|
||||
FILE* fp = ws.OpenFile( sFileName, L"rb" ); // file automatically closed by ~ON_Workspace()
|
||||
if ( !fp ) {
|
||||
dump.Print("**ERROR** Unable to open file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ON_BinaryFile file( ON::archive_mode::read3dm, fp );
|
||||
|
||||
int version = 0;
|
||||
ON_String comment_block;
|
||||
bool rc = file.Read3dmStartSection( &version, comment_block );
|
||||
if (!rc) {
|
||||
dump.Print("**ERROR** Read3dmStartSection() failed\n");
|
||||
return false;
|
||||
}
|
||||
dump.Print("====== VERSION: %d\n",version );
|
||||
dump.Print("====== COMMENT BLOCK:\n",version );
|
||||
dump.PushIndent();
|
||||
dump.Print(comment_block);
|
||||
dump.PopIndent();
|
||||
dump.Print("====== CHUNKS:\n",version );
|
||||
unsigned int typecode;
|
||||
while ( !file.AtEnd() ) {
|
||||
typecode = file.Dump3dmChunk( dump, 0 );
|
||||
if ( !typecode )
|
||||
break;
|
||||
if ( typecode == TCODE_ENDOFFILE )
|
||||
break;
|
||||
}
|
||||
dump.Print("====== FINISHED: %ls\n",sFileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns:
|
||||
True if .3dm file was successfully read into an ONX_Model class.
|
||||
*/
|
||||
static bool ReadFileHelper(
|
||||
const wchar_t* sFileName,
|
||||
bool bVerboseTextDump,
|
||||
bool bChunkDump,
|
||||
ON_TextLog& dump
|
||||
)
|
||||
{
|
||||
if ( bChunkDump )
|
||||
{
|
||||
return Dump3dmFileHelper(sFileName,dump);
|
||||
}
|
||||
|
||||
ONX_Model model;
|
||||
|
||||
dump.Print("\nOpenNURBS Archive File: %ls\n", sFileName );
|
||||
|
||||
// open file containing opennurbs archive
|
||||
FILE* archive_fp = ON::OpenFile( sFileName, L"rb");
|
||||
if ( !archive_fp )
|
||||
{
|
||||
dump.Print(" Unable to open file.\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
dump.PushIndent();
|
||||
|
||||
// create achive object from file pointer
|
||||
ON_BinaryFile archive( ON::archive_mode::read3dm, archive_fp );
|
||||
|
||||
// read the contents of the file into "model"
|
||||
bool rc = model.Read( archive, &dump );
|
||||
|
||||
// close the file
|
||||
ON::CloseFile( archive_fp );
|
||||
|
||||
// print diagnostic
|
||||
if ( rc )
|
||||
dump.Print("Successfully read.\n");
|
||||
else
|
||||
dump.Print("Errors during reading.\n");
|
||||
|
||||
// create a text dump of the model
|
||||
if ( bVerboseTextDump )
|
||||
{
|
||||
dump.PushIndent();
|
||||
model.Dump(dump);
|
||||
dump.PopIndent();
|
||||
}
|
||||
|
||||
dump.PopIndent();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns:
|
||||
Number of files read.
|
||||
*/
|
||||
static int ReadDirectoryHelper(
|
||||
int directory_depth,
|
||||
int maximum_directory_depth,
|
||||
const wchar_t* directory_name,
|
||||
const wchar_t* file_name_filter,
|
||||
bool bVerboseTextDump,
|
||||
bool bChunkDump,
|
||||
ON_TextLog& dump
|
||||
)
|
||||
{
|
||||
int file_count = 0;
|
||||
if ( directory_depth <= maximum_directory_depth )
|
||||
{
|
||||
if ( 0 == file_name_filter || 0 == file_name_filter[0] )
|
||||
file_name_filter = L"*.3dm";
|
||||
|
||||
// read files in this directory
|
||||
ON_FileIterator file_it;
|
||||
bool bFoundDirectory = false;
|
||||
for ( bool bHaveFileSystemItem = (file_it.Initialize( directory_name, file_name_filter ) && file_it.FirstItem());
|
||||
bHaveFileSystemItem;
|
||||
bHaveFileSystemItem = file_it.NextItem()
|
||||
)
|
||||
{
|
||||
if (file_it.CurrentItemIsDirectory())
|
||||
{
|
||||
bFoundDirectory = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( false == file_it.CurrentItemIsFile() )
|
||||
continue;
|
||||
|
||||
if ( file_it.CurrentItemIsHidden() )
|
||||
continue;
|
||||
|
||||
ON_wString full_path(file_it.CurrentItemFullPathName());
|
||||
if ( full_path.IsEmpty() )
|
||||
continue;
|
||||
|
||||
if ( !ON::IsOpenNURBSFile(full_path) )
|
||||
continue;
|
||||
|
||||
if ( ReadFileHelper(full_path,bVerboseTextDump,bChunkDump,dump) )
|
||||
file_count++;
|
||||
}
|
||||
|
||||
// read files in subdirectories
|
||||
if ( bFoundDirectory && directory_depth < maximum_directory_depth )
|
||||
{
|
||||
ON_FileIterator dir_it;
|
||||
for ( bool bHaveFileSystemItem = (dir_it.Initialize( directory_name, nullptr ) && dir_it.FirstItem());
|
||||
bHaveFileSystemItem;
|
||||
bHaveFileSystemItem = dir_it.NextItem()
|
||||
)
|
||||
{
|
||||
if ( false == dir_it.CurrentItemIsDirectory() )
|
||||
continue;
|
||||
|
||||
if ( dir_it.CurrentItemIsHidden() )
|
||||
continue;
|
||||
|
||||
ON_wString full_path(dir_it.CurrentItemFullPathName());
|
||||
if ( full_path.IsEmpty() )
|
||||
continue;
|
||||
|
||||
file_count += ReadDirectoryHelper(
|
||||
directory_depth + 1,
|
||||
maximum_directory_depth,
|
||||
full_path,
|
||||
file_name_filter,
|
||||
bVerboseTextDump,
|
||||
bChunkDump,
|
||||
dump
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return file_count;
|
||||
}
|
||||
|
||||
|
||||
static void print_help(const char* example_read_exe_name)
|
||||
{
|
||||
if ( 0 == example_read_exe_name || 0 == example_read_exe_name[0])
|
||||
example_read_exe_name = "example_read";
|
||||
|
||||
printf("\n");
|
||||
printf("SYNOPSIS:\n");
|
||||
printf(" %s [-out:outputfilename.txt] [-c] [-r] <file or directory names>\n",example_read_exe_name );
|
||||
printf("\n");
|
||||
printf("DESCRIPTION:\n");
|
||||
printf(" If a file is listed, it is read as an opennurbs model file.\n");
|
||||
printf(" If a directory is listed, all .3dm files in that directory\n");
|
||||
printf(" are read as opennurbs model files.\n");
|
||||
printf("\n");
|
||||
printf(" Available options:\n");
|
||||
printf(" -out:outputfilename.txt\n");
|
||||
printf(" The output is written to the named file.\n");
|
||||
printf(" -chunkdump\n");
|
||||
printf(" Does a chunk dump instead of reading the file's contents.\n");
|
||||
printf(" -recursive\n");
|
||||
printf(" Recursivly reads files in subdirectories.\n");
|
||||
printf("\n");
|
||||
printf("EXAMPLE:\n");
|
||||
printf(" %s -out:list.txt -resursive .../example_files\n",example_read_exe_name);
|
||||
printf(" with read all the opennurbs .3dm files in the\n");
|
||||
printf(" example_files/ directory and subdirectories.\n");
|
||||
}
|
||||
|
||||
|
||||
#if defined(ON_COMPILER_MSC)
|
||||
|
||||
// When you run a C program, you can use either of the two wildcards
|
||||
// the question mark (?) and the asterisk (*) to specify filename
|
||||
// and path arguments on the command line.
|
||||
// By default, wildcards are not expanded in command-line arguments.
|
||||
// You can replace the normal argument vector argv loading routine with
|
||||
// a version that does expand wildcards by linking with the setargv.obj or wsetargv.obj file.
|
||||
// If your program uses a main function, link with setargv.obj.
|
||||
// If your program uses a wmain function, link with wsetargv.obj.
|
||||
// Both of these have equivalent behavior.
|
||||
// To link with setargv.obj or wsetargv.obj, use the /link option.
|
||||
//
|
||||
// For example:
|
||||
// cl example.c /link setargv.obj
|
||||
// The wildcards are expanded in the same manner as operating system commands.
|
||||
// (See your operating system user's guide if you are unfamiliar with wildcards.)
|
||||
|
||||
// example_read.vcxproj linkin options include setargv.obj.
|
||||
|
||||
#endif
|
||||
|
||||
int main( int argc, const char *argv[] )
|
||||
{
|
||||
// If you are using OpenNURBS as a Windows DLL, then you MUST use
|
||||
// ON::OpenFile() to open the file. If you are not using OpenNURBS
|
||||
// as a Windows DLL, then you may use either ON::OpenFile() or fopen()
|
||||
// to open the file.
|
||||
|
||||
const char* example_read_exe_name = 0;
|
||||
if ( argc >= 1 && 0 != argv && 0 != argv[0] && 0 != argv[0][0] )
|
||||
{
|
||||
on_splitpath(
|
||||
argv[0],
|
||||
nullptr, // drive
|
||||
nullptr, // director,
|
||||
&example_read_exe_name,
|
||||
nullptr // extension
|
||||
);
|
||||
}
|
||||
|
||||
if ( 0 == example_read_exe_name || 0 == example_read_exe_name[0] )
|
||||
{
|
||||
#if defined(ON_OS_WINDOWS)
|
||||
example_read_exe_name = "example_read.exe";
|
||||
#else
|
||||
example_read_exe_name = "example_read";
|
||||
#endif
|
||||
}
|
||||
|
||||
int argi;
|
||||
if ( argc < 2 )
|
||||
{
|
||||
print_help(example_read_exe_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Call once in your application to initialze opennurbs library
|
||||
ON::Begin();
|
||||
|
||||
// default dump is to stdout
|
||||
ON_TextLog dump_to_stdout;
|
||||
dump_to_stdout.SetIndentSize(2);
|
||||
ON_TextLog* dump = &dump_to_stdout;
|
||||
FILE* dump_fp = 0;
|
||||
|
||||
bool bVerboseTextDump = true;
|
||||
|
||||
bool bChunkDump = false;
|
||||
|
||||
|
||||
int maximum_directory_depth = 0;
|
||||
|
||||
int file_count = 0;
|
||||
|
||||
for ( argi = 1; argi < argc; argi++ )
|
||||
{
|
||||
const char* arg = argv[argi];
|
||||
|
||||
// check for -out or /out option
|
||||
if ( ( 0 == strncmp(arg,"-out:",5) || 0 == strncmp(arg,"-out:",5)
|
||||
#if defined(ON_OS_WINDOWS)
|
||||
|| 0 == strncmp(arg,"/out:",5)
|
||||
#endif
|
||||
)
|
||||
&& arg[5] )
|
||||
{
|
||||
// change destination of dump file
|
||||
if ( dump != &dump_to_stdout )
|
||||
{
|
||||
delete dump;
|
||||
dump = 0;
|
||||
}
|
||||
if ( dump_fp )
|
||||
{
|
||||
ON::CloseFile(dump_fp);
|
||||
}
|
||||
|
||||
const char* sDumpFilename = arg+5;
|
||||
FILE* text_fp = ON::OpenFile(sDumpFilename,"w");
|
||||
if ( text_fp )
|
||||
{
|
||||
dump_fp = text_fp;
|
||||
dump = new ON_TextLog(dump_fp);
|
||||
dump->SetIndentSize(2);
|
||||
}
|
||||
|
||||
if ( 0 == dump )
|
||||
dump = &dump_to_stdout;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for -chunkdump or /chunkdump option
|
||||
if ( 0 == strcmp(arg,"-C")
|
||||
|| 0 == strcmp(arg,"-c")
|
||||
|| 0 == strcmp(arg,"-chunk")
|
||||
|| 0 == strcmp(arg,"-chunkdump")
|
||||
#if defined(ON_OS_WINDOWS)
|
||||
|| 0 == strcmp(arg,"/C")
|
||||
|| 0 == strcmp(arg,"/c")
|
||||
|| 0 == strcmp(arg,"/chunk")
|
||||
|| 0 == strcmp(arg,"/chunkdump")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
bChunkDump = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for -recursive or /recursive option
|
||||
if ( 0 == strcmp(arg,"-R")
|
||||
|| 0 == strcmp(arg,"-r")
|
||||
|| 0 == strcmp(arg,"-recurse")
|
||||
|| 0 == strcmp(arg,"-recursive")
|
||||
#if defined(ON_OS_WINDOWS)
|
||||
|| 0 == strcmp(arg,"/R")
|
||||
|| 0 == strcmp(arg,"/r")
|
||||
|| 0 == strcmp(arg,"/recurse")
|
||||
|| 0 == strcmp(arg,"/recursive")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
maximum_directory_depth = 32;
|
||||
continue;
|
||||
}
|
||||
|
||||
ON_wString ws_arg = arg;
|
||||
const wchar_t* wchar_arg = ws_arg;
|
||||
|
||||
if ( ON::IsDirectory(wchar_arg) )
|
||||
{
|
||||
file_count += ReadDirectoryHelper( 0, maximum_directory_depth, wchar_arg, 0, bVerboseTextDump, bChunkDump, *dump );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ReadFileHelper( wchar_arg, bVerboseTextDump, bChunkDump, *dump ) )
|
||||
file_count++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dump->Print("%s read %d opennurbs model files.\n",example_read_exe_name,file_count);
|
||||
if ( dump != &dump_to_stdout )
|
||||
{
|
||||
delete dump;
|
||||
dump = 0;
|
||||
}
|
||||
|
||||
if ( dump_fp )
|
||||
{
|
||||
// close the text dump file
|
||||
ON::CloseFile( dump_fp );
|
||||
dump_fp = 0;
|
||||
}
|
||||
|
||||
// OPTIONAL: Call just before your application exits to clean
|
||||
// up opennurbs class definition information.
|
||||
// Opennurbs will not work correctly after ON::End()
|
||||
// is called.
|
||||
ON::End();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user