Hi Warren,
I've tried sending this patch directly to your email address a couple of times in the last month, but I never heard back from you -- maybe your spam filter doesn't like the attachment? (Hehe, either that or you find me annoying.) Anyways, I'll try sending it indirectly through the mailing list. Again, the code in the patch should be regarded as being in the public domain. The attached patch centers the objects in the coordinate system, sets up three orthogonal viewpoints, reverses non-agreeing triangle normals (needed for cartoon objects, since the triangles tend to alternate normal direction -- probably derived from triangle strips), and has nicer materials under some viewers (not perfect, but I'm hoping some other pymol users will have suggestions). I don't currently export vertex normals, but I may need to do that so that surfaces have smooth shading in the VRML viewers -- something to play with for later. One thing that I should note, exporting the surface geometry at the triangle level might work well when exporting to a renderer, but isn't the best way to do export for VRML or any other scene description format. It would be much better to export at the object level, so that a list of vertices can be output, then the triangles are exported as indices into the list of vertices -- this would lead to smaller files, and also the topology of the surface is preserved making automatic vertex normal interpolation possible (which is not possible when exporting a collection of unrelated triangles). I have no idea if it is possible to access such information from within pymol though -- well, it is possible to have access to this data when a surface is first created through the RepSurface structure, but I think that data is thrown out after the surface is created. Regards, Chris -- ____________________________________________________________________ ( Chris Want ) ( Research Computing Support ) ( Academic Information and Communication Technologies (AICT) ) ( University of Alberta ) ( Tel: 1-780-492-9418 ) --------------------------------------------------------------------
Index: layer1/Ray.c =================================================================== RCS file: /cvsroot/pymol/pymol/layer1/Ray.c,v retrieving revision 1.200 diff -u -p -r1.200 Ray.c --- layer1/Ray.c 16 Feb 2006 18:44:53 -0000 1.200 +++ layer1/Ray.c 6 Mar 2006 16:01:17 -0000 @@ -936,6 +936,21 @@ void RayRenderVRML1(CRay *I,int width,in } #endif + +static int TriangleReverse(CPrimitive *p) +{ + float s1[3], s2[3], n0[3]; + + subtract3f(p->v1,p->v2,s1); + subtract3f(p->v3,p->v2,s2); + cross_product3f(s1,s2,n0); + + if (dot_product3f(p->n0,n0) < 0) + return 0; + else + return 1; +} + void RayRenderVRML2(CRay *I,int width,int height, char **vla_ptr,float front,float back, float fov, float angle,float z_corr) @@ -969,13 +984,47 @@ void RayRenderVRML2(CRay *I,int width,in char *vla = *vla_ptr; int cc = 0; /* character count */ OrthoLineType buffer; + float mid[3], wid[3]; RayExpandPrimitives(I); RayTransformFirst(I,0); - strcpy(buffer,"#VRML V2.0 ascii\n\n"); + RayComputeBox(I); + mid[0] = (I->max_box[0] + I->min_box[0]) / 2.0; + mid[1] = (I->max_box[1] + I->min_box[1]) / 2.0; + mid[2] = (I->max_box[2] + I->min_box[2]) / 2.0; + wid[0] = (I->max_box[0] - I->min_box[0]); + wid[1] = (I->max_box[1] - I->min_box[1]); + wid[2] = (I->max_box[2] - I->min_box[2]); + + UtilConcatVLA(&vla,&cc, + "#VRML V2.0 ascii\n" + "\n"); + sprintf(buffer, + "Viewpoint {\n" + " position 0 0 %6.8f\n" + " orientation 1 0 0 0\n" + " description \"Z view\"\n" + "}\n" + "Viewpoint {\n" + " position %6.8f 0 0\n" + " orientation 0 1 0 1.570796\n" + " description \"X view\"\n" + "}\n" + "Viewpoint {\n" + " position 0 %6.8f 0\n" + " orientation 0 -0.707106 -0.7071061 3.141592\n" + " description \"Y view\"\n" + "}\n", + (wid[2] + wid[1]), + (wid[0] + wid[1]), + (wid[1] + wid[2])); UtilConcatVLA(&vla,&cc,buffer); - + UtilConcatVLA(&vla,&cc, + "NavigationInfo {\n" + " headlight TRUE\n" + " type \"EXAMINE\"\n" + "}\n"); { int a, b; CPrimitive *prim; @@ -994,12 +1043,16 @@ void RayRenderVRML2(CRay *I,int width,in mesh_start = a; UtilConcatVLA(&vla,&cc, "Shape {\n" + " appearance Appearance {\n" + " material Material { diffuseColor 1.0 1.0 1.0 }\n" + " }\n" " geometry IndexedFaceSet {\n" " coord Coordinate {\n" " point [\n"); mesh_obj=true; } } else if(mesh_obj) { + CPrimitive *cprim; int tri = 0; /* output connectivity */ UtilConcatVLA(&vla,&cc, @@ -1007,7 +1060,11 @@ void RayRenderVRML2(CRay *I,int width,in " }\n" " coordIndex [\n"); for(b=mesh_start;b<a;b++) { - sprintf(buffer,"%d %d %d -1,\n", tri, tri+1, tri+2); + cprim = I->Primitive+b; + if (TriangleReverse(cprim)) + sprintf(buffer,"%d %d %d -1,\n", tri, tri+2, tri+1); + else + sprintf(buffer,"%d %d %d -1,\n", tri, tri+1, tri+2); UtilConcatVLA(&vla,&cc,buffer); tri+=3; } @@ -1019,7 +1076,6 @@ void RayRenderVRML2(CRay *I,int width,in " color Color {\n" " color [\n"); for(b=mesh_start;b<a;b++) { - CPrimitive *cprim; cprim = I->Primitive+b; sprintf(buffer, "%6.4f %6.4f %6.4f,\n" @@ -1052,7 +1108,9 @@ void RayRenderVRML2(CRay *I,int width,in " }\n" " }\n" "}\n", - vert[0],vert[1],vert[2]-z_corr, + vert[0]-mid[0], + vert[1]-mid[1], + vert[2]-mid[2], prim->r1, prim->c1[0],prim->c1[1],prim->c1[2]); UtilConcatVLA(&vla,&cc,buffer); @@ -1157,7 +1215,9 @@ void RayRenderVRML2(CRay *I,int width,in "%s" " ]\n" "}\n", - vert2[0], vert2[1], vert2[2]-z_corr, + vert2[0]-mid[0], + vert2[1]-mid[1], + vert2[2]-mid[2], axis[0], axis[1], axis[2], angle, geometry); UtilConcatVLA(&vla,&cc,buffer); @@ -1166,16 +1226,19 @@ void RayRenderVRML2(CRay *I,int width,in case cPrimTriangle: /* output coords. connectivity and vertex colors handled above/below */ sprintf(buffer, - "%8.6f %8.6f %8.6f,\n %8.6f %8.6f %8.6f,\n %8.6f %8.6f %8.6f,\n", - vert[0], vert[1], vert[2]-z_corr, - vert[3], vert[4], vert[5]-z_corr, - vert[6], vert[7], vert[8]-z_corr); + "%8.6f %8.6f %8.6f,\n" + "%8.6f %8.6f %8.6f,\n" + "%8.6f %8.6f %8.6f,\n", + vert[0] - mid[0], vert[1] - mid[1], vert[2] - mid[2], + vert[3] - mid[0], vert[4] - mid[1], vert[5] - mid[2], + vert[6] - mid[0], vert[7] - mid[1], vert[8] - mid[2]); UtilConcatVLA(&vla,&cc,buffer); break; } } if(mesh_obj) { + CPrimitive *cprim; int tri = 0; /* output connectivity */ UtilConcatVLA(&vla,&cc, @@ -1183,8 +1246,11 @@ void RayRenderVRML2(CRay *I,int width,in " }\n" " coordIndex [\n"); for(b=mesh_start;b<a;b++) { - sprintf(buffer, - "%d %d %d -1,\n", tri, tri+1, tri+2); + cprim = I->Primitive+b; + if (TriangleReverse(cprim)) + sprintf(buffer,"%d %d %d -1,\n", tri, tri+2, tri+1); + else + sprintf(buffer,"%d %d %d -1,\n", tri, tri+1, tri+2); UtilConcatVLA(&vla,&cc,buffer); tri+=3; } @@ -1196,7 +1262,6 @@ void RayRenderVRML2(CRay *I,int width,in " color Color {\n" " color [\n"); for(b=mesh_start;b<a;b++) { - CPrimitive *cprim; cprim = I->Primitive+b; sprintf(buffer, "%6.4f %6.4f %6.4f,\n"