/************************************* iv2rib.c++ ************************************** * (C) 1997 Mark Lasersohn - Cow House Productions Iv2rib V0.11 This is an alpha executable and source for Irix 5.3 and the OpenInventor 2.0 (or better) run-time library. I reserve all rights, this executable and source file is the copywritten property of Cow House Productions and may not be packaged or resold without written permission. It is distributed from my web page (http://www.cowhouse.com). The source and executable may be distributed freely, as long as it is done so freely and my copyright notices remain intact. Syntax: iv2rib [-b][-n][-size x y][-bmrt] input_file.iv [ > output.rib ] The -b flag causes backface removal. This will save memory and rendering time, but if there is a reflection that reveals the back of an object, the removal will be evident. The -n flag causes normals to be included in the output polygon information. Iv2rib will not translate the inventor 2D constructs, such as points, lines, or 2D text. I have also been informed that it won't do so well with quads or nurbs. To compile the source on SGI with OpenInventor, simple type: CC iv2rib.c++ -lInventor -o iv2rib I don't have any other versions of Inventor, so TGS and Portable Graphics users are on their own. This is command line utility without a graphical user interface. Thus it should readily compile. But if you have any problems, please feel free to contact me at laser@cowhouse.com. I have happily tracked down and on occasion fixed bugs found by users. I don't promise to fix any problems but I will get back to you and I really do want to hear your ideas, suggestions, and comments. Mark Lasersohn Cow House Productions laser@cowhouse.com http://www.cowhouse.com */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEGREES (360.0 / 6.28) char surf_name[10000][20]; float surf_ambient_r[10000]; float surf_ambient_g[10000]; float surf_ambient_b[10000]; float surf_diffuse_r[10000]; float surf_diffuse_g[10000]; float surf_diffuse_b[10000]; float surf_specular_r[10000]; float surf_specular_g[10000]; float surf_specular_b[10000]; float surf_transparency[10000]; float surf_shininess[10000]; int surf_cnt; int backface; char texture_filename[256]; long int texture_index_count; int vcnt = 0; int nvcnt = 0; SbVec3f gvec[1000000]; SbVec3f nvec[1000000]; SbVec3f gvec2[1000000]; SbVec3f nvec2[1000000]; FILE *fp1, *fp2; float camera_loc_x = 0.0; float camera_loc_y = 0.0; float camera_loc_z = 0.0; float bound_x, bound_y, bound_z; float bound_xmin, bound_ymin, bound_zmin; float bound_xmax, bound_ymax, bound_zmax; int normalate = 0; int bmrt_flag = 0; static const SbVec3f &transformPoint(const SbMatrix &m, const SbVec3f &p) { static SbVec3f tp; m.multVecMatrix(p, tp); return tp; } static const SbVec3f &transformNormal(const SbMatrix &m, const SbVec3f &n) { static SbVec3f tn; m.multDirMatrix(n, tn); tn.normalize(); return tn; } SoCallbackAction::Response preTextureCB(void *, SoCallbackAction *, const SoNode *nd) { char *cp; SoTexture2 *texture = (SoTexture2 *)nd; strcpy(texture_filename, texture->filename.getValue().getString()); cp = texture_filename + strlen(texture_filename); while((*cp != '.') && (cp > texture_filename)) cp--; *cp = '\0'; return(SoCallbackAction::CONTINUE); } SoCallbackAction::Response preCameraCB(void *, SoCallbackAction *, const SoNode *nd) { SbVec3f vec; float radians; SoPerspectiveCamera *camera = (SoPerspectiveCamera *)nd; vec = camera->position.getValue(); camera_loc_x = vec[0]; camera_loc_y = vec[1]; camera_loc_z = vec[2]; SbRotation rot = camera->orientation.getValue(); rot.getValue(vec, radians); printf("Orientation \"rh\"\n"); printf("Projection \"perspective\" \"fov\" %f\n", camera->aspectRatio.getValue() * DEGREES); printf("WorldBegin\n"); return(SoCallbackAction::CONTINUE); } SoCallbackAction::Response preLightCB(void *, SoCallbackAction *cba, const SoNode *nd) { float r, g, b; float angle; SbVec3f vec1; SbVec3f vec2; SbVec3f vec3; float dx_min, dy_min, dz_min; float dx_max, dy_max, dz_max; float intensity; float minimum, maximum; static int light_count = 1; if(light_count == 1) { if(bmrt_flag == 1) printf("Attribute \"light\" \"shadows\" \"on\"\n"); } const SbMatrix &vm = cba->getViewingMatrix(); if(nd->isOfType(SoDirectionalLight::getClassTypeId())) { SoDirectionalLight *light = (SoDirectionalLight *)nd; light->color.getValue().getValue(r, g, b); vec1[0] = camera_loc_x; vec1[1] = camera_loc_y; vec1[2] = camera_loc_z; vec2 = transformPoint(vm, vec1); vec3 = light->direction.getValue(); vec3[0] = vec1[0] + vec3[0]; vec3[1] = vec1[1] + vec3[1]; vec3[2] = vec1[2] + vec3[2]; vec3 = transformPoint(vm, vec3); printf("LightSource \"distantlight\" %d \"intensity\" [%g] \"lightcolor\" [%g %g %g] \"from\" [%g %g %g] \"to\" [%g %g %g]\n" , light_count, light->intensity.getValue(), r, g, b, vec2[0], vec2[1], -vec2[2] , vec3[0], vec3[1], -vec3[2]); printf("Illuminate %d 1\n", light_count); light_count++; } if(nd->isOfType(SoPointLight::getClassTypeId())) { SoPointLight *light = (SoPointLight *)nd; light->color.getValue().getValue(r, g, b); vec1 = light->location.getValue(); dx_min = fabs(vec1[0] - bound_xmin); dy_min = fabs(vec1[1] - bound_ymin); dz_min = fabs(vec1[2] - bound_zmin); minimum = sqrt((dx_min * dx_min) + (dy_min * dy_min) + (dz_min * dz_min)); dx_max = fabs(vec1[0] - bound_xmax); dy_max = fabs(vec1[1] - bound_ymax); dz_max = fabs(vec1[2] - bound_zmax); maximum = sqrt((dx_max * dx_max) + (dy_max * dy_max) + (dz_max * dz_max)); if(maximum > minimum) intensity = maximum; else intensity = minimum; intensity *= intensity; vec2 = transformPoint(vm, vec1); printf("LightSource \"pointlight\" %d \"intensity\" [%g] \"lightcolor\" [%g %g %g] \"from\" [%g %g %g]\n" , light_count, intensity, r, g, b, vec2[0], vec2[1], -vec2[2]); printf("Illuminate %d 1\n", light_count); light_count++; } if(nd->isOfType(SoSpotLight::getClassTypeId())) { SoSpotLight *light = (SoSpotLight *)nd; light->color.getValue().getValue(r, g, b); vec1 = light->location.getValue(); dx_min = fabs(vec1[0] - bound_xmin); dy_min = fabs(vec1[1] - bound_ymin); dz_min = fabs(vec1[2] - bound_zmin); minimum = sqrt((dx_min * dx_min) + (dy_min * dy_min) + (dz_min * dz_min)); dx_max = fabs(vec1[0] - bound_xmax); dy_max = fabs(vec1[1] - bound_ymax); dz_max = fabs(vec1[2] - bound_zmax); maximum = sqrt((dx_max * dx_max) + (dy_max * dy_max) + (dz_max * dz_max)); if(maximum > minimum) intensity = maximum; else intensity = minimum; intensity *= intensity; vec2 = transformPoint(vm, vec1); vec3 = light->direction.getValue(); vec3[0] = vec1[0] + vec3[0]; vec3[1] = vec1[1] + vec3[1]; vec3[2] = vec1[2] + vec3[2]; vec3 = transformPoint(vm, vec3); printf("LightSource \"spotlight\" %d \"intensity\" [%g] \"lightcolor\" [%g %g %g] \"from\" [%g %g %g] \"to\" [%g %g %g] " , light_count, intensity, r, g, b, vec2[0], vec2[1], -vec2[2] , vec3[0], vec3[1], -vec3[2]); angle = light->cutOffAngle.getValue() * DEGREES; printf("\"coneangle\" [%g]\n", angle); printf("Illuminate %d 1\n", light_count); light_count++; } return(SoCallbackAction::CONTINUE); } static void addTriangleCB(void *, SoCallbackAction *cba, const SoPrimitiveVertex *v1, const SoPrimitiveVertex *v2, const SoPrimitiveVertex *v3) { static int flag = 0; if((vcnt < 999999) && (nvcnt < 999999)) { flag = 0; if(backface == 1) { const SbMatrix &mm = cba->getModelMatrix(); SbMatrix nm = mm.inverse().transpose(); SbVec3f vec1 = transformNormal(nm, v1->getNormal()); SbVec3f vec2 = transformNormal(nm, v2->getNormal()); SbVec3f vec3 = transformNormal(nm, v3->getNormal()); if((vec1[2] >= 0.0) || (vec2[2] >= 0.0) || (vec3[2] >= 0.0)) { gvec[vcnt++] = v1->getPoint(); nvec[nvcnt++] = v1->getNormal(); gvec[vcnt++] = v2->getPoint(); nvec[nvcnt++] = v2->getNormal(); gvec[vcnt++] = v3->getPoint(); nvec[nvcnt++] = v3->getNormal(); } } else { gvec[vcnt++] = v1->getPoint(); nvec[nvcnt++] = v1->getNormal(); gvec[vcnt++] = v2->getPoint(); nvec[nvcnt++] = v2->getNormal(); gvec[vcnt++] = v3->getPoint(); nvec[nvcnt++] = v3->getNormal(); } } else { if(flag == 0) { fprintf(stderr, "\n\nError: Too many triangles ( > 1000000) in a single shape\n"); fprintf(stderr, "further triangles in this shape will be ignored\n\n"); } flag = 1; } } SoCallbackAction::Response countMaterialCB(void *, SoCallbackAction *, const SoNode *) { static int cnt = 0; cnt++; fprintf(stderr, "\r shape nodes: %d", cnt); return(SoCallbackAction::CONTINUE); } void evalGraph(SoSeparator *root) { SoCallbackAction::Response addMaterialCB(void *, SoCallbackAction *, const SoNode *); // Set up callbacks to add to scene graph, then apply SoType shapeType = SoShape::getClassTypeId(); SoType lightType = SoLight::getClassTypeId(); SoType textureType = SoTexture2::getClassTypeId(); SoType cameraType = SoCamera::getClassTypeId(); SoCallbackAction ca; ca.addTriangleCallback(shapeType, addTriangleCB, NULL); ca.addPostCallback(shapeType, addMaterialCB, NULL); ca.addPreCallback(lightType, preLightCB, NULL); ca.addPreCallback(cameraType, preCameraCB, NULL); ca.addPreCallback(textureType, preTextureCB, NULL); ca.apply(root); fprintf(stderr, "\rdone \n"); } void countGraph(SoSeparator *root) { // Set up callbacks to add to scene graph, then apply SoType shapeType = SoShape::getClassTypeId(); SoCallbackAction ca; ca.addPreCallback(shapeType, countMaterialCB, NULL); ca.apply(root); printf("\n"); } void hunt_text(SoGroup *nd) { int loop; SoNode *child; for(loop = 0;loop < nd->getNumChildren();loop++) { child = nd->getChild(loop); if(child->isOfType(SoText2::getClassTypeId())) { SoText2 *text2 = (SoText2 *)child; SoText3 *text3 = new SoText3; text3->justification = text2->justification; text3->string = text2->string; text3->spacing = text2->spacing; text3->parts = SoText3::FRONT; nd->replaceChild(text2, text3); } else { if(child->isOfType(SoGroup::getClassTypeId())) { hunt_text((SoGroup *)child); } } } } void main(int argc, char **argv) { SoInput in; SoSeparator *root; int size_x, size_y; int loop; char *cp; fprintf(stderr, "iv2rib V0.11 (C) 1997 Mark Lasersohn - Cow House Productions\n"); if(argc > 1) { backface = 0; SoDB::init(); vcnt = 0; nvcnt = 0; size_x = 0; size_y = 0; loop = 1; while(loop < argc - 1) { if(strncmp(argv[loop], "-bmrt", 5) == 0) bmrt_flag = 1; else if(strncmp(argv[loop], "-b", 2) == 0) backface = 1; else if(strncmp(argv[loop], "-n", 2) == 0) normalate = 1; else if(strncmp(argv[loop], "-size", 5) == 0) { if(loop + 2 < argc) { loop++; if(atoi(argv[loop]) > 0) { size_x = atoi(argv[loop]); loop++; if(atoi(argv[loop]) > 0) { size_y = atoi(argv[loop]); } else { fprintf(stderr, "Error: expecting size arguments on command line\n"); exit(-1); } } else { fprintf(stderr, "Error: expecting size arguments on command line\n"); exit(-1); } } else { fprintf(stderr, "Error: expecting size arguments on command line\n"); exit(-1); } } else if(strncmp(argv[loop], "-bmrt", 5) == 0) bmrt_flag = 1; loop++; } if(! in.openFile(argv[loop])) { fprintf(stderr, "%s: Cannot open %s\n", argv[0], argv[loop]); exit(-1); } root = SoDB::readAll(&in); if (root == NULL) { fprintf(stderr, "%s: Problem reading data\n", argv[0]); exit(-1); } in.closeFile(); root->ref(); hunt_text((SoGroup *)root); countGraph(root); root->ref(); fprintf(stderr, "\nBuilding rib file\n"); cp = argv[loop]; while(*cp != '\0') { if(*cp == '.') *cp = '\0'; cp++; } printf("Display \"%s.tif\" \"file\" \"rgb\"\n", argv[loop]); if((size_x > 0) && (size_y > 0)) { printf("Format %d %d 1.0\n", size_x, size_y); } else { printf("Format 400 400 1.0\n"); } SoGetBoundingBoxAction bba(SbViewportRegion(0, 0)); bba.apply(root); SbBox3f box = bba.getBoundingBox(); box.getSize(bound_x, bound_y, bound_z); box.getBounds(bound_xmin, bound_ymin, bound_zmin, bound_xmax, bound_ymax, bound_zmax); evalGraph(root); printf("WorldEnd\n"); } else { fprintf(stderr, "syntax: iv2rib [-b][-n][-size x y][-bmrt] input_file.iv\n"); } } SoCallbackAction::Response addMaterialCB(void *, SoCallbackAction *cba, const SoNode *nd) { SbColor ambient; SbColor diffuse; SbColor specular; SbColor emission; float shininess; float transparency; float r, g, b; char geometry_file[256]; static int file_counter = 0; SbVec2f vec2; SbVec3f vec3; int loop; float vx1, vy1, vz1; float vx2, vy2, vz2; float vx3, vy3, vz3; float nx1, ny1, nz1; float nx2, ny2, nz2; float nx3, ny3, nz3; int flag; SbVec3f translation; SbRotation rotation; SbVec3f scale; SbRotation scale_orientation; SbVec2s size; int numComps; int texturing = 0; char node_name[1024]; int surf_index; int cnt; long int index1; long int index2; long int index3; long int nindex1; long int nindex2; long int nindex3; long int tindex1; long int tindex2; long int tindex3; float x, y, z; float xmin, ymin, zmin; float xmax, ymax, zmax; int normals; cba->getMaterial(ambient, diffuse, specular, emission, shininess, transparency); sprintf(geometry_file, "geo%04d", file_counter); fprintf(stderr, "\r (%d) ", file_counter); file_counter++; texture_index_count = cba->getNumTextureCoordinates(); node_name[0] = '\0'; strcpy(node_name, nd->getName().getString()); texturing = 0; if(cba->getTextureImage(size, numComps) != NULL) { texturing = 1; } flag = -1; for(loop = 0;loop < surf_cnt;loop++) { ambient.getValue(r, g, b); if((r == surf_ambient_r[loop]) && (g == surf_ambient_g[loop]) && (b == surf_ambient_b[loop])) { diffuse.getValue(r, g, b); if((r == surf_diffuse_r[loop]) && (g == surf_diffuse_g[loop]) && (b == surf_diffuse_b[loop])) { specular.getValue(r, g, b); if((r == surf_specular_r[loop]) && (g == surf_specular_g[loop]) && (b == surf_specular_b[loop])) { if(transparency == surf_transparency[loop]) { if(shininess == surf_shininess[loop]) { if(strlen(node_name) > 0) { printf("# %s \n", node_name); } flag = loop; surf_index = loop; } } } } } } if(flag == -1) { strcpy(surf_name[surf_cnt], geometry_file); surf_index = surf_cnt; ambient.getValue(r, g, b); surf_ambient_r[surf_cnt] = r; surf_ambient_g[surf_cnt] = g; surf_ambient_b[surf_cnt] = b; diffuse.getValue(r, g, b); surf_diffuse_r[surf_cnt] = r; surf_diffuse_g[surf_cnt] = g; surf_diffuse_b[surf_cnt] = b; specular.getValue(r, g, b); surf_specular_r[surf_cnt] = r; surf_specular_g[surf_cnt] = g; surf_specular_b[surf_cnt] = b; surf_transparency[surf_cnt] = transparency; surf_shininess[surf_cnt] = shininess; surf_cnt++; } if(nd->isOfType(SoIndexedTriangleStripSet::getClassTypeId())) { printf("AttributeBegin\n"); diffuse.getValue(r, g, b); printf("Color [%g %g %g]\n", r, g, b); printf("Opacity [%g %g %g]\n", 1.0 - transparency, 1.0 - transparency, 1.0 - transparency); printf("Surface \"paintedplastic\" "); specular.getValue(r, g, b); printf("\"Ks\" [%g] ", (r + b + g) / 3.0); diffuse.getValue(r, g, b); printf("\"Kd\" [%g] ", (r + b + g) / 3.0); ambient.getValue(r, g, b); printf("\"Ka\" [%g] ", (r + b + g) / 3.0); specular.getValue(r, g, b); printf("\"specularcolor\" [%g %g %g] ", r, g, b); if(texturing) { if(bmrt_flag == 1) { printf("\"texturename\" [\"%s.tif\"]\n", texture_filename); } else { printf("\"texturename\" [\"%s.tex\"]\n", texture_filename); } } else { printf("\n"); } SoIndexedTriangleStripSet *tri = (SoIndexedTriangleStripSet *)nd; const SbMatrix &mm = cba->getModelMatrix(); SbMatrix nm = mm.inverse().transpose(); const SbMatrix &vm = cba->getViewingMatrix(); if(tri->coordIndex.getNum() == tri->normalIndex.getNum()) normals = 1; else normals = 0; for(loop = 0;loop < tri->coordIndex.getNum() - 2;loop++) { index1 = tri->coordIndex[loop + 2]; index2 = tri->coordIndex[loop + 1]; index3 = tri->coordIndex[loop]; if(normals == 1) { nindex1 = tri->normalIndex[loop + 2]; nindex2 = tri->normalIndex[loop + 1]; nindex3 = tri->normalIndex[loop]; } if(texture_index_count > 0) { texturing = 1; if(cba->getTextureCoordinateBinding() == SoTextureCoordinateBinding::PER_VERTEX_INDEXED) { tindex1 = tri->textureCoordIndex[loop + 2]; tindex2 = tri->textureCoordIndex[loop + 1]; tindex3 = tri->textureCoordIndex[loop]; } else { tindex1 = index1; tindex2 = index2; tindex3 = index3; } } if((index1 != -1) && (index2 != -1) && (index3 != -1)) { vec3 = cba->getCoordinate3((int)index1); vec3 = transformPoint(mm, vec3); vec3 = transformPoint(vm, vec3); vec3.getValue(x, y, z); printf("Polygon \"P\" [ %g %g %g ", x, y, -z); vec3 = cba->getCoordinate3((int)index2); vec3 = transformPoint(mm, vec3); vec3 = transformPoint(vm, vec3); vec3.getValue(x, y, z); printf("%g %g %g ", x, y, -z); vec3 = cba->getCoordinate3((int)index3); vec3 = transformPoint(mm, vec3); vec3 = transformPoint(vm, vec3); vec3.getValue(x, y, z); printf("%g %g %g]\n", x, y, -z); if((normals == 1) && (normalate == 1)) { vec3 = cba->getNormal((int)nindex1); vec3 = transformNormal(nm, vec3); vec3.getValue(x, y, z); printf(" \"N\" [%g %g %g ", x, y, z); vec3 = cba->getNormal((int)nindex2); vec3 = transformNormal(nm, vec3); vec3.getValue(x, y, z); printf("%g %g %g ", x, y, z); vec3 = cba->getNormal((int)nindex3); vec3 = transformNormal(nm, vec3); vec3.getValue(x, y, z); printf("%g %g %g]\n", x, y, z); } if(texture_index_count > 0) { vec2 = cba->getTextureCoordinate2((int)tindex1); vec2.getValue(x, y); printf("\"st\" [%g %g ", x, y); vec2 = cba->getTextureCoordinate2((int)tindex2); vec2.getValue(x, y); printf("%g %g ", x, y); vec2 = cba->getTextureCoordinate2((int)tindex3); vec2.getValue(x, y); printf("%g %g]\n", x, y); } } } printf("AttributeEnd\n"); } else { SoNode *node = (SoNode *)nd; SoGetBoundingBoxAction bba(SbViewportRegion(0, 0)); bba.apply(node); SbBox3f box = bba.getBoundingBox(); box.getBounds(xmin, ymin, zmin, xmax, ymax, zmax); box.getSize(x, y, z); const SbMatrix &mm = cba->getModelMatrix(); mm.getTransform(translation, rotation, scale, scale_orientation); x *= scale[0]; y *= scale[1]; z *= scale[2]; if(vcnt == 0) { fprintf(stderr, "\n\nError: Unsupported shape type - probably 2D (Point, Line, or Text2) node\n"); fprintf(stderr, "Creating a tiny sphere to keep Rayshade from complaining\n"); printf("/* Error: Unsupported shape type - probably 2D (Point, Line, or Text2) node */\n"); printf("/* Creating a tiny sphere to keep Rayshade from complaining */\n"); printf("sphere 0.00001 0.0 0.0 0.0\n"); } const SbMatrix &vm = cba->getViewingMatrix(); if(vcnt != 0) { cnt = 0; SbMatrix nm = mm.inverse().transpose(); for(loop = 0;loop < vcnt;loop++) { gvec2[loop] = transformPoint(mm, gvec[loop]); gvec2[loop] = transformPoint(vm, gvec2[loop]); nvec2[loop] = nvec[loop]; } for(loop = 0;loop < vcnt;loop += 3) { vx1 = gvec2[loop][0]; vy1 = gvec2[loop][1]; vz1 = gvec2[loop][2]; vx2 = gvec2[loop + 1][0]; vy2 = gvec2[loop + 1][1]; vz2 = gvec2[loop + 1][2]; vx3 = gvec2[loop + 2][0]; vy3 = gvec2[loop + 2][1]; vz3 = gvec2[loop + 2][2]; nx1 = nvec2[loop][0]; ny1 = nvec2[loop][1]; nz1 = nvec2[loop][2]; nx2 = nvec2[loop + 1][0]; ny2 = nvec2[loop + 1][1]; nz2 = nvec2[loop + 1][2]; nx3 = nvec2[loop + 2][0]; ny3 = nvec2[loop + 2][1]; nz3 = nvec2[loop + 2][2]; if(((vx1 == vx2) && (vx1 == vx3) && (vy1 == vy2) && (vy1 == vy3)) || ((vx1 == vx2) && (vx1 == vx3) && (vz1 == vz2) && (vz1 == vz3)) || ((vy1 == vy2) && (vy1 == vy3) && (vz1 == vz2) && (vz1 == vz3))) { } else { if(((vx1 == vx2) && (vy1 == vy2) && (vz1 == vz2)) || ((vx1 == vx3) && (vy1 == vy3) && (vz1 == vz3)) || ((vx2 == vx3) && (vy2 == vy3) && (vz2 == vz3))) { } else { cnt += 3; } } } if(cnt < vcnt) { fprintf(stderr, "\nWarning: Mesh contains illegal triangles\n"); } if(cnt > 0) { printf("AttributeBegin\n"); diffuse.getValue(r, g, b); printf("Color [%g %g %g]\n", r, g, b); printf("Opacity [%g %g %g]\n", 1.0 - transparency, 1.0 - transparency, 1.0 - transparency); printf("Surface \"paintedplastic\" "); specular.getValue(r, g, b); printf("\"Ks\" [%g] ", (r + b + g) / 3.0); diffuse.getValue(r, g, b); printf("\"Kd\" [%g] ", (r + b + g) / 3.0); ambient.getValue(r, g, b); printf("\"Ka\" [%g] ", (r + b + g) / 3.0); specular.getValue(r, g, b); printf("\"specularcolor\" [%g %g %g] ", r, g, b); if(texturing) { if(bmrt_flag == 1) { printf("\"texturename\" [\"%s.tif\"]\n", texture_filename); } else { printf("\"texturename\" [\"%s.tex\"]\n", texture_filename); } } else { printf("\n"); } for(loop = 0;loop < vcnt;loop += 3) { vx1 = gvec2[loop][0]; vy1 = gvec2[loop][1]; vz1 = gvec2[loop][2] * -1.0; vx2 = gvec2[loop + 1][0]; vy2 = gvec2[loop + 1][1]; vz2 = gvec2[loop + 1][2] * -1.0; vx3 = gvec2[loop + 2][0]; vy3 = gvec2[loop + 2][1]; vz3 = gvec2[loop + 2][2] * -1.0; nx1 = nvec2[loop][0]; ny1 = nvec2[loop][1]; nz1 = nvec2[loop][2] * -1.0; nx2 = nvec2[loop + 1][0]; ny2 = nvec2[loop + 1][1]; nz2 = nvec2[loop + 1][2] * -1.0; nx3 = nvec2[loop + 2][0]; ny3 = nvec2[loop + 2][1]; nz3 = nvec2[loop + 2][2] * -1.0; if(normalate == 1) { printf("Polygon \"P\" [ %g %g %g %g %g %g %g %g %g ]\"N\" [%g %g %g %g %g %g %g %g %g]\n" , vx1, vy1, vz1, vx2, vy2, vz2 , vx3, vy3, vz3, nx1, ny1, nz1 , nx2, ny2, nz2, nx3, ny3, nz3); } else { printf("Polygon \"P\" [ %g %g %g %g %g %g %g %g %g ]\n" , vx1, vy1, vz1, vx2, vy2, vz2 , vx3, vy3, vz3); } } printf("AttributeEnd\n"); } else { fprintf(stderr, "\nError: Mesh contained no legal triangles - omitted\n"); } } else { fprintf(stderr, "\nError: Unsupported shape type - probably 2D (Point, Line, or Text2) node\n"); printf("/* Error: Unsupported shape type - probably 2D (Point, Line, or Text2) node */\n"); } } vcnt = 0; nvcnt = 0; return(SoCallbackAction::CONTINUE); }