home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- Program : PLANT.EXE v0.50a
- Purpose : Create plant-like objects for PoV Ray v1.0 and v2.0 and Polyray v1.6
- raytracers and also export to CTDS format.
- Created : 9/28/93
- By : Rob Bryerton CIS [73747,433]
- File : PLANT050.CPP
- Compiler: Microsoft C++ v8.00
- Model : Small
- Comments: Creates 'organic' plant-like objects using spheres...
-
- *****************************************************************************/
-
- #include <graph.h> // for graphics functions
- #include <stdlib.h> // for srand(), rand()
- #include <time.h> // for randomize()
- #include <math.h> // for sin(), cos()
- #include <conio.h> // for getch()
- #include <fstream.h> // for disk access, cin, cout, etc
- #include <string.h> // for strcpy()
- #include <float.h> // for FLT_MIN, FLT_MAX, etc
-
- #define VERSION "0.50a"
- #define GREEN 2 // color indices
- #define RED 4
- #define LIGHTGREEN 10
- #define YELLOW 14
-
- enum bool {FALSE, TRUE};
- enum Format {POV2,POV1,POLY,CTDS};
-
- struct Vector{ double x,y,z;};
-
- void calc_bounds(void);
- void calc_branch(int size, double theta, double x, double y);
- void calc_cluster(int size, double x, double y);
- void close_display(void);
- void end_run(void);
- void get_inputs(void);
- void init_display(int v_mode);
- void new_union(void);
- void process_args (int argc, char* argv[]);
- void process_option (char* s);
- void reset_bounds(void);
- void set_precision(char* prec);
- void show_title(void);
- void usage(void);
- void write_header(void);
- void write_piece(void);
- void write_union_end(void);
- void write_end(void);
-
- Format format = POV2; // default output
- bool spheres_only = FALSE; // write spheres and cones
- bool nest_bounds = FALSE;
- bool bound_sum = FALSE; // include bound stats w/ each bound written
- bool display = FALSE; // ****** change to FALSE for release version
- bool extended = FALSE; // ****** change to FALSE for release version
- bool write_texture=TRUE; // write texture on EACH segment...choose from 4 colors
- int v_mode=0; // ****** change to 0 for release version
- long bound_val=30,bound_count=0;// bnd every ...and count # bounds written for next nested
- long total_bounds = 1; // start w/1 for default global bounding box
- long counter=0; // total # of objects written
- char com[3] = "//"; // default comment char
- char filename[80]; // outfile name
- char union_name[80]; // for output file union name
- char format_name[20]; // for FORMAT statement in output file
- char buff[257]; // general use buffer
- char texture[80];
- char prev_texture[80]; // the one b/4 texture !
- clock_t start, finish; // ******** 2 lines for timer
- double duration;
- double basic_rad = 1.0,sphere_rad=1.0; // basic radius and current sphere radius
- double bound_radi = 0.0; // current max sph. radius for bound info
- double prev_sphere_rad,max_radius; // radii
- double ht_scale = 1.0; // flat or tall plant
- double internal_scale, user_scale, overall_scale; // fixes numbers so object is 10 units
- Vector ray = {0.0, 0.0, 0.0}; // outfile vector
- Vector prev_ray = {0.0, 0.0, 0.0};
- Vector min = {FLT_MAX, FLT_MAX, FLT_MAX}; // for nested bounding info
- Vector max = {FLT_MIN, FLT_MIN, FLT_MIN};
- Vector gmin = {FLT_MAX, FLT_MAX, FLT_MAX}; // for scene extent and
- Vector gmax = {FLT_MIN, FLT_MIN, FLT_MIN}; // global bounding info
-
- ofstream outfile; // these vars are used for basic shape calculations
- double pi=3.1415926535897932384626; // pi ...lower #'s change 'radius' of plant
- int nume=30; // numerator of probability ...left or rite ?
- int denom=100; // denominator of prob.
- int number=4; // number of branches per cluster
- double rad=4.5; // length of straight line segments
- double deltheta=0.1; // change in THETA (radians)
- int segs=60; // max objects & line segments per branch
- int size=60;
-
- int max_write_len=60; // disregard any piece longer than this number
-
- double redux=3.0; // how much to divide # of segments...lower # means finer 'res.' (more objects)
- int min_len=1; // min # of line segments (spheres per branch)
- int x,y; // display vector...object vector is derived from this also
-
-
-
- //main
- int main(int argc, char* argv[])
- {
- if(argc>1)process_args (argc, argv);
-
- show_title();
- get_inputs(); // get user input and check for 'validity'
-
- outfile.open(filename,ios::out); // try to open disk file
- if(! outfile) exit(1); // if disk access error,exit
-
- if(display) init_display(v_mode); // try to set graphics display
-
- write_header();
- outfile.setf(ios::showpoint | ios::fixed);
- //outfile.precision(6);
- srand( (unsigned)time(NULL) ); // seed random number
-
- x=512,y=384; // set origin of cluster
- internal_scale = 0.1111; // default object size is
- overall_scale = internal_scale*user_scale; // approx.10x10x10
- size = segs;
- bound_val = segs*0.5; // seems to be the best figure as far as rendering
- // speed and bound accuracy are concerned
- if(bound_val < 20) bound_val = 20; // don't want too many bounds
-
- if(display) cerr << "TOP VIEW (XZ)\n";
- cerr << "\nCalculating object... Press any key to abort\n\n";
- start = clock(); // ****************** start timer
-
- calc_cluster(size, x, y); // calculate plant and show progress
-
- if(format != CTDS) write_union_end(); // write final nested bound if nec.
- write_end();
- outfile.close; // close disk file
- finish = clock(); // ********************* stop timer
- duration = (double)(finish - start) / CLOCKS_PER_SEC; // *** calc. time
-
- if(display) {
- cerr << "Press any key to continue...";
- getch(); // wait for keypress
- close_display(); // restore video to previous state
- }
- cout << endl << counter << " objects used to create " << filename;
- cout << "\nCalculation time : "<<duration<< " seconds\n"; // show time
- return(0);
- }
-
- /****************************** **************************
- ****************************** FUNCTION DEFINITIONS *************************
- ****************************** *************************/
-
- void calc_bounds()
- {
- // compute min and max object vectors for current bounding box if needed
- if(format != CTDS && nest_bounds){
- min.x = __min(min.x,ray.x);
- max.x = __max(max.x,ray.x);
- min.y = __min(min.y,ray.y);
- max.y = __max(max.y,ray.y);
- min.z = __min(min.z,ray.z);
- max.z = __max(max.z,ray.z);
- }
-
- gmin.x = __min(gmin.x,ray.x); // now globally
- gmax.x = __max(gmax.x,ray.x);
- gmin.y = __min(gmin.y,ray.y);
- gmax.y = __max(gmax.y,ray.y);
- gmin.z = __min(gmin.z,ray.z);
- gmax.z = __max(gmax.z,ray.z);
- }
-
- void calc_branch(int size, double theta, double x, double y)
- {
- for(int j=0; j<size; j++)
- { // get rand. #, range 0 to denom
- int randy = rand() % denom;
- int chng = (randy<nume) ? -1 : 1; // left or right ??
- theta = theta + chng * deltheta; // new angle
- x = x + rad*sin(theta); // x and y
- y = y + rad*cos(theta); // of next point
- if (size <= max_write_len ){ // this decides whether or not
- // to execute next statements
- /*************************************************************/
- if(size</*4*/(segs*0.0667)){ ray.y =j+(segs-3)+(segs/redux)+((segs/redux)/redux);
- if(display) _setcolor(RED);
- if(j==0) strcpy(texture,"flower_tex");
- sphere_rad = basic_rad*0.85;
- }
- else if(size</*13*/(segs*0.22)){ ray.y =j+(segs-2)+(segs/redux);
- if(display) _setcolor(YELLOW);
- if(j==0) strcpy(texture,"sub_branch_tex");
- sphere_rad = basic_rad*1.2;
- }
- else if(size</*40*/(segs*0.675)){ ray.y =j+(segs-1);
- if(display) _setcolor(LIGHTGREEN);
- if(j==0) strcpy(texture,"branch_tex");
- sphere_rad = basic_rad*1.6;
- }
- else{ ray.y =j;
- if(display) _setcolor(GREEN); //dk green
- if(j==0) strcpy(texture,"stem_tex");
- sphere_rad = basic_rad*2.0;
- }
- if(display){
- if(! write_texture) _setcolor(GREEN); //no textures, right??
- if (v_mode==1) _lineto(int(x*0.625),int(y*0.625));
- else if(v_mode==2) _lineto(int(x*0.78125),int(y*0.78125));
- else _lineto(int(x),int(y)); // draw line
- }
-
- ray.x = ((double)(x-512)*0.3)*overall_scale; // translate sizes to
- ray.z = ((double)(y-384)*0.3)*overall_scale; // file sizes based on
- ray.y = ray.y*overall_scale*ht_scale; // scaling info...
- sphere_rad *= overall_scale;
-
- if(counter==0){ //first time around only
- prev_sphere_rad = sphere_rad;
- max_radius = sphere_rad;
- }
- bound_radi = prev_sphere_rad; //current bound, radius to add to bound
-
- if((format != CTDS) && // if it's POV or Polyray AND we're
- (bound_count==bound_val /*&& nest_bounds*/ || //ready for a bound OR....
- prev_sphere_rad != sphere_rad /*&& nest_bounds*/)// the sphere radius changed...
- ){ // so it's time for a new bound
- write_union_end();
- new_union();
- if(nest_bounds){ // added IF
- total_bounds++;
- reset_bounds();
- }
- bound_count=1;
- write_piece();
- }
- else {
- bound_count++;
- write_piece();
- }
- strcpy(prev_texture, texture);
- prev_sphere_rad = sphere_rad;
- prev_ray.x = ray.x;
- prev_ray.y = ray.y;
- prev_ray.z = ray.z;
-
- calc_bounds();
- counter++; // increment object count
- }
- /***************************************************/
- }
- if(size>min_len)
- { // if branch is long enough,
- int newsize = size / redux; // make a new one, but smaller
- calc_cluster(newsize,x,y); // than before.
- }
- }
-
- void calc_cluster(int size, double x, double y)
- {
- if( kbhit()) end_run();
-
- for(int i=0; i<number; i++) // for each branch
- {
- double theta = i * 2 * pi / number;
-
- if(display){
- if (v_mode==1) _moveto(int(x*0.625),int(y*0.625));
- else if(v_mode==2) _moveto(int(x*0.78125),int(y*0.78125));
- else _moveto(int(x),int(y)); // get set to draw next line
- }
-
- // make a branch
- calc_branch(size, theta, x, y);
- }
- }
-
-
- void close_display()
- {
- _setvideomode(_DEFAULTMODE); // restore video to previous state
- }
-
- void end_run()
- {
- if(format != CTDS) write_union_end();
- write_end();
- if(display) close_display();
- cerr << "\n--RUN ABORTED--\n";
- cout << counter << " objects used to create " << filename << endl;
-
- exit(1);
- }
-
-
- void get_inputs()
- {
- double noise=1.0,pi_distort=1.0,sphere_mult=1.0,denom_mult=1.0;
-
- cout<< "\n1\tPOV 2.0\n2\tPOV 1.0\n3\tPolyray\n4\tCTDS\n" << "Number for format? [1]: ";
- cin.getline(buff,256); int choice = atoi(buff);
- switch(choice){ // output format
- case 2 : format = POV1; strcpy(format_name,"POV-Ray v1.0"); break;
- case 3 : format = POLY; strcpy(format_name,"Polyray v1.6"); break;
- case 4 : format = CTDS; strcpy(format_name,"CTDS"); break;
- default: format = POV2; strcpy(format_name,"POV-Ray v2.0");
- }
- cout << "Ouput filename? [plant.inc]: ";
- cin.getline(buff,256); strcpy(filename,buff);
- if(format != CTDS){
- cout << "Union name? [plant]: ";
- cin.getline(buff,256); strcpy(union_name,buff); }
- cout << "Number of branches (recursive) ? [4]:";
- cin.getline(buff,256); number = atoi(buff);
- cout << "Maximum # of spheres per branch ? [60]:";
- cin.getline(buff,256); segs = atoi(buff); if(segs==0) segs = 60;
- cout << "Minimum # of spheres per branch ? [1]:";
- cin.getline(buff,256); min_len = atoi(buff);
- if(extended) {
- cout << "Disregard branches longer than ? [" <<segs<< "]:";
- cin.getline(buff,256); max_write_len = atoi(buff);
- cout << "Divide branches by ? [3.0]:";
- cin.getline(buff,256); redux = atof(buff);
- cout << "Radial distortion (PI * x) ? [1.0]:";
- cin.getline(buff,256); pi_distort = atof(buff);
- cout << "Branch rotation factor ? [1.0]:";
- cin.getline(buff,256); denom_mult = atof(buff);
- cout << "Overall noise factor ? [1.0]:";
- cin.getline(buff,256); noise = atof(buff);
- cout << "Height scaling ? [1.0]:";
- cin.getline(buff,256); ht_scale = atof(buff);
- cout << "Sphere scaling ? [1.0]:";
- cin.getline(buff,256); sphere_mult = atof(buff); }
- cout << "Global scaling ? [1.0]: ";
- cin.getline(buff,256); user_scale = atof(buff);
-
- // Set up default values if applicable
- if(filename[0]=='\0') strcpy(filename,"plant.inc");
- if(union_name[0]=='\0') strcpy(union_name,"plant");
- if(min_len==0) min_len = 1;
- if(denom_mult==0.0) denom_mult = 1.0; denom *= denom_mult;
- if(number==0) number = 4; if(user_scale==0.0) user_scale = 1.0;
- if(pi_distort==0.0) pi_distort = 1.0; pi *= pi_distort;
- if(noise==0.0) noise = 1.0; deltheta *= noise;
- /*if(segs==0) segs = 60;*/ if(max_write_len==0) max_write_len = segs;
- if(redux==0.0) redux = 3.0;
- if(ht_scale==0.0) ht_scale = 1.0;
- if(sphere_mult==0.0) sphere_mult = 1.0; basic_rad *= sphere_mult;
- if(min_len == segs && max_write_len < min_len){
- // this would cause a math error
- min_len--; // not what user wanted, but better than a stack underflow!!
- }
- }
-
-
- void init_display(int v_mode)
- {
- switch(v_mode){
- case 3 : if(!_setvideomode(_XRES16COLOR)) {cerr << "\nCouldn't set 1024x768 graphics mode... trying 800x600\n"; v_mode = 2;}
- else break; /* 1024x768x16 */
- case 2 : if(!_setvideomode(_SRES16COLOR)) {cerr << "\nCouldn't set 800x600 graphics mode... trying 640x480\n"; v_mode = 1;}
- else break; /* 800x600x16 */
- case 1 : if(!_setvideomode(_VRES16COLOR)) {cerr << "\nCouldn't set 640x480 graphics mode... continuing without display\n"; v_mode = 0;}
- else break; /* 640x480x16 */
- default : display = FALSE; /* no display */
- }
- }
-
-
- void new_union()
- {
-
- switch(format){
- case POV1 :
- outfile << " object{\n union{\n"; break;
- case POLY :
- outfile << "+object{ \n"; break;
- default : // POV2
- outfile << " object{\n union{\n";
- }
-
- }
-
-
- void process_args (int argc, char* argv[])
- {
- for (int i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-' || argv[i][0] == '/')
- process_option (&argv[i][1]);
- else
- {usage(); exit(1);}
- }
- }
-
-
- void process_option (char* s)
- {
- switch (toupper(s[0]))
- {
- case 'B': nest_bounds = TRUE; break; //def=FALSE, don't write bounds
- case 'E': extended = TRUE; break;
- case 'O': spheres_only = TRUE; break;
- case 'P': set_precision(&s[1]); break;
- case 'D': display = TRUE; v_mode = atoi(&s[1]); break; //def=no display
- case 'S': bound_sum = TRUE; break; //def=FALSE, global bound report only
- case 'T': write_texture = FALSE; break; //def=TRUE, write textures
- case '?': usage(); exit(0);
- case 'H': usage(); exit(0);
- default : usage(); exit(1);
- }
- }
-
- void reset_bounds()
- {
- min.x=FLT_MAX, min.y=FLT_MAX, min.z=FLT_MAX; //
- max.x=FLT_MIN, max.y=FLT_MIN, max.z=FLT_MIN; // reset for new bounding box
- }
-
- void set_precision(char* prec)
- {
- outfile.precision((atoi(prec) > 2 ? atoi(prec) : 6 ));
- }
-
- void show_title()
- {
- cout << "\nPlant v"<< VERSION << ", Copyright (c) 1993 Rob Bryerton\n"
- << "Creates a data file of a plant-like object for the POV-Ray v1.0\n"
- << "and v2.0 and Polyray v1.6 raytracers, and the Connect The Dots\n"
- << "Smoother (CTDS).\n";
- }
-
- void write_header()
- {
- if(format==CTDS){ strcpy(com,";"); strcpy(union_name,"-----");}
-
- outfile
- <<com<<" FILE: "<<filename<<" UNION NAME: "<<union_name<<" FORMAT: "<<format_name<< endl
- <<com<<" This data file created by PLANT.EXE v"<<VERSION<<" for the POV-Ray v1.0 and\n"
- <<com<<" v2.0 and Polyray v1.6 raytracers, and the Connect The Dots Smoother (CTDS).\n"
- <<com<<" ----------------SEE END OF LISTING FOR OBJECT EXTENTS----------------------\n\n";
- switch(format) {
- case POLY :
- if(write_texture) {
- outfile
- << "include \"..\\colors.inc\"\n"
- << "define stem_tex texture{ matte { color <0.0, 0.65, 0.0> } }\n"
- << "define branch_tex texture{ matte { color <0.0, 0.8, 0.0> } }\n"
- << "define sub_branch_tex texture{ matte { color yellow } }\n"
- << "define flower_tex texture{ matte { color red } }\n";
- }
- outfile
- << "\ndefine " << union_name << endl
- << "object{ \n object{\n";
- break;
- case POV1 :
- outfile
- << "#declare stem_tex= texture{ diffuse 0.7 color green 0.65 } \n";
- if(write_texture) {
- outfile
- << "#declare branch_tex= texture{ diffuse 0.7 color green 0.8 } \n"
- << "#declare sub_branch_tex= texture{ diffuse 0.7 color Yellow } \n"
- << "#declare flower_tex= texture{ diffuse 0.7 color Red } \n";
- }
- outfile
- << "\n#declare "<<union_name<<" = composite{ \nobject{\n union{\n";
- break;
- default : // POV2
- if(write_texture) {
- outfile
- << "#declare stem_tex= texture{ pigment{color green 0.65} finish{diffuse 0.7} } \n"
- << "#declare branch_tex= texture{ pigment{color green 0.8} finish{diffuse 0.7} } \n"
- << "#declare sub_branch_tex= texture{ pigment{color Yellow} finish{diffuse 0.7} } \n"
- << "#declare flower_tex= texture{ pigment{color Red} finish{diffuse 0.7} } \n";
- }
- outfile
- << "\n#declare "<<union_name<<" = union{ \nobject{\n union{\n";
- }
- }
-
- void write_piece()
- {
- switch(format){
- case POLY :
- if(counter !=0 && bound_count!=1) outfile << " +"; // for Polyray union
- else outfile << " ";
- if(counter==0 || bound_count == 1 || spheres_only) //
- outfile << "object{ sphere < " <<ray.x<< ", " << ray.y << ", " <<ray.z<< " >, " << sphere_rad << " }\n";
- else{
- outfile << "object{ sphere < " <<ray.x<< ", " << ray.y << ", " <<ray.z<< " >, " << sphere_rad << " }\n";
- outfile << " +object{ cone < " <<prev_ray.x<< ", " << prev_ray.y << ", " <<prev_ray.z<< " >, " << sphere_rad << ", < " <<ray.x<< ", " << ray.y << ", " <<ray.z<< " >, " << sphere_rad << " }\n";
- counter++; bound_count++; //add another object to total
- }
- break;
- case CTDS :
- if(sphere_rad != prev_sphere_rad) outfile << endl; //insert blank line for CTDS for each new sphere size for /m option
- outfile << ray.x<< " " << ray.y << " " <<ray.z<< " " << sphere_rad << endl;
- break;
- case POV1 :
- outfile << " sphere{ < " <<ray.x<< " " << ray.y << " " <<ray.z<< " > " << sphere_rad << " }\n";
- break;
- default : // POV2
- if(counter==0 || bound_count == 1 || spheres_only) //
- outfile << " sphere{ < " <<ray.x<< ", " << ray.y << ", " <<ray.z<< " >, " << sphere_rad << " }\n";
- else{
- outfile << " sphere{ < " <<ray.x<< ", " << ray.y << ", " <<ray.z<< " >, " << sphere_rad << " }\n";
- outfile << " cone{ < " <<prev_ray.x<< ", " << prev_ray.y << ", " <<prev_ray.z<< " >, " << sphere_rad << ", < " <<ray.x<< ", " << ray.y << ", " <<ray.z<< " >, " << sphere_rad << " }\n";
- counter++; bound_count++; //add another object to total
- } // else
- } // switch
- } // function
-
-
-
- void write_union_end()
- {
- Vector cbmin,cbmax; // current bound min and max vectors
- if(nest_bounds){
- cbmax.x = max.x + bound_radi;
- cbmin.x = min.x - bound_radi;
- cbmax.y = max.y + bound_radi;
- cbmin.y = min.y - bound_radi;
- cbmax.z = max.z + bound_radi;
- cbmin.z = min.z - bound_radi;
- }
-
- switch(format){
- case POLY :
- if(write_texture) outfile << " " << prev_texture << endl;
- if(nest_bounds){
- outfile << " bounding_box < " <<cbmin.x<<", "<<cbmin.y<<", "<<cbmin.z<<" >,<"
- <<cbmax.x<<", "<<cbmax.y<<", "<<cbmax.z<<" >\n";
- }
- outfile << " }"; // close the current union
- break;
- case POV1 :
- outfile << " }\n"; // close the current union
- if(write_texture) outfile << " texture{ " << prev_texture << " }\n";
- else outfile << " texture{ stem_tex }\n";
-
- if(nest_bounds){ outfile << " bounded_by{ \n"
- << " box{ < " << cbmin.x<<" "<<cbmin.y<<" "<<cbmin.z << "> < "
- << cbmax.x<<" "<<cbmax.y<<" "<<cbmax.z << "> }\n }\n";
- }
- outfile << " }"; // close current object
- break;
- default : // POV2
- outfile << " }\n";
- if(write_texture) outfile << " texture{ " << prev_texture << " }\n";
- if(nest_bounds){ outfile << " bounded_by{ \n"
- << " box{ < " << cbmin.x<<", "<<cbmin.y<<", "<<cbmin.z << ">, < "
- << cbmax.x<<", "<<cbmax.y<<", "<<cbmax.z << "> }\n }\n";
-
- }
- outfile << " }"; // close current object
- }
- if(bound_sum && nest_bounds){
- outfile <<com<<" Current bounding box info...\n"
- <<com<<" Min. x : " << cbmin.x << endl
- <<com<<" y : " << cbmin.y << endl
- <<com<<" z : " << cbmin.z << endl
- <<com<<" Max. x : " << cbmax.x << endl
- <<com<<" y : " << cbmax.y << endl
- <<com<<" z : " << cbmax.z;
- }
- outfile << endl;
- }
-
-
- void write_end()
- {
- gmax.x += max_radius;
- gmin.x -= max_radius;
- gmax.y += max_radius;
- gmin.y -= max_radius;
- gmax.z += max_radius;
- gmin.z -= max_radius;
- if(nest_bounds){
- switch(format){
- case POLY :
- outfile << " bounding_box < " <<gmin.x<<", "<<gmin.y<<", "<<gmin.z<<" >,<"
- <<gmax.x<<", "<<gmax.y<<", "<<gmax.z<<" >\n";
- break;
- case POV1 :
- outfile << " bounded_by{\n"
- << " box{ < " << gmin.x<<" "<<gmin.y<<" "<<gmin.z << "> < "
- << gmax.x<<" "<<gmax.y<<" "<<gmax.z << "> }\n }\n";
- break;
- default : //POV2
- outfile << " bounded_by{\n"
- << " box{ < " << gmin.x<<", "<<gmin.y<<", "<<gmin.z << ">, < "
- << gmax.x<<", "<<gmax.y<<", "<<gmax.z << "> }\n }\n";
- }
- }
- outfile << "}\n\n"; // close 'master' union
- // this next block is output for ALL formats w/the appropriate comment char's
- if(format != CTDS && nest_bounds){
- outfile <<com<<" Bounds written...."<< total_bounds << endl;
- }
- outfile <<com<<" Objects written..."<< counter << endl << endl
- <<com<<" Object extents are as follows...\n"
- <<com<<" Min. x : " << gmin.x << endl
- <<com<<" y : " << gmin.y << endl
- <<com<<" z : " << gmin.z << endl
- <<com<<" Max. x : " << gmax.x << endl
- <<com<<" y : " << gmax.y << endl
- <<com<<" z : " << gmax.z << endl;
- }
-
-
-
- void usage()
- {
- cerr << "\n Plant v" << VERSION << endl
- << "Usage: plant [options]\n"
- << "Options: -b Write bounds in POV or Polyray output.\n"
- << " -d# enables 2D (xz) display of plant... # is the graphics mode.\n"
- << " 0=no display 1=640x480 2=800x600 3=1024x768 \n"
- << " Default value is 0.\n"
- << " -e Gives you a menu with an extended choice of options.\n"
- << " -o Use spheres ONLY (no cones) in output file.\n"
- << " -p# where # is the precision of the output file numbers.\n"
- << " Range is 3 - 9 with a default precision of 6 decimal places.\n"
- << " -s Include all bounding stats in output file. (POV and Polyray)\n"
- << " -t Do NOT write textures in output file.\n"
- << "\nType PLANT with no parameters for the default menus and options.\n";
- }
-
-
-