home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / Anwendun / Pov / POVTOOLS / TOOLS / C3D2POV / SOURCE / CYB_POV.C next >
Encoding:
C/C++ Source or Header  |  1995-11-25  |  11.1 KB  |  307 lines

  1. /********************************************************************************
  2.  
  3.         Konvertiert Cybersculpt 3D2-Files in das POV-Sourceformat.
  4.  
  5.         (c) Coderight Juni 1994:
  6.  
  7.                                     Jochen Knaus            EMail: knaus@mibm.ruf.uni-freiburg.de
  8.                                     Nickeleshalde 19
  9.                                     88400 Biberach
  10.  
  11.         Datum:                27.7.1994
  12.         Update:                30.9.1994 (1.20): kleiner, schneller
  13.                                     19.12.94  (1.3) : Objektsplitting, einh. Kommandozeile
  14.         Version:            1.29
  15.  
  16.         Dieses Konvertierprogramm ist Freeware, im Geiste des POV.
  17.         Irgendwann demnächst wird's auf "smooth triangles" erweitert.
  18.  
  19.         Das ganze sehr unsauber, unstrukturiert, aber schnell gebastelt und
  20.         sollte trotzdem schnell portabel sein.
  21.  
  22.         Aufruf:    CYB_POV -flags 3d2_file <Destfile> <objektname>
  23.                         Flags:    -v    : POV-1 File erzeugen.
  24.                                         -b    : Automatisches berechnen der Objektgrenzen.
  25.                                         -o    : Objektsplitting.
  26.  
  27. **********************************************************************************/
  28.  
  29. #include<stdio.h>
  30. #include<string.h>
  31. #include<portab.h>
  32. #include<stdlib.h>
  33. #include<limits.h>
  34.  
  35. #define _LF                                                            /* Define for separate Linefeed                 */
  36.  
  37. #define VERSION_A    1
  38. #define VERSION_B 29
  39. #define    PATHLEN    256+1                                        /* max. Pfadlänge.                                            */
  40.  
  41. #if !defined( _LF )                                            /* Zeilenabschluß wahlweise mit oder        */
  42. char    buffer3[3] = { '}', 13, 0 };            /* ohne separates Linefeed.                            */
  43. #else
  44. char    buffer3[4] = { '}', 13, 10, 0 };
  45. #endif
  46.  
  47. int        abbruch( void );                                    /* Schließt Files.                                            */
  48. void    write_bounds( void );                            /* Bestimmt und schreibt Objektgrenzen.    */
  49.  
  50. FILE     *source, *destin;                                    /* Filehandles global...                                */
  51. WORD    wandel[6], minmax[6];
  52. int        pov_mode = 2, bounds = FALSE, obj_split = FALSE;
  53. char    *vorzeichen[6], buffer[4000], minus[2] = { '-', 0 },
  54.             nullos[2] = { 0 };
  55.  
  56. int    main( int argc, char *argv[] )
  57. {
  58.     WORD                    header[128], anz_obj, anz_punkte, anz_facetten,
  59.                                 *punkte, *facetten;
  60.     char                    obj_name[10],  buffer2[256],
  61.                                 def_file[PATHLEN] = "STD.POV", def_name[64] = "DEFOBJ",
  62.                                 source_file[PATHLEN];
  63.     register WORD    i, j, m = 1;
  64.  
  65.     printf( "\n3D2->POV Converter vers. %d.%d, (c) 1994 by Jochen Knaus (AURA), Freeware.\n\n",
  66.                     VERSION_A, VERSION_B );
  67.  
  68.     if( argc <= 1 )
  69.     {
  70.         puts( "Kommandozeile: [-vob] sourcefile [destination] [objectname]" );
  71.         return( FALSE );                                        /* Keine Parameter ?                                        */
  72.     }
  73.  
  74.     /* Alle Einträge nach Optionen untersuchen.    */
  75.     if( (argv[1])[0] == '-' )                                        /* "-" beginnt Optionen. */
  76.     {
  77.         if( strlen( argv[1] ) > 1 )                                /* Einzelnes "-" */
  78.         {
  79.             for( j=1 ; j < strlen( argv[1] ); j++ )    /* Alle Optionenzeichen. */
  80.             {
  81.                 switch( (argv[1])[j] )
  82.                 {
  83.                     case    'v':    pov_mode = 1; break;        /* Umschalten auf Ver. 1 */
  84.                     case    'b':    bounds = TRUE ; break;    /* Autobounding. */
  85.                     case    'o':    obj_split = TRUE;                /* Objektsplitting. */
  86.                 }
  87.             }
  88.         }
  89.     }
  90.     else m = 0;                                                                    /* Filenamen im ersten Argument. */
  91.  
  92.     /* Dateinamen und Objektnamen (wenn vorhanden) übernehmen. */
  93.     if( argc > ( 1 + m ) )
  94.     {
  95.         strncpy( source_file, argv[1+m], 127 );
  96.         if( argc > ( 2 + m ) )
  97.         {
  98.             strncpy( def_file, argv[2+m], 127 );
  99.             if( argc > ( 3 + m ) ) strncpy( def_name, argv[3+m], 63 );
  100.         }
  101.     }
  102.     else                                                                                /* Kein zu konvertierendes File ?    */
  103.     {
  104.         fprintf( stderr, "Kein Cybersculptfile angegeben !" );
  105.         return( FALSE );
  106.     }
  107.  
  108.     if( strlen( source_file ) == 0 )                            /* Kein 3D2-File angegeben ? */
  109.     { fputs( "No source (3D2) file.", stderr );
  110.         return( -1 ); }
  111.  
  112.     /* Quelldatei (binär) öffnen. */
  113.     if( ( source = fopen( source_file, "rb" ) ) == NULL )
  114.     {
  115.         fprintf( stdout, "Cannot access sourcefile <%s>.", source_file );
  116.         return( FALSE );
  117.     }
  118.  
  119.     /* Zieldatei (ASCII) erzeugen. */
  120.     if( ( destin = fopen( def_file, "w+" ) ) == NULL )
  121.     {
  122.         fprintf( stderr, "Cannot create or access destinationfile <%s>.", def_file );
  123.         return( FALSE );
  124.     }
  125.  
  126.     /* Header lesen, bei Fehler abbrechen. */
  127.     if( fread( header, 256, 1, source ) < 0 ) return( abbruch() );
  128.  
  129.     if( header[0] != 15618 )                                             /* 3D2-File Kennung ?                */
  130.     {
  131.         fputs( "Kein 3D2 File...", stderr );
  132.         return( abbruch() );
  133.     }
  134.  
  135.     anz_obj = header[1];                                                    /* Anzahl Objekte.                    */
  136.     printf( "%s: convert %d object(s).\n\n", source_file, anz_obj );
  137.  
  138.     /* #declare <objektnamen> erzeugen.    */
  139.     sprintf( buffer, "#declare %s = union {%s", def_name, &buffer3[1] );
  140.     fwrite( buffer, strlen(buffer), 1, destin );
  141.  
  142.     if( !obj_split && bounds )                                    /* Grenzwerte initialisieren? */
  143.     {                                                                                            /* Ohne Objektsplitting muß */
  144.         minmax[0] = INT_MAX; minmax[1] = INT_MIN;        /* Box um ganzes Objekt be- */
  145.         minmax[2] = INT_MAX; minmax[3] = INT_MIN;        /* rechnet werden.                    */
  146.         minmax[4] = INT_MAX; minmax[5] = INT_MIN;
  147.     }
  148.  
  149.     /* Alle Objekte umsetzen, Bufferstring initialisieren.    */
  150.     for( i=0, buffer[0] = '\0'; i<anz_obj ; i++ )                        /* Alle Objekte !    */
  151.     {
  152.         fread( obj_name, 9, 1, source );                            /* Objektnamen.    */
  153.         fread( &anz_punkte, 2, 1, source );                        /* Anzahl Punkte (2 Bytes).    */
  154.  
  155.         if( obj_split )                                                                /* Objektsplitting ?    */
  156.         {
  157.             strcat( buffer, "union{ " ); /* strcat( buffer, &buffer3[1] ); */
  158.  
  159.             if( obj_split && bounds )                                /* Grenzwerte initialisieren. */
  160.             {                                                                                    /* Bei Objektsplitting für    */
  161.                 minmax[0] = INT_MAX; minmax[1] = INT_MIN;    /* jedes einzelne Objekt    */
  162.                 minmax[2] = INT_MAX; minmax[3] = INT_MIN;        /* Boundbox berechnen.    */
  163.                 minmax[4] = INT_MAX; minmax[5] = INT_MIN;
  164.             }
  165.         }
  166.  
  167.         if( anz_punkte > 0 )
  168.         {
  169.             /* Speicher für Punkte reservieren. */
  170.             if( ( punkte = malloc( (long) (anz_punkte * 6) ) ) == NULL )
  171.                 return( abbruch() );
  172.             else
  173.                 fread( punkte, anz_punkte*2, 3, source );            /* Punkte einlesen.  */
  174.  
  175.             if( bounds )                                                    /* Objektgrenzen feststellen ? */
  176.             {
  177.                 for( j = 0 ; j < anz_punkte ; j++ )        /* Objektextremas festellen. */
  178.                 {
  179.                     if( punkte[j*3+0] < minmax[0] ) minmax[0] = punkte[j*3+0];
  180.                     if( punkte[j*3+0] > minmax[1] ) minmax[1] = punkte[j*3+0];
  181.                     if( punkte[j*3+1] < minmax[2] ) minmax[2] = punkte[j*3+1];
  182.                     if( punkte[j*3+1] > minmax[3] ) minmax[3] = punkte[j*3+1];
  183.                     if( punkte[j*3+2] < minmax[4] ) minmax[4] = punkte[j*3+2];
  184.                     if( punkte[j*3+2] > minmax[5] ) minmax[5] = punkte[j*3+2];
  185.                 }
  186.             }
  187.  
  188.             /* Anzahl Facetten. */
  189.             fread( &anz_facetten, 2, 1, source );
  190.  
  191.             /* Objekt und Anzahl Facetten ausgeben. */
  192.             printf( "%8s: %4d faces: ", obj_name, anz_facetten );
  193.  
  194.             /* Facettenspeicher reservieren. */
  195.             if( ( facetten = malloc( (long) (anz_facetten * 8) ) ) == NULL )
  196.             {    free( punkte ); return( abbruch() ); }
  197.             else
  198.                 /* Facetten einlesen. */
  199.                 fread( facetten, anz_facetten*4, 2, source );
  200.  
  201.             /* Objektnamen als Kommentar in Source einfügen. */
  202.             sprintf( buffer2, "/* %s */", obj_name );
  203.             strcat( buffer, buffer2 );    strcat( buffer, &buffer3[1] );
  204.  
  205.             for( j = 0; j<anz_facetten ; j++ )                            /* Facetten konvertieren. */
  206.             {
  207.                 strcat( buffer, " triangle{" );
  208.  
  209.                 /* Punkte wandeln... 2 Stellen Nachkomma (/100) (3D2-Fixkommaformat!),
  210.                      Verkleinerung müssen in POV durchgeführt werden.    */
  211.                 for( m=0 ; m<3 ; m++ )
  212.                 {
  213.                     wandel[0] = (punkte[facetten[j*4+m]*3+0]);            /* x */
  214.                     wandel[1] = (punkte[facetten[j*4+m]*3+1]);            /* y */
  215.                     wandel[2] = (punkte[facetten[j*4+m]*3+2]);            /* z */
  216.                     wandel[3] = abs( wandel[0] );                                        /* Für Nachkomma... */
  217.                     wandel[4] = abs( wandel[1] );
  218.                     wandel[5] = abs( wandel[2] );
  219.                     if( wandel[0] < 0 ) vorzeichen[0] = minus; else vorzeichen[0] = nullos;
  220.                     if( wandel[1] < 0 ) vorzeichen[1] = minus; else vorzeichen[1] = nullos;
  221.                     if( wandel[2] < 0 ) vorzeichen[2] = minus; else vorzeichen[2] = nullos;
  222.  
  223.                     if( pov_mode == 1 )                                        /* POV vers.1 : Keine Kommas */
  224.                         sprintf( buffer2, "<%s%d.%d %s%d.%d %s%d.%d>",
  225.                                             vorzeichen[0], wandel[3] / 100, wandel[3] % 100,
  226.                                             vorzeichen[1], wandel[4] / 100, wandel[4] % 100,
  227.                                             vorzeichen[2], wandel[5] / 100, wandel[5] % 100 );
  228.                     else
  229.                         sprintf( buffer2, "<%s%d.%d,%s%d.%d,%s%d.%d>",
  230.                                             vorzeichen[0], wandel[3] / 100, wandel[3] % 100,
  231.                                             vorzeichen[1], wandel[4] / 100, wandel[4] % 100,
  232.                                             vorzeichen[2], wandel[5] / 100, wandel[5] % 100 );
  233.  
  234.                     strcat( buffer, buffer2 );
  235.                 }
  236.                 strcat( buffer, buffer3 );                                    /* "}" und CR/LF anhängen.                */
  237.  
  238.                 if( j%10 == 0 )                                                            /* Alle 10 Dreiecke schreiben.        */
  239.                 {
  240.                     printf( "." );            /* Der User sieht das Proggy arbeiten und freut sich... */
  241.                     fwrite( buffer, strlen(buffer), 1, destin );
  242.                     buffer[0] = '\0';                                                    /* Buffer zurücksetzen.                        */
  243.                 }
  244.             }     /* Nächstes Facette */
  245.  
  246.  
  247.             if( strlen( buffer ) > 0 )                                        /* Restlichen Facetten schreiben. */
  248.             {        fwrite( buffer, strlen(buffer), 1, destin ); buffer[0] = '\0'; }
  249.  
  250.             if( obj_split )                                                                    /* Objektsplitting ?                        */
  251.             {
  252.                 if( bounds ) write_bounds();                                    /* even. Grenzen schreiben.            */
  253.                 fwrite( buffer3, strlen(buffer3), 1, destin );/* "union" abschliessen.                */
  254.             }
  255.  
  256.             free(punkte); free(facetten);                                        /* Objektspeicher freigeben.        */
  257.         }  /* "endif"... */
  258.  
  259.         puts( " done." );
  260.     }        /* Nächstes 3D2-Objekt. */
  261.  
  262.     /* Falls für gesamtes Objekt "bounded" gewünscht wurde. */
  263.     if( bounds && !obj_split ) write_bounds();
  264.  
  265.     fwrite( buffer3, strlen(buffer3), 1, destin );            /* declare-union abschließen.        */
  266.     fclose( source ); fclose( destin );                                    /* Files schließen.                            */
  267.     return( TRUE );
  268. }
  269.  
  270. /* Bestimmt Grenzen und fügt diese an. */
  271. VOID write_bounds()
  272. {
  273.     wandel[0] = abs( minmax[0] ); wandel[1] = abs( minmax[1] );
  274.     wandel[2] = abs( minmax[2] ); wandel[3] = abs( minmax[3] );
  275.     wandel[4] = abs( minmax[4] ); wandel[5] = abs( minmax[5] );
  276.     if( minmax[0] < 0 ) vorzeichen[0] = minus; else vorzeichen[0] = nullos;
  277.     if( minmax[1] < 0 ) vorzeichen[1] = minus; else vorzeichen[1] = nullos;
  278.     if( minmax[2] < 0 ) vorzeichen[2] = minus; else vorzeichen[2] = nullos;
  279.     if( minmax[3] < 0 ) vorzeichen[3] = minus; else vorzeichen[3] = nullos;
  280.     if( minmax[4] < 0 ) vorzeichen[4] = minus; else vorzeichen[4] = nullos;
  281.     if( minmax[5] < 0 ) vorzeichen[5] = minus; else vorzeichen[5] = nullos;
  282.  
  283.     if( pov_mode == 1 )
  284.         sprintf( buffer, " bounded_by{box{<%s%d.%d %s%d.%d %s%d.%d><%s%d.%d %s%d.%d %s%d.%d>}}",
  285.                             vorzeichen[0], wandel[0] / 100, wandel[0] % 100,
  286.                             vorzeichen[2], wandel[2] / 100, wandel[2] % 100,
  287.                             vorzeichen[4], wandel[4] / 100, wandel[4] % 100,
  288.                             vorzeichen[1], wandel[1] / 100, wandel[1] % 100,
  289.                             vorzeichen[3], wandel[3] / 100, wandel[3] % 100,
  290.                             vorzeichen[5], wandel[5] / 100, wandel[5] % 100 );
  291.     else
  292.         sprintf( buffer, " bounded_by{box{<%s%d.%d,%s%d.%d,%s%d.%d><%s%d.%d,%s%d.%d,%s%d.%d>}}",
  293.                             vorzeichen[0], wandel[0] / 100, wandel[0] % 100,
  294.                             vorzeichen[2], wandel[2] / 100, wandel[2] % 100,
  295.                             vorzeichen[4], wandel[4] / 100, wandel[4] % 100,
  296.                             vorzeichen[1], wandel[1] / 100, wandel[1] % 100,
  297.                             vorzeichen[3], wandel[3] / 100, wandel[3] % 100,
  298.                             vorzeichen[5], wandel[5] / 100, wandel[5] % 100 );
  299.  
  300.     fwrite( buffer, strlen(buffer), 1, destin );    buffer[0] = '\0';
  301. }
  302.  
  303. int abbruch()
  304. {
  305.     fclose( source );    fclose( destin );
  306.     return( FALSE );
  307. }