#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXCOLOURS 17 /* Current material colour, initialised to impossible value */ float crcol = -1.0, cgcol = -1.0, cbcol = -1.0; /* Current line style, initialised to impossible value */ float clstl = -1; /* Line style list */ float linestyle[4] = {0xffff, 0x0f0f, 0x00ff, 0x000f}; /* Material colour list */ float rcol[2*MAXCOLOURS], gcol[2*MAXCOLOURS], bcol[2*MAXCOLOURS]; /* Flag to see if shape hints have been set for polygons */ int shape_hints = 0; /* Output file */ SoOutput *output; /* Root node for Inventor Scene Graph */ SoSeparator *NGL04root; /* Texture maps */ SoTexture2 *texture1, *texture2; /* Current texture, initialised to impossible value */ int ctexture = -1; /* NAG window in which to display the output */ Widget NAGWindow; int win_display; extern "C" { /********************************************************************* * getNGLRoot returns the root node of the Scene Graph ********************************************************************* */ SoSeparator *getNGLRoot(void) { return NGL04root; } /********************************************************************* * iv_setcolour creates an new material if the requested colour * is different from the one currently in use ********************************************************************* */ void iv_setcolour(int ncol, int colflag) { int icol; /* Use the colour or monochrome material colour * depending on the value of cflag */ if (colflag == 0) /* Monochrome colours stored in lower part of array */ icol = ncol; else /* Real colours in top part of array */ icol = ncol + MAXCOLOURS; /* Set up the new material if required */ if (crcol != rcol[icol] || cgcol != gcol[icol] || cbcol != bcol[icol]) { SoMaterial *material; crcol = rcol[icol]; cgcol = gcol[icol]; cbcol = bcol[icol]; material = new SoMaterial; NGL04root->addChild(material); material->diffuseColor.setValue(crcol, cgcol, cbcol); } } /********************************************************************* * iv_setlinestyle creates an new drawstyle if the requested linestyle * is different from the one currently in use ********************************************************************* */ void iv_setlinestyle(int lstl) { /* Set the new drawstyle if required */ if (clstl != lstl) { SoDrawStyle *style = new SoDrawStyle; NGL04root->addChild(style); style->linePattern.setValue(linestyle[lstl-1]); } } /********************************************************************* * j06wdz renames the first Inventor file to ensure that they are all * named consistently if more than one file is generated ********************************************************************* */ void j06wdz(char *name) { char *errstr = "system command failed: "; char *savefstr = "\n\nThe file has been saved as: "; char *msg, *newname, *sysstr; int length,sys; /* If output is being written to a file, then rename it */ if (win_display == 0) { /* Allocate sufficient space for the new name */ length = strlen(name) + 3; newname = (char *) malloc((size_t) (length * sizeof(char))); /* Define the new name */ (void) strcpy(newname, name); (void) strcat(newname, ".1"); /* Allocate sufficient space for the mv command */ length = strlen("mv ") + 2 * strlen(name) + strlen(" ") + 3; sysstr = (char *) malloc((size_t) (length * sizeof(char))); /* Generate mv command and execute */ (void) strcpy(sysstr, "mv "); (void) strcat(sysstr, name); (void) strcat(sysstr, " "); (void) strcat(sysstr, newname); sys = system(sysstr); /* Error message */ if (sys != 0) { /* Allocate sufficient space for error message */ length = strlen(errstr) + strlen(sysstr) + strlen(name) + strlen(savefstr) + 1; msg = (char *) malloc((size_t) (length * sizeof(char))); /* Generate error message */ (void) strcpy(msg, errstr); (void) strcat(msg, sysstr); (void) strcat(msg, savefstr); (void) strcat(msg, name); } } } /********************************************************************* * j06wzy writes the Inventor Scene Graph to the current output file * and closes the file ********************************************************************* */ void j06wzy(void) { /* If root of Scene Graph was requested, do nothing here */ if (win_display == 0) { /* Attach the Inventor Scene Graph to the output file */ SoWriteAction wa(output); wa.apply(NGL04root); /* Close the output file */ output->closeFile(); } else if (win_display == 1) fprintf(stderr, "viewer not implemented\n"); /* Reset the current colour to its impossible value in case a new * file is to be started up and the material is to be re-recorded */ crcol = -1.0; cgcol = -1.0; cbcol = -1.0; /* Reset the shape hints flag in case a new file is to be started * up and polygons will be plotted */ shape_hints = 0; } /********************************************************************* * j06ycw writes a polyline to the Inventor Scene Graph, using the * requested colour index and line style ********************************************************************* */ void j06ycw(float *x, float *y, int *npt, int *colflag, int *ncol, int *lstl) { long i; SoCoordinate3 *coords; SoIndexedLineSet *lines; /* Use colour or monochrome depending on the value of colflag */ iv_setcolour(*ncol, *colflag); /* Set the line style if required */ iv_setlinestyle(*lstl); /* Add the coordinates node */ coords = new SoCoordinate3; NGL04root->addChild(coords); /* Add an indexed line node */ lines = new SoIndexedLineSet; NGL04root->addChild(lines); /* We have npt points, which will make npt-1 line segments. * Set the coord indices, and the material indices for * the line (each segment of the line needs a separate index). */ for(i = 0; i < *npt-1; i++) lines->coordIndex.set1Value(i, i); /* Set the index of the last coordinate, then insert the index * to indicate the end of this line. */ lines->coordIndex.set1Value(i, *npt-1); i++; lines->coordIndex.set1Value(i, SO_END_LINE_INDEX); /* Add the points to the list of coordinates */ for(i = 0; i < *npt; i++) coords->point.set1Value(i, x[i], y[i], 0.0); } /********************************************************************* * j06xlz sets up the array of possible colours to use for materials ********************************************************************* */ void j06xlz(int *ncol, float *r, float *g, float *b, int *colflag) { int icol; /* Use monochrome or colour depending on value of colflag */ if (*colflag == 0) icol = *ncol; else icol = *ncol + MAXCOLOURS; /* Set the appropriate material colour * while keeping the existing other values */ rcol[icol] = *r; gcol[icol] = *g; bcol[icol] = *b; } /********************************************************************* * j06ynz writes a polygon to the Inventor Scene Graph, using the * requested colour index ********************************************************************* */ void j06ynz(float *x, float *y, int *npt, int *colflag, int *ncol, int *style, int *index, float *s) { long i; SoCoordinate3 *coords; SoIndexedFaceSet *faces; SoSeparator *sep; /* Insert some shape hints when the first polygon is plotted */ if (shape_hints == 0) { /* Ensure that faces may be concave as well as be convex. * The default assumes that faces are convex, which optimises * rendering, but means that concave polygons don't get * displayed properly in fill mode. */ SoShapeHints *hints = new SoShapeHints; hints->faceType = SoShapeHints::UNKNOWN_FACE_TYPE; /* State the vertex ordering explicitly, ensuring that * two-sided lighting is turned on, or faces with normals * pointing away from the viewer will appear black. */ hints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; NGL04root->addChild(hints); /* Set up the images for the texture maps */ texture1 = new SoTexture2; unsigned char image1[] = { 0, 255, 255, 0 }; texture1->image.setValue(SbVec2s(2,2) , 1, image1); texture2 = new SoTexture2; unsigned char image2[] = { 0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 0, 50, 75, 100, 125, 150, 175, 200, 225, 250, 0, 25, 75, 100, 125, 150, 175, 200, 225, 250, 0, 25, 50, 100, 125, 150, 175, 200, 225, 250, 0, 25, 50, 75, 75, 100, 125, 150, 175, 200, 225, 250, 0, 25, 50, 50, 75, 100, 125, 150, 175, 200, 225, 250, 0, 25, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 0, 0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250 }; texture2->image.setValue(SbVec2s(11,9) , 1, image2); /* Set the flag, so this will not be executed again */ shape_hints = 1; } /* Use colour or monochrome depending on the value of colflag */ iv_setcolour(*ncol, *colflag); /* Texture is required */ if (*style == 2) { /* Separator to keep transformations local to the polygon * required only if texture is requested */ sep = new SoSeparator; NGL04root->addChild(sep); /* Add the texture node */ if (*index < 11) sep->addChild(texture1); else sep->addChild(texture2); /* Ensure that the size of the patterns does not change * with the size of the polygon * Have fac repeats of the basic pattern in the unit square */ SoTexture2Transform *trans = new SoTexture2Transform; float fac = 5.0; int ind; if (*index < 11) ind = *index; else { ind = *index/10; ind = *index - ind * 10; } float scalefac = fac * (*s) * float(ind); trans->scaleFactor.setValue(scalefac, scalefac); sep->addChild(trans); } /* Add the coordinates node. * Initialise the number of coordinates. * Add the indexed face node */ coords = new SoCoordinate3; faces = new SoIndexedFaceSet; if (*style == 2) { sep->addChild(coords); sep->addChild(faces); } else { NGL04root->addChild(coords); NGL04root->addChild(faces); } /* Set the coordinate indices, then insert the index * to indicate the end of this face. */ for( i=0; i<*npt; i++) faces->coordIndex.set1Value(i, i); faces->coordIndex.set1Value(i, SO_END_FACE_INDEX); /* Add the points to the list of coordinates */ for( i=0; i<*npt; i++) coords->point.set1Value(i, x[i], y[i], 0.0); } /********************************************************************* * j06zhk writes a text font and text size to the Inventor Scene * Graph, using the requested colour index ********************************************************************* */ void j06zhk(const char *fontname, float *fontsize, int *colflag, int *ncol) { /* Use colour or monochrome depending on the value of colflag */ iv_setcolour(*ncol, *colflag); /* Define the font size * Use a fudge factor because the characters do not occupy all * the available size */ SoFont *font = new SoFont; font->size.setValue(1.2 * (*fontsize)); font->name.setValue(fontname); NGL04root->addChild(font); } /********************************************************************* * j06zhl writes text to the Inventor Scene Graph, using the current * values of colour index, font, and text size ********************************************************************* */ void j06zhl(char *strng, float *x, float *y, float *angle) { /* Separator to keep transformations local to the text string */ SoSeparator *sep = new SoSeparator; NGL04root->addChild(sep); /* Position the text at (x,y,0), rotated over the z axis */ SoTransform *transform = new SoTransform; SbRotation rot(SbVec3f(0.0, 0.0, 1.0), *angle); transform->rotation = rot; transform->translation.setValue(*x, *y, 0.0); sep->addChild(transform); /* Define the text string */ SoText3 *text = new SoText3; text->string = strng; sep->addChild(text); } /********************************************************************* * nagiv1 initialises the Inventor Library, and opens a file for * ASCII or binary output if requested ********************************************************************* */ void nagiv1(char *filename, int *binary) { static int first = 1; /* Initialise the Inventor Library only once */ if (first == 1) { if (strcmp(filename, "**") != 0) { /* If output file or pointer requested * initialise Inventor */ SoDB::init(); /* Distinguish between file and pointer output */ if (strcmp(filename, "*") != 0) win_display = 0; else win_display = 2; } else { /* otherwise initialise Inventor and Xt */ NAGWindow = SoXt::init(""); win_display = 1; } first = 0; } /* Write Inventor ASCII or binary output to a named file */ output = new SoOutput; if (*binary == 1) output->setBinary(TRUE); else output->setBinary(FALSE); if (win_display == 0) output->openFile(filename); /* Create a new Inventor root node and reference it */ NGL04root = new SoSeparator; NGL04root->ref(); } }