Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
DumpGroup.c
/* |
* DumpGroup.c |
* |
* This code lets you select a QuickDraw 3D 3DMF file (via |
* the Standard Get File dialog) which is parsed to find all |
* objects in the metafile. The object class names of these |
* objects are printed in a SIOUX window indented according |
* to their nested level in the group hierarchy. When an |
* attribute set is encountered all contained attributes |
* are printed after this object type. |
* |
* Change History: |
* |
* 12/01/96 Nick Thompson - Created initial version. |
* 01/21/97 Robert Dierkes - Added nesting level at beginning of each |
* printed line and the parsing of attribute sets. |
* |
* ©1997 Apple computer Inc., All Rights Reserved |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <CodeFragments.h> |
#include <Dialogs.h> |
#include <Fonts.h> |
#include <Memory.h> |
#include <QuickDraw.h> |
#include <StandardFile.h> |
#include <Windows.h> |
#include "QD3D.h" |
#include "QD3DGroup.h" |
#include "QD3DIO.h" |
#include "QD3DStorage.h" |
/* Local prototypes */ |
static void InitToolbox(void) ; |
void PrintGroupElementsAndRecurse( TQ3GroupObject theGroup, unsigned long depth ); |
TQ3Status PrintAttributeSetType(TQ3AttributeSet objectType); |
/* initialize the Mac toolbox */ |
static void InitToolbox(void) |
{ |
MaxApplZone() ; |
MoreMasters() ; MoreMasters() ; MoreMasters() ; |
InitGraf( &qd.thePort ); |
InitFonts(); |
InitWindows(); |
FlushEvents( everyEvent, 0 ) ; |
InitCursor(); |
} |
static TQ3FileObject MyNewFileObject( FSSpec *myFSSpec ) |
{ |
TQ3FileObject myFileObj; |
TQ3StorageObject myStorageObj; |
OSType myFileType; |
FInfo fndrInfo ; |
/* |
* we assume the FSSpec passed in was valid, get the file information |
* we need to know the file type, this routine may get called by an appleEvent |
* handler, so we can't assume a type, we need to get it from the fsspec. |
*/ |
FSpGetFInfo( myFSSpec, &fndrInfo ) ; |
/* pull out the file type */ |
myFileType = fndrInfo.fdType ; |
/* Create new storage object and new file object */ |
if(((myStorageObj = Q3FSSpecStorage_New( myFSSpec )) == NULL) |
|| ((myFileObj = Q3File_New()) == NULL)) |
{ |
if (myStorageObj != NULL) |
Q3Object_Dispose(myStorageObj); |
return(NULL); |
} |
/* Set the storage for the file object */ |
Q3File_SetStorage(myFileObj, myStorageObj); |
Q3Object_Dispose(myStorageObj); |
return (myFileObj); |
} |
static TQ3Status MyReadObjectsFromFileIntoGroup( TQ3FileObject theFile,TQ3GroupObject myGroup) |
{ |
if(theFile != NULL) { |
TQ3Object myTempObj ; |
TQ3Boolean isEOF ; |
/* read all objects from the file into the group */ |
do { |
myTempObj = Q3File_ReadObject( theFile ); |
if( myTempObj != NULL ) { |
if( !Q3Object_IsType( myTempObj, kQ3SharedTypeViewHints ) ) |
{ |
Q3Group_AddObject( myGroup, myTempObj ) ; |
} |
Q3Object_Dispose( myTempObj ) ; |
} |
/* check to see if we reached the end of file yet */ |
isEOF = Q3File_IsEndOfFile( theFile ); |
} while (isEOF == kQ3False); |
} |
if( myGroup != NULL ) |
return kQ3Success ; |
else |
return kQ3Failure ; |
} |
static TQ3GroupObject MyNewModelFromFile(FSSpec *theFileSpec) |
{ |
TQ3GroupObject myGroup = NULL ; |
TQ3Boolean isText = kQ3False ; |
TQ3FileMode myFileMode = 0; |
TQ3FileObject theFile; |
/* Create a group for the complete model. */ |
if ((myGroup = Q3Group_New()) == NULL ) |
return NULL; |
theFile = MyNewFileObject( theFileSpec ) ; |
// Open the file object |
if( Q3File_OpenRead( theFile, &myFileMode ) != kQ3Success) |
return NULL ; |
if( MyReadObjectsFromFileIntoGroup( theFile, myGroup ) == 0) |
DebugStr("\pMetafile data read is null") ; |
Q3File_Close(theFile); // close and dispose of the file object |
Q3Object_Dispose(theFile); |
return myGroup ; |
} |
/* get an FSSpec for a metafile */ |
static Boolean MetafileFileSpecify( FSSpec *theFile ) |
{ |
StandardFileReply theSFReply ; |
SFTypeList myTypes = { '3DMF' } ; |
const short numTypes = 1 ; |
/* Get the file name to open */ |
StandardGetFile( nil, numTypes, myTypes, &theSFReply ) ; |
if( theSFReply.sfGood ) |
*theFile = theSFReply.sfFile ; |
/* did the user cancel? */ |
return theSFReply.sfGood ; |
} |
/* the guts... :) */ |
void PrintGroupElementsAndRecurse( TQ3GroupObject theGroup, unsigned long depth ) |
{ |
TQ3GroupPosition thePosition ; |
TQ3Object theObjectAtPosition ; |
TQ3Status theStatus ; |
TQ3Object thisObject ; |
TQ3ObjectType thisObjectType ; |
TQ3ObjectClassNameString objectClassString ; |
unsigned long i ; |
unsigned long numberOfObjects ; |
/* sanity checks, and totals... */ |
if( depth < 1 ) |
depth = 1 ; /* we must always be called with a depth of at least 1 */ |
if ( Q3Object_IsType( theGroup, kQ3ShapeTypeGroup) ) |
{ |
/* print the group name here */ |
thisObjectType = Q3Object_GetLeafType ( theGroup ) ; |
Q3ObjectHierarchy_GetStringFromType( thisObjectType, objectClassString) ; |
Q3Group_CountObjects( theGroup, &numberOfObjects ) ; |
/* really this group is at the level before this, so subtract 1 from the total */ |
printf("%4u ", (depth - 1)) ; |
for( i = 0; i < (depth - 1); i++ ) |
printf(" ") ; |
printf( "%s (contains %u objects)\n", objectClassString, numberOfObjects) ; |
} |
else |
{ |
printf( "PrintGroupElementsAndRecurse called in error, theGroup ain't a group") ; |
return ; |
} |
/* get the first object from the group and iterate through */ |
theStatus = Q3Group_GetFirstPosition ( theGroup, &thePosition ) ; |
while( thePosition != NULL && theStatus == kQ3Success ) |
{ |
theStatus = Q3Group_GetPositionObject ( theGroup, thePosition, &thisObject ) ; |
if(theStatus == kQ3Failure ) |
{ |
printf("GetPositionObject failed, Aborting") ; |
return ; |
} |
if ( Q3Object_IsType( thisObject, kQ3ShapeTypeGroup) ) |
{ |
PrintGroupElementsAndRecurse( thisObject, depth + 1 ) ; |
} |
else |
{ |
thisObjectType = Q3Object_GetLeafType ( thisObject ) ; |
Q3ObjectHierarchy_GetStringFromType( thisObjectType, objectClassString) ; |
printf("%4u ", depth) ; |
for( i = 0; i < depth; i++ ) |
printf(" ") ; |
printf( "%s", objectClassString ) ; |
if (thisObjectType == kQ3SetTypeAttribute) { |
PrintAttributeSetType(thisObject); |
} |
printf( "\n" ) ; |
} |
Q3Object_Dispose( thisObject ) ; |
/* finally get the next object in the group */ |
theStatus = Q3Group_GetNextPosition(theGroup, &thePosition) ; |
} |
} |
TQ3Status PrintAttributeSetType(TQ3Object object) |
{ |
TQ3AttributeType attrType; |
TQ3AttributeType attributeTypes[] = { |
kQ3AttributeTypeNone, |
kQ3AttributeTypeSurfaceUV, |
kQ3AttributeTypeShadingUV, |
kQ3AttributeTypeNormal, |
kQ3AttributeTypeAmbientCoefficient, |
kQ3AttributeTypeDiffuseColor, |
kQ3AttributeTypeSpecularColor, |
kQ3AttributeTypeSpecularControl, |
kQ3AttributeTypeTransparencyColor, |
kQ3AttributeTypeSurfaceTangent, |
kQ3AttributeTypeHighlightState, |
kQ3AttributeTypeSurfaceShader |
}; |
char *attributeTypeNames[] = { |
"None", |
"SurfaceUV", |
"ShadingUV", |
"Normal", |
"AmbientCoefficient", |
"DiffuseColor", |
"SpecularColor", |
"SpecularControl", |
"TransparencyColor", |
"SurfaceTangent", |
"HighlightState", |
"SurfaceShader" |
}; |
unsigned long i, total, count; |
TQ3Status status; |
if (Q3Object_IsType(object, kQ3SetTypeAttribute) == kQ3False) { |
return kQ3Failure; |
} |
count = 0; |
total = sizeof(attributeTypes) / sizeof(TQ3AttributeType); |
attrType = kQ3AttributeTypeNone; |
while (1) { |
status = Q3AttributeSet_GetNextAttributeType(object, &attrType); |
if (status == kQ3Failure) { |
break; |
} |
if (attrType == kQ3AttributeTypeNone) { |
break; |
} |
printf((count == 0) ? " [" : ", "); |
for (i = 0; i < total; i++) { |
if (attrType == attributeTypes[i]) { |
break; |
} |
} |
if (i < total) { |
printf("%s", attributeTypeNames[i]); |
} |
else { |
printf("Custom(%u)", attrType); |
} |
count++; |
} |
if (count) { |
printf("]"); |
} |
else { |
printf(" [None]", attrType); |
} |
return status; |
} |
#ifdef STADALONE_PROGRAM_TO_DUMP_A_GROUP |
/* entry point */ |
void main(void) |
{ |
TQ3Status myStatus ; |
InitToolbox() ; |
if( (long)Q3Initialize != kUnresolvedCFragSymbolAddress ) |
{ |
if((myStatus = Q3Initialize()) == kQ3Success) |
{ |
FSSpec theFileSpec ; |
/* get a metafile */ |
if( MetafileFileSpecify( &theFileSpec )) |
{ |
TQ3GroupObject theGroup ; |
if((theGroup = MyNewModelFromFile(&theFileSpec )) != NULL ) |
PrintGroupElementsAndRecurse( theGroup, 0L ); |
Q3Object_Dispose( theGroup ) ; |
} |
Q3Exit() ; |
} |
} |
} |
#endif |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14