home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
-
- Konvertiert Cybersculpt 3D2-Files in das POV-Sourceformat.
-
- (c) Coderight Juni 1994:
-
- Jochen Knaus EMail: knaus@mibm.ruf.uni-freiburg.de
- Nickeleshalde 19
- 88400 Biberach
-
- Datum: 27.7.1994
- Update: 30.9.1994 (1.20): kleiner, schneller
- 19.12.94 (1.3) : Objektsplitting, einh. Kommandozeile
- Version: 1.29
-
- Dieses Konvertierprogramm ist Freeware, im Geiste des POV.
- Irgendwann demnächst wird's auf "smooth triangles" erweitert.
-
- Das ganze sehr unsauber, unstrukturiert, aber schnell gebastelt und
- sollte trotzdem schnell portabel sein.
-
- Aufruf: CYB_POV -flags 3d2_file <Destfile> <objektname>
- Flags: -v : POV-1 File erzeugen.
- -b : Automatisches berechnen der Objektgrenzen.
- -o : Objektsplitting.
-
- **********************************************************************************/
-
- #include<stdio.h>
- #include<string.h>
- #include<portab.h>
- #include<stdlib.h>
- #include<limits.h>
-
- #define _LF /* Define for separate Linefeed */
-
- #define VERSION_A 1
- #define VERSION_B 29
- #define PATHLEN 256+1 /* max. Pfadlänge. */
-
- #if !defined( _LF ) /* Zeilenabschluß wahlweise mit oder */
- char buffer3[3] = { '}', 13, 0 }; /* ohne separates Linefeed. */
- #else
- char buffer3[4] = { '}', 13, 10, 0 };
- #endif
-
- int abbruch( void ); /* Schließt Files. */
- void write_bounds( void ); /* Bestimmt und schreibt Objektgrenzen. */
-
- FILE *source, *destin; /* Filehandles global... */
- WORD wandel[6], minmax[6];
- int pov_mode = 2, bounds = FALSE, obj_split = FALSE;
- char *vorzeichen[6], buffer[4000], minus[2] = { '-', 0 },
- nullos[2] = { 0 };
-
- int main( int argc, char *argv[] )
- {
- WORD header[128], anz_obj, anz_punkte, anz_facetten,
- *punkte, *facetten;
- char obj_name[10], buffer2[256],
- def_file[PATHLEN] = "STD.POV", def_name[64] = "DEFOBJ",
- source_file[PATHLEN];
- register WORD i, j, m = 1;
-
- printf( "\n3D2->POV Converter vers. %d.%d, (c) 1994 by Jochen Knaus (AURA), Freeware.\n\n",
- VERSION_A, VERSION_B );
-
- if( argc <= 1 )
- {
- puts( "Kommandozeile: [-vob] sourcefile [destination] [objectname]" );
- return( FALSE ); /* Keine Parameter ? */
- }
-
- /* Alle Einträge nach Optionen untersuchen. */
- if( (argv[1])[0] == '-' ) /* "-" beginnt Optionen. */
- {
- if( strlen( argv[1] ) > 1 ) /* Einzelnes "-" */
- {
- for( j=1 ; j < strlen( argv[1] ); j++ ) /* Alle Optionenzeichen. */
- {
- switch( (argv[1])[j] )
- {
- case 'v': pov_mode = 1; break; /* Umschalten auf Ver. 1 */
- case 'b': bounds = TRUE ; break; /* Autobounding. */
- case 'o': obj_split = TRUE; /* Objektsplitting. */
- }
- }
- }
- }
- else m = 0; /* Filenamen im ersten Argument. */
-
- /* Dateinamen und Objektnamen (wenn vorhanden) übernehmen. */
- if( argc > ( 1 + m ) )
- {
- strncpy( source_file, argv[1+m], 127 );
- if( argc > ( 2 + m ) )
- {
- strncpy( def_file, argv[2+m], 127 );
- if( argc > ( 3 + m ) ) strncpy( def_name, argv[3+m], 63 );
- }
- }
- else /* Kein zu konvertierendes File ? */
- {
- fprintf( stderr, "Kein Cybersculptfile angegeben !" );
- return( FALSE );
- }
-
- if( strlen( source_file ) == 0 ) /* Kein 3D2-File angegeben ? */
- { fputs( "No source (3D2) file.", stderr );
- return( -1 ); }
-
- /* Quelldatei (binär) öffnen. */
- if( ( source = fopen( source_file, "rb" ) ) == NULL )
- {
- fprintf( stdout, "Cannot access sourcefile <%s>.", source_file );
- return( FALSE );
- }
-
- /* Zieldatei (ASCII) erzeugen. */
- if( ( destin = fopen( def_file, "w+" ) ) == NULL )
- {
- fprintf( stderr, "Cannot create or access destinationfile <%s>.", def_file );
- return( FALSE );
- }
-
- /* Header lesen, bei Fehler abbrechen. */
- if( fread( header, 256, 1, source ) < 0 ) return( abbruch() );
-
- if( header[0] != 15618 ) /* 3D2-File Kennung ? */
- {
- fputs( "Kein 3D2 File...", stderr );
- return( abbruch() );
- }
-
- anz_obj = header[1]; /* Anzahl Objekte. */
- printf( "%s: convert %d object(s).\n\n", source_file, anz_obj );
-
- /* #declare <objektnamen> erzeugen. */
- sprintf( buffer, "#declare %s = union {%s", def_name, &buffer3[1] );
- fwrite( buffer, strlen(buffer), 1, destin );
-
- if( !obj_split && bounds ) /* Grenzwerte initialisieren? */
- { /* Ohne Objektsplitting muß */
- minmax[0] = INT_MAX; minmax[1] = INT_MIN; /* Box um ganzes Objekt be- */
- minmax[2] = INT_MAX; minmax[3] = INT_MIN; /* rechnet werden. */
- minmax[4] = INT_MAX; minmax[5] = INT_MIN;
- }
-
- /* Alle Objekte umsetzen, Bufferstring initialisieren. */
- for( i=0, buffer[0] = '\0'; i<anz_obj ; i++ ) /* Alle Objekte ! */
- {
- fread( obj_name, 9, 1, source ); /* Objektnamen. */
- fread( &anz_punkte, 2, 1, source ); /* Anzahl Punkte (2 Bytes). */
-
- if( obj_split ) /* Objektsplitting ? */
- {
- strcat( buffer, "union{ " ); /* strcat( buffer, &buffer3[1] ); */
-
- if( obj_split && bounds ) /* Grenzwerte initialisieren. */
- { /* Bei Objektsplitting für */
- minmax[0] = INT_MAX; minmax[1] = INT_MIN; /* jedes einzelne Objekt */
- minmax[2] = INT_MAX; minmax[3] = INT_MIN; /* Boundbox berechnen. */
- minmax[4] = INT_MAX; minmax[5] = INT_MIN;
- }
- }
-
- if( anz_punkte > 0 )
- {
- /* Speicher für Punkte reservieren. */
- if( ( punkte = malloc( (long) (anz_punkte * 6) ) ) == NULL )
- return( abbruch() );
- else
- fread( punkte, anz_punkte*2, 3, source ); /* Punkte einlesen. */
-
- if( bounds ) /* Objektgrenzen feststellen ? */
- {
- for( j = 0 ; j < anz_punkte ; j++ ) /* Objektextremas festellen. */
- {
- if( punkte[j*3+0] < minmax[0] ) minmax[0] = punkte[j*3+0];
- if( punkte[j*3+0] > minmax[1] ) minmax[1] = punkte[j*3+0];
- if( punkte[j*3+1] < minmax[2] ) minmax[2] = punkte[j*3+1];
- if( punkte[j*3+1] > minmax[3] ) minmax[3] = punkte[j*3+1];
- if( punkte[j*3+2] < minmax[4] ) minmax[4] = punkte[j*3+2];
- if( punkte[j*3+2] > minmax[5] ) minmax[5] = punkte[j*3+2];
- }
- }
-
- /* Anzahl Facetten. */
- fread( &anz_facetten, 2, 1, source );
-
- /* Objekt und Anzahl Facetten ausgeben. */
- printf( "%8s: %4d faces: ", obj_name, anz_facetten );
-
- /* Facettenspeicher reservieren. */
- if( ( facetten = malloc( (long) (anz_facetten * 8) ) ) == NULL )
- { free( punkte ); return( abbruch() ); }
- else
- /* Facetten einlesen. */
- fread( facetten, anz_facetten*4, 2, source );
-
- /* Objektnamen als Kommentar in Source einfügen. */
- sprintf( buffer2, "/* %s */", obj_name );
- strcat( buffer, buffer2 ); strcat( buffer, &buffer3[1] );
-
- for( j = 0; j<anz_facetten ; j++ ) /* Facetten konvertieren. */
- {
- strcat( buffer, " triangle{" );
-
- /* Punkte wandeln... 2 Stellen Nachkomma (/100) (3D2-Fixkommaformat!),
- Verkleinerung müssen in POV durchgeführt werden. */
- for( m=0 ; m<3 ; m++ )
- {
- wandel[0] = (punkte[facetten[j*4+m]*3+0]); /* x */
- wandel[1] = (punkte[facetten[j*4+m]*3+1]); /* y */
- wandel[2] = (punkte[facetten[j*4+m]*3+2]); /* z */
- wandel[3] = abs( wandel[0] ); /* Für Nachkomma... */
- wandel[4] = abs( wandel[1] );
- wandel[5] = abs( wandel[2] );
- if( wandel[0] < 0 ) vorzeichen[0] = minus; else vorzeichen[0] = nullos;
- if( wandel[1] < 0 ) vorzeichen[1] = minus; else vorzeichen[1] = nullos;
- if( wandel[2] < 0 ) vorzeichen[2] = minus; else vorzeichen[2] = nullos;
-
- if( pov_mode == 1 ) /* POV vers.1 : Keine Kommas */
- sprintf( buffer2, "<%s%d.%d %s%d.%d %s%d.%d>",
- vorzeichen[0], wandel[3] / 100, wandel[3] % 100,
- vorzeichen[1], wandel[4] / 100, wandel[4] % 100,
- vorzeichen[2], wandel[5] / 100, wandel[5] % 100 );
- else
- sprintf( buffer2, "<%s%d.%d,%s%d.%d,%s%d.%d>",
- vorzeichen[0], wandel[3] / 100, wandel[3] % 100,
- vorzeichen[1], wandel[4] / 100, wandel[4] % 100,
- vorzeichen[2], wandel[5] / 100, wandel[5] % 100 );
-
- strcat( buffer, buffer2 );
- }
- strcat( buffer, buffer3 ); /* "}" und CR/LF anhängen. */
-
- if( j%10 == 0 ) /* Alle 10 Dreiecke schreiben. */
- {
- printf( "." ); /* Der User sieht das Proggy arbeiten und freut sich... */
- fwrite( buffer, strlen(buffer), 1, destin );
- buffer[0] = '\0'; /* Buffer zurücksetzen. */
- }
- } /* Nächstes Facette */
-
-
- if( strlen( buffer ) > 0 ) /* Restlichen Facetten schreiben. */
- { fwrite( buffer, strlen(buffer), 1, destin ); buffer[0] = '\0'; }
-
- if( obj_split ) /* Objektsplitting ? */
- {
- if( bounds ) write_bounds(); /* even. Grenzen schreiben. */
- fwrite( buffer3, strlen(buffer3), 1, destin );/* "union" abschliessen. */
- }
-
- free(punkte); free(facetten); /* Objektspeicher freigeben. */
- } /* "endif"... */
-
- puts( " done." );
- } /* Nächstes 3D2-Objekt. */
-
- /* Falls für gesamtes Objekt "bounded" gewünscht wurde. */
- if( bounds && !obj_split ) write_bounds();
-
- fwrite( buffer3, strlen(buffer3), 1, destin ); /* declare-union abschließen. */
- fclose( source ); fclose( destin ); /* Files schließen. */
- return( TRUE );
- }
-
- /* Bestimmt Grenzen und fügt diese an. */
- VOID write_bounds()
- {
- wandel[0] = abs( minmax[0] ); wandel[1] = abs( minmax[1] );
- wandel[2] = abs( minmax[2] ); wandel[3] = abs( minmax[3] );
- wandel[4] = abs( minmax[4] ); wandel[5] = abs( minmax[5] );
- if( minmax[0] < 0 ) vorzeichen[0] = minus; else vorzeichen[0] = nullos;
- if( minmax[1] < 0 ) vorzeichen[1] = minus; else vorzeichen[1] = nullos;
- if( minmax[2] < 0 ) vorzeichen[2] = minus; else vorzeichen[2] = nullos;
- if( minmax[3] < 0 ) vorzeichen[3] = minus; else vorzeichen[3] = nullos;
- if( minmax[4] < 0 ) vorzeichen[4] = minus; else vorzeichen[4] = nullos;
- if( minmax[5] < 0 ) vorzeichen[5] = minus; else vorzeichen[5] = nullos;
-
- if( pov_mode == 1 )
- sprintf( buffer, " bounded_by{box{<%s%d.%d %s%d.%d %s%d.%d><%s%d.%d %s%d.%d %s%d.%d>}}",
- vorzeichen[0], wandel[0] / 100, wandel[0] % 100,
- vorzeichen[2], wandel[2] / 100, wandel[2] % 100,
- vorzeichen[4], wandel[4] / 100, wandel[4] % 100,
- vorzeichen[1], wandel[1] / 100, wandel[1] % 100,
- vorzeichen[3], wandel[3] / 100, wandel[3] % 100,
- vorzeichen[5], wandel[5] / 100, wandel[5] % 100 );
- else
- sprintf( buffer, " bounded_by{box{<%s%d.%d,%s%d.%d,%s%d.%d><%s%d.%d,%s%d.%d,%s%d.%d>}}",
- vorzeichen[0], wandel[0] / 100, wandel[0] % 100,
- vorzeichen[2], wandel[2] / 100, wandel[2] % 100,
- vorzeichen[4], wandel[4] / 100, wandel[4] % 100,
- vorzeichen[1], wandel[1] / 100, wandel[1] % 100,
- vorzeichen[3], wandel[3] / 100, wandel[3] % 100,
- vorzeichen[5], wandel[5] / 100, wandel[5] % 100 );
-
- fwrite( buffer, strlen(buffer), 1, destin ); buffer[0] = '\0';
- }
-
- int abbruch()
- {
- fclose( source ); fclose( destin );
- return( FALSE );
- }