in layer1/Ray.cpp [1251:1640]
void RayRenderVRML2(CRay * I, int width, int height,
char **vla_ptr, float front, float back,
float fov, float angle, float z_corr)
{
/*
From: pymol-users-admin@lists.sourceforge.net on behalf of Chris Want
Sent: Tuesday, February 07, 2006 1:47 PM
To: pymol-users@lists.sourceforge.net
Subject: [PyMOL] VRML patch
Hi Warren,
I took your advice and modified the RayRenderVRML2() function to
support triangles. I also threw out the sphere code that was already
there and rewrote it (the code there was for VRML1, not
VRML2). While I was at it, I also implemented export for cylinders
and sausages.
The code in the attached patch (diff-ed against cvs, and tested with
two VRML2 readers) can be regarded as being in the public domain.
Regards,
Chris
cwant_at_ualberta.ca
*/
char *vla = *vla_ptr;
ov_size cc = 0; /* character count */
OrthoLineType buffer;
float mid[3]; /*, wid[3]; */
float h_fov = cPI * (fov * width) / (180 * height);
int identity = (SettingGetGlobal_i(I->G, cSetting_geometry_export_mode) == 1);
RayExpandPrimitives(I);
RayTransformFirst(I, 0, identity);
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]);
*/
copy3f(I->Pos, mid);
UtilConcatVLA(&vla, &cc, "#VRML V2.0 utf8\n" /* WLD: most VRML2 readers req. utf8 */
"\n");
if(!identity) {
sprintf(buffer, "Viewpoint {\n" " position 0 0 %6.8f\n" " orientation 1 0 0 0\n" " description \"Z view\"\n" " fieldOfView %8.6f\n" /* WLD: use correct FOV */
"}\n"
/* WLD: only write the viewpoint which matches PyMOL
"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" */ ,
-z_corr, /* *0.96646 for some reason, PyMOL and C4D cameras differ by about 3.5% ... */
h_fov
/*(wid[2] + wid[1]),
(wid[0] + wid[1]),
(wid[1] + wid[2]) */
);
UtilConcatVLA(&vla, &cc, buffer);
}
if(!identity) {
float light[3];
auto lightv = SettingGet<const float*>(I->G, cSetting_light);
copy3f(lightv, light);
normalize3f(light);
sprintf(buffer,
"DirectionalLight {\n"
" direction %8.6f %8.6f %8.3f\n" "}\n", light[0], light[1], light[2]);
UtilConcatVLA(&vla, &cc, buffer);
}
UtilConcatVLA(&vla, &cc,
"NavigationInfo {\n" " headlight TRUE\n" " type \"EXAMINE\"\n" "}\n");
{
int a, b;
CPrimitive *prim;
float *vert;
int mesh_obj = false, mesh_start = 0;
CBasis *base = I->Basis + 1;
for(a = 0; a < I->NPrimitive; a++) {
prim = I->Primitive + a;
vert = base->Vertex + 3 * (prim->vert);
if(prim->type == cPrimTriangle) {
if(!mesh_obj) {
/* start mesh */
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, " ]\n" " }\n" " coordIndex [\n");
for(b = mesh_start; b < a; b++) {
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;
}
/* output vertex colors */
UtilConcatVLA(&vla, &cc,
" ]\n"
" colorPerVertex TRUE\n" " color Color {\n" " color [\n");
for(b = mesh_start; b < a; b++) {
cprim = I->Primitive + b;
sprintf(buffer,
"%6.4f %6.4f %6.4f,\n"
"%6.4f %6.4f %6.4f,\n"
"%6.4f %6.4f %6.4f,\n",
cprim->c1[0], cprim->c1[1], cprim->c1[2],
cprim->c2[0], cprim->c2[1], cprim->c2[2],
cprim->c3[0], cprim->c3[1], cprim->c3[2]);
UtilConcatVLA(&vla, &cc, buffer);
}
/* output vertex normals */
UtilConcatVLA(&vla, &cc,
" ] } \n"
" normalPerVertex TRUE\n" " normal Normal {\n" " vector [\n");
for(b = mesh_start; b < a; b++) {
cprim = I->Primitive + b;
{
float *norm = base->Normal + 3 * base->Vert2Normal[cprim->vert];
sprintf(buffer, "%6.4f %6.4f %6.4f,\n" "%6.4f %6.4f %6.4f,\n" "%6.4f %6.4f %6.4f,\n", norm[3], norm[4], norm[5], /* transformed cprim->n1 */
norm[6], norm[7], norm[8], /* transformed cprim->n2 */
norm[9], norm[10], norm[11]); /* transformed cprim->n3 */
UtilConcatVLA(&vla, &cc, buffer);
}
}
UtilConcatVLA(&vla, &cc, " ] }\n" " normalIndex [ \n");
tri = 0;
for(b = mesh_start; b < a; b++) {
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;
}
/* close mesh */
UtilConcatVLA(&vla, &cc, " ] \n" " }\n" "}\n");
mesh_obj = false;
}
switch (prim->type) {
case cPrimSphere:
sprintf(buffer,
"Transform {\n"
" translation %8.6f %8.6f %8.6f\n"
" children Shape {\n"
" geometry Sphere { radius %8.6f }\n"
" appearance Appearance {\n"
" material Material { diffuseColor %6.4f %6.4f %6.4f \n"
" specularColor 0.8 0.8 0.8 \n"
" shininess 0.8 }\n"
" }\n"
" }\n"
"}\n",
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);
break;
case cPrimCone:
/* TO DO */
break;
case cPrimCylinder:
case cPrimSausage:
{
float *d, vert2[3], axis[3], angle;
OrthoLineType geometry;
/* find the axis and angle that will rotate the y axis onto
* the direction of the length of the cylinder
*/
d = base->Normal + 3 * base->Vert2Normal[prim->vert];
if((d[0] * d[0] + d[2] * d[2]) < 0.000001) {
/* parallel with y */
axis[0] = 1.0;
axis[1] = 0.0;
axis[2] = 0.0;
if(d[1] > 0) {
angle = 0.0;
} else {
angle = cPI;
}
} else {
axis[0] = d[2];
axis[1] = 0.0;
axis[2] = -d[0];
normalize3f(axis);
angle = d[1];
if(angle > 1.0)
angle = 1.0;
else if(angle < -1.0)
angle = -1.0;
angle = acos(angle);
}
/* vrml cylinders have origin in middle, not tip, that is why we
* use prim->l1/2
*/
scale3f(d, prim->l1 / 2, vert2);
add3f(vert, vert2, vert2);
if(prim->type == cPrimSausage) {
OrthoLineType geom_add;
sprintf(geometry,
" Shape {\n"
" geometry Cylinder {\n"
" radius %8.6f\n"
" height %8.6f\n"
" bottom FALSE\n"
" top FALSE\n"
" }\n"
" appearance Appearance {\n"
" material Material { diffuseColor %6.4f %6.4f %6.4f \n"
" specularColor 0.8 0.8 0.8 \n"
" shininess 0.8 }\n"
" }\n",
prim->r1, prim->l1,
(prim->c1[0] + prim->c2[0]) / 2,
(prim->c1[1] + prim->c2[1]) / 2, (prim->c1[2] + prim->c2[2]) / 2);
/* WLD: format string split to comply with ISO C89 standards */
sprintf(geom_add,
" }\n"
" Transform {\n"
" translation 0.0 %8.6f 0.0\n"
" children Shape {\n"
" geometry Sphere { radius %8.6f }\n"
" appearance Appearance {\n"
" material Material { diffuseColor %6.4f %6.4f %6.4f \n"
" specularColor 0.8 0.8 0.8 \n"
" shininess 0.8 }\n"
" }\n"
" }\n"
" }\n", prim->l1 / 2, prim->r1, prim->c1[0], prim->c1[1], prim->c1[2]
);
strcat(geometry, geom_add);
/* WLD: format string split to comply with ISO C89 standards */
sprintf(geom_add,
" Transform {\n"
" translation 0.0 %8.6f 0.0\n"
" children Shape {\n"
" geometry Sphere { radius %8.6f }\n"
" appearance Appearance {\n"
" material Material { diffuseColor %6.4f %6.4f %6.4f \n"
" specularColor 0.8 0.8 0.8 \n"
" shininess 0.8 }\n"
" }\n"
" }\n"
" }\n",
-prim->l1 / 2, prim->r1, prim->c2[0], prim->c2[1], prim->c2[2]);
strcat(geometry, geom_add);
} else {
sprintf(geometry,
" Shape {\n"
" geometry Cylinder {\n"
" radius %8.6f\n"
" height %8.6f\n"
" }\n"
" appearance Appearance {\n"
" material Material { diffuseColor %6.4f %6.4f %6.4f \n"
" specularColor 0.8 0.8 0.8 \n"
" shininess 0.8 }\n"
" }\n"
" }\n",
prim->r1, prim->l1,
(prim->c1[0] + prim->c2[0]) / 2,
(prim->c1[1] + prim->c2[1]) / 2, (prim->c1[2] + prim->c2[2]) / 2);
}
sprintf(buffer,
"Transform {\n"
" translation %8.6f %8.6f %8.6f\n"
" rotation %8.6f %8.6f %8.6f %8.6f\n"
" children [\n"
"%s"
" ]\n"
"}\n",
vert2[0] - mid[0],
vert2[1] - mid[1],
vert2[2] - mid[2], axis[0], axis[1], axis[2], angle, geometry);
UtilConcatVLA(&vla, &cc, buffer);
}
break;
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] - 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) {
CBasis *base = I->Basis + 1;
CPrimitive *cprim;
int tri = 0;
/* output connectivity */
UtilConcatVLA(&vla, &cc, " ]\n" " }\n" " coordIndex [\n");
for(b = mesh_start; b < a; b++) {
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;
}
/* output vertex colors */
UtilConcatVLA(&vla, &cc,
" ]\n" " colorPerVertex TRUE\n" " color Color {\n" " color [\n");
for(b = mesh_start; b < a; b++) {
cprim = I->Primitive + b;
sprintf(buffer,
"%6.4f %6.4f %6.4f,\n"
"%6.4f %6.4f %6.4f,\n"
"%6.4f %6.4f %6.4f,\n",
cprim->c1[0], cprim->c1[1], cprim->c1[2],
cprim->c2[0], cprim->c2[1], cprim->c2[2],
cprim->c3[0], cprim->c3[1], cprim->c3[2]);
UtilConcatVLA(&vla, &cc, buffer);
}
/* output vertex normals */
UtilConcatVLA(&vla, &cc,
" ] } \n"
" normalPerVertex TRUE\n" " normal Normal {\n" " vector [\n");
for(b = mesh_start; b < a; b++) {
cprim = I->Primitive + b;
{
float *norm = base->Normal + 3 * base->Vert2Normal[cprim->vert];
sprintf(buffer, "%6.4f %6.4f %6.4f,\n" "%6.4f %6.4f %6.4f,\n" "%6.4f %6.4f %6.4f,\n", norm[3], norm[4], norm[5], /* transformed cprim->n1 */
norm[6], norm[7], norm[8], /* transformed cprim->n2 */
norm[9], norm[10], norm[11]); /* transformed cprim->n3 */
UtilConcatVLA(&vla, &cc, buffer);
}
}
UtilConcatVLA(&vla, &cc, " ] }\n" " normalIndex [ \n");
tri = 0;
for(b = mesh_start; b < a; b++) {
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;
}
/* close mesh */
UtilConcatVLA(&vla, &cc, " ] \n" " }\n" "}\n");
mesh_obj = false;
}
}
*vla_ptr = vla;
}