Skip to content

Commit

Permalink
Merge pull request #116 from tpaviot/review/x3d-improvements
Browse files Browse the repository at this point in the history
Review/x3d improvements
  • Loading branch information
tpaviot committed Jul 3, 2015
2 parents de469e3 + 64c92c6 commit d6a0e1b
Show file tree
Hide file tree
Showing 12 changed files with 23,400 additions and 1,078 deletions.
2 changes: 1 addition & 1 deletion examples/core_simple_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeEdge
from OCC.BRepMesh import brepmesh_Mesh
from OCC.TopExp import TopExp_Explorer
from OCC.TopoDS import TopoDS_Compound, topods_Face
from OCC.TopoDS import TopoDS_Compound, topods_Face, topods_Edge
from OCC.TopAbs import TopAbs_FACE
from OCC.TopLoc import TopLoc_Location
from OCC.gp import gp_Pnt
Expand Down
83 changes: 83 additions & 0 deletions examples/core_webgl_x3dom_shader_demo1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python

##Copyright 2009-2014 Thomas Paviot ([email protected])
##
##This file is part of pythonOCC.
##
##pythonOCC is free software: you can redistribute it and/or modify
##it under the terms of the GNU Lesser General Public License as published by
##the Free Software Foundation, either version 3 of the License, or
##(at your option) any later version.
##
##pythonOCC is distributed in the hope that it will be useful,
##but WITHOUT ANY WARRANTY; without even the implied warranty of
##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
##GNU Lesser General Public License for more details.
##
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>.

from OCC.Display.WebGl import x3dom_renderer
from OCC.BRepPrimAPI import BRepPrimAPI_MakeTorus

# loads brep shape
torus_shp = BRepPrimAPI_MakeTorus(40., 10.).Shape()

# shader
vertex_shader = '''
attribute vec3 position;
attribute vec3 normal;
uniform mat4 modelViewMatrix;
uniform mat4 modelViewMatrixInverse;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 normalMatrix;
varying vec3 fragNormal;
varying vec3 fragEyeVector;
void main()
{
fragEyeVector = -(modelViewMatrix * vec4(position, 0.0)).xyz;
fragNormal = (normalMatrix * vec4(normal, 0.0)).xyz;
gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);
}
'''

fragment_shader = '''
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform vec3 light0_Direction;
varying vec3 fragNormal;
varying vec3 fragEyeVector;
vec3 base = vec3(0.3);
vec3 cool = vec3(0.0, 0.0, 0.5);
vec3 warm = vec3(1.0, 0.85, 0.0);
//application parameters
uniform float alphaParam;
uniform float betaParam;
void main()
{
vec3 normal = normalize(fragNormal);
vec3 eye = normalize(fragEyeVector);
vec3 rVec = reflect(eye, normal);
float spec = pow(max(0.0, dot(light0_Direction, rVec)), 27.0);
float diff = dot(-light0_Direction, normal);
diff = (1.0 + diff) * 0.5;
vec3 col = diff * (cool + alphaParam * base) + (1.0 - diff) * (warm + betaParam * base);
col += vec3(spec);
gl_FragColor = vec4(col, 1.0);
}
'''

# render cylinder head in x3dom
my_renderer = x3dom_renderer.X3DomRenderer()
my_renderer.DisplayShape(torus_shp, vertex_shader, fragment_shader)
28 changes: 28 additions & 0 deletions examples/core_webgl_x3dom_splitted_faces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python

##Copyright 2009-2014 Thomas Paviot ([email protected])
##
##This file is part of pythonOCC.
##
##pythonOCC is free software: you can redistribute it and/or modify
##it under the terms of the GNU Lesser General Public License as published by
##the Free Software Foundation, either version 3 of the License, or
##(at your option) any later version.
##
##pythonOCC is distributed in the hope that it will be useful,
##but WITHOUT ANY WARRANTY; without even the implied warranty of
##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
##GNU Lesser General Public License for more details.
##
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>.

from OCC.Display.WebGl import x3dom_renderer
from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox

box_shp = BRepPrimAPI_MakeBox(10., 20., 30.).Shape()

# render cylinder head in x3dom
my_renderer = x3dom_renderer.X3DomRenderer()
# display with one esh (Shape node) per face
my_renderer.DisplayShape(box_shp, map_faces_to_mesh=True)
152 changes: 82 additions & 70 deletions src/Visualization/Tesselator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

//---------------------------------------------------------------------------
#include "Tesselator.h"
#include <sstream>
//---------------------------------------------------------------------------
#include <TopExp_Explorer.hxx>
#include <Bnd_Box.hxx>
Expand Down Expand Up @@ -224,7 +225,7 @@ void Tesselator::TesselateWithUVCoords()

gp_Vec2d theCoord_p;
gp_Pnt2d d_coord;
cout << "Tesselate with UV coords\n";

//Triangulate
BRepMesh::Mesh(myShape, myDeviation);

Expand Down Expand Up @@ -342,90 +343,101 @@ void Tesselator::ComputeDefaultDeviation()
myDeviation = adeviation;
}

void Tesselator::ExportShapeToX3D(char * filename, int diffR, int diffG, int diffB)
std::string Tesselator::ExportShapeToX3DIndexedFaceSet()
{
ofstream X3Dfile;
int *vertices_idx = new int[3];
int *texcoords_idx = new int[3];
int *normals_idx = new int[3];
X3Dfile.open (filename);
// write header
X3Dfile << "<?xml version='1.0' encoding='UTF-8'?>" ;
X3Dfile << "<!DOCTYPE X3D PUBLIC 'ISO//Web3D//DTD X3D 3.1//EN' 'http://www.web3d.org/specifications/x3d-3.1.dtd'>";
X3Dfile << "<X3D>";
X3Dfile << "<Head>";
X3Dfile << "<meta name='generator' content='pythonOCC, http://www.pythonocc.org'/>";
X3Dfile << "</Head>";
X3Dfile << "<Scene><Shape><Appearance><Material DEF='Shape_Mat' diffuseColor='0.65 0.65 0.65' ";
X3Dfile << "shininess='0.9' specularColor='1 1 1'></Material></Appearance>";
// export faces indices
X3Dfile << "<IndexedFaceSet coordIndex='";
std::stringstream str1;
int *vertices_idx = new int[3];
int *texcoords_idx = new int[3];
int *normals_idx = new int[3];

str1 << "<IndexedFaceSet coordIndex='";
for (int i=0;i<tot_triangle_count;i++) {
ObjGetTriangle(i, vertices_idx, texcoords_idx, normals_idx);
// vertex indices
X3Dfile << i*3 << " " << 1+i*3 << " " << 2+i*3 << " -1 ";
str1 << i*3 << " " << 1+i*3 << " " << 2+i*3 << " -1\n";
}
X3Dfile << "' solid='false'>";
str1 << "' solid='false'>\n";
// write points coordinates
X3Dfile << "<Coordinate point='";
str1 << "<Coordinate point='";
for (int i=0;i<tot_triangle_count;i++) {
ObjGetTriangle(i, vertices_idx, texcoords_idx, normals_idx);
X3Dfile <<locVertexcoord[vertices_idx[0]]<< " " <<locVertexcoord[vertices_idx[0]+1]<<" "
<< locVertexcoord[vertices_idx[0]+2]<<" ";
str1 <<locVertexcoord[vertices_idx[0]]<< " " <<locVertexcoord[vertices_idx[0]+1]<<" "
<< locVertexcoord[vertices_idx[0]+2]<<"\n";
// Second vertex
X3Dfile <<locVertexcoord[vertices_idx[1]]<<" "<<locVertexcoord[vertices_idx[1]+1]<<" "
<< locVertexcoord[vertices_idx[1]+2]<<" ";
str1 <<locVertexcoord[vertices_idx[1]]<<" "<<locVertexcoord[vertices_idx[1]+1]<<" "
<< locVertexcoord[vertices_idx[1]+2]<<"\n";
// Third vertex
X3Dfile << locVertexcoord[vertices_idx[2]]<<" "<<locVertexcoord[vertices_idx[2]+1]<<" "
<< locVertexcoord[vertices_idx[2]+2]<<" ";
str1 << locVertexcoord[vertices_idx[2]]<<" "<<locVertexcoord[vertices_idx[2]+1]<<" "
<< locVertexcoord[vertices_idx[2]+2]<<"\n";
}
X3Dfile << "' containerField='coord'></Coordinate>";
str1 << "' containerField='coord'></Coordinate>\n";
// write normals
X3Dfile << "<Normal vector='";
str1 << "<Normal vector='";
for (int i=0;i<tot_triangle_count;i++) {
ObjGetTriangle(i, vertices_idx, texcoords_idx, normals_idx);
// First normal
X3Dfile << locNormalcoord[normals_idx[0]]<<" "<<locNormalcoord[normals_idx[0]+1]<<" "
<< locNormalcoord[normals_idx[0]+2]<<" ";
str1 << locNormalcoord[normals_idx[0]]<<" "<<locNormalcoord[normals_idx[0]+1]<<" "
<< locNormalcoord[normals_idx[0]+2]<<"\n";
// Second normal
X3Dfile << locNormalcoord[normals_idx[1]]<<" "<<locNormalcoord[normals_idx[1]+1]<<" "
<< locNormalcoord[normals_idx[1]+2]<<" ";
str1 << locNormalcoord[normals_idx[1]]<<" "<<locNormalcoord[normals_idx[1]+1]<<" "
<< locNormalcoord[normals_idx[1]+2]<<"\n";
// Third normal
X3Dfile << locNormalcoord[normals_idx[2]]<<" "<<locNormalcoord[normals_idx[2]+1]<<" "
<< locNormalcoord[normals_idx[2]+2] << " ";
str1 << locNormalcoord[normals_idx[2]]<<" "<<locNormalcoord[normals_idx[2]+1]<<" "
<< locNormalcoord[normals_idx[2]+2] << "\n";
}
X3Dfile << "' containerField='normal'></Normal>";
str1 << "' containerField='normal'></Normal>\n";
// close all markups
X3Dfile << "</IndexedFaceSet></Shape></Scene></X3D>\n";
X3Dfile.close();
str1 << "</IndexedFaceSet>\n";

delete [] vertices_idx;
delete [] texcoords_idx;
delete [] normals_idx;

return str1.str();
}

void Tesselator::ExportShapeToX3D(char * filename, int diffR, int diffG, int diffB)
{
ofstream X3Dfile;
X3Dfile.open (filename);
// write header
X3Dfile << "<?xml version='1.0' encoding='UTF-8'?>" ;
X3Dfile << "<!DOCTYPE X3D PUBLIC 'ISO//Web3D//DTD X3D 3.1//EN' 'http://www.web3d.org/specifications/x3d-3.1.dtd'>";
X3Dfile << "<X3D>";
X3Dfile << "<Head>";
X3Dfile << "<meta name='generator' content='pythonOCC, http://www.pythonocc.org'/>";
X3Dfile << "</Head>";
X3Dfile << "<Scene><Shape><Appearance><Material DEF='Shape_Mat' diffuseColor='0.65 0.65 0.65' ";
X3Dfile << "shininess='0.9' specularColor='1 1 1'></Material></Appearance>";
// write tesselation
X3Dfile << ExportShapeToX3DIndexedFaceSet();
X3Dfile << "</Shape></Scene></X3D>\n";
X3Dfile.close();

}

void Tesselator::ExportShapeToJSON(char * filename)
void Tesselator::ExportShapeToThreejs(char * filename)
{
ofstream JSONObject;
ofstream js_file;
int *vertices_idx = new int[3];
int *texcoords_idx = new int[3];
int *normals_idx = new int[3];
JSONObject.open (filename);
js_file.open (filename);
// write header
JSONObject << "var Shape = function () {\n";
JSONObject << "var scope = this;\n";
JSONObject << "THREE.Geometry.call( this );\n";
js_file << "var Shape = function () {\n";
js_file << "var scope = this;\n";
js_file << "THREE.Geometry.call( this );\n";
// first write vertices coords
for (int i=0;i<tot_triangle_count;i++) {
ObjGetTriangle(i, vertices_idx, texcoords_idx, normals_idx);
// First vertex
JSONObject << "v("<<locVertexcoord[vertices_idx[0]]<<","<<locVertexcoord[vertices_idx[0]+1]<<","
js_file << "v("<<locVertexcoord[vertices_idx[0]]<<","<<locVertexcoord[vertices_idx[0]+1]<<","
<< locVertexcoord[vertices_idx[0]+2]<<");\n";
// Second vertex
JSONObject << "v("<<locVertexcoord[vertices_idx[1]]<<","<<locVertexcoord[vertices_idx[1]+1]<<","
js_file << "v("<<locVertexcoord[vertices_idx[1]]<<","<<locVertexcoord[vertices_idx[1]+1]<<","
<< locVertexcoord[vertices_idx[1]+2]<<");\n";
// Third vertex
JSONObject << "v("<<locVertexcoord[vertices_idx[2]]<<","<<locVertexcoord[vertices_idx[2]+1]<<","
js_file << "v("<<locVertexcoord[vertices_idx[2]]<<","<<locVertexcoord[vertices_idx[2]+1]<<","
<< locVertexcoord[vertices_idx[2]+2]<<");\n";


Expand All @@ -434,43 +446,43 @@ void Tesselator::ExportShapeToJSON(char * filename)
for (int i=0;i<tot_triangle_count;i++) {
ObjGetTriangle(i, vertices_idx, texcoords_idx, normals_idx);
// vertex indices
JSONObject << "f3("<<i*3<<","<<1+i*3<<","<<2+i*3<<",";
js_file << "f3("<<i*3<<","<<1+i*3<<","<<2+i*3<<",";
// First normal
JSONObject << locNormalcoord[normals_idx[0]]<<","<<locNormalcoord[normals_idx[0]+1]<<","
js_file << locNormalcoord[normals_idx[0]]<<","<<locNormalcoord[normals_idx[0]+1]<<","
<< locNormalcoord[normals_idx[0]+2]<<",";
// Second normal
JSONObject << locNormalcoord[normals_idx[1]]<<","<<locNormalcoord[normals_idx[1]+1]<<","
js_file << locNormalcoord[normals_idx[1]]<<","<<locNormalcoord[normals_idx[1]+1]<<","
<< locNormalcoord[normals_idx[1]+2]<<",";
// Third normal
JSONObject << locNormalcoord[normals_idx[2]]<<","<<locNormalcoord[normals_idx[2]+1]<<","
js_file << locNormalcoord[normals_idx[2]]<<","<<locNormalcoord[normals_idx[2]+1]<<","
<< locNormalcoord[normals_idx[2]+2];
JSONObject << ");\n";
js_file << ");\n";
}

// at last, write texcoords
for (int i=0;i<tot_triangle_count;i++) {
ObjGetTriangle(i, vertices_idx, texcoords_idx, normals_idx);
JSONObject << "uvs(";
JSONObject << locTexcoord[texcoords_idx[0]]<<","<<locTexcoord[texcoords_idx[0]+2]<<",";
JSONObject << locTexcoord[texcoords_idx[1]]<<","<<locTexcoord[texcoords_idx[1]+2]<<",";
JSONObject << locTexcoord[texcoords_idx[2]]<<","<<locTexcoord[texcoords_idx[2]+2];
JSONObject << ");\n";
js_file << "uvs(";
js_file << locTexcoord[texcoords_idx[0]]<<","<<locTexcoord[texcoords_idx[0]+2]<<",";
js_file << locTexcoord[texcoords_idx[1]]<<","<<locTexcoord[texcoords_idx[1]+2]<<",";
js_file << locTexcoord[texcoords_idx[2]]<<","<<locTexcoord[texcoords_idx[2]+2];
js_file << ");\n";
}

// footer
JSONObject << "function v( x, y, z ) {\n";
JSONObject<< " scope.vertices.push(new THREE.Vector3(x,y,z));\n";
JSONObject<<"}\n";
JSONObject <<"function f3( a, b, c, n1_x,n1_y,n1_z,n2_x,n2_y,n2_z,n3_x,n3_y,n3_z ) {\n";
JSONObject << " scope.faces.push(new THREE.Face3(a,b,c,[new THREE.Vector3(n1_x,n1_y,n1_z),\n";
JSONObject << "new THREE.Vector3( n2_x, n2_y, n2_z ), new THREE.Vector3( n3_x, n3_y, n3_z ) ] ) );\n";
JSONObject << "}\n";
JSONObject << "function uvs(a,b,c,d,e,f) {\n";
JSONObject << "scope.faceVertexUvs[ 0 ].push( [new THREE.Vector2(a,b), new THREE.Vector2(c,d), new THREE.Vector2(e,f)] );\n";
JSONObject << "}\n}\n";
JSONObject << "Shape.prototype = new THREE.Geometry();\n";
JSONObject << "Shape.prototype.constructor = Shape;\n";
JSONObject.close();
js_file << "function v( x, y, z ) {\n";
js_file<< " scope.vertices.push(new THREE.Vector3(x,y,z));\n";
js_file<<"}\n";
js_file <<"function f3( a, b, c, n1_x,n1_y,n1_z,n2_x,n2_y,n2_z,n3_x,n3_y,n3_z ) {\n";
js_file << " scope.faces.push(new THREE.Face3(a,b,c,[new THREE.Vector3(n1_x,n1_y,n1_z),\n";
js_file << "new THREE.Vector3( n2_x, n2_y, n2_z ), new THREE.Vector3( n3_x, n3_y, n3_z ) ] ) );\n";
js_file << "}\n";
js_file << "function uvs(a,b,c,d,e,f) {\n";
js_file << "scope.faceVertexUvs[ 0 ].push( [new THREE.Vector2(a,b), new THREE.Vector2(c,d), new THREE.Vector2(e,f)] );\n";
js_file << "}\n}\n";
js_file << "Shape.prototype = new THREE.Geometry();\n";
js_file << "Shape.prototype.constructor = Shape;\n";
js_file.close();
delete [] vertices_idx;
delete [] texcoords_idx;
delete [] normals_idx;
Expand Down
4 changes: 3 additions & 1 deletion src/Visualization/Tesselator.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define TesselatorH
//---------------------------------------------------------------------------
#include <vector>
#include <string>
//---------------------------------------------------------------------------
#include <gp_Pnt.hxx>
#include <TopoDS_Shape.hxx>
Expand Down Expand Up @@ -97,7 +98,8 @@ Standard_EXPORT class Tesselator
float* VerticesList();
float* NormalsList();
float* TextureCoordinatesList();
void ExportShapeToJSON(char *filename);
void ExportShapeToThreejs(char *filename);
std::string ExportShapeToX3DIndexedFaceSet();
void ExportShapeToX3D(char *filename, int diffR=1, int diffG=0, int diffB=0);
int ObjGetTriangleCount();
int ObjGetVertexCount();
Expand Down
4 changes: 3 additions & 1 deletion src/Visualization/Visualization.i
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
%}

%include ../SWIG_files/common/ExceptionCatcher.i
%include "python/std_string.i"

%typemap(out) float [ANY] {
int i;
Expand Down Expand Up @@ -60,7 +61,8 @@ class Tesselator {
int ObjGetTriangleCount();
int ObjGetVertexCount();
int ObjGetNormalCount();
void ExportShapeToJSON(char *filename);
std::string ExportShapeToX3DIndexedFaceSet();
void ExportShapeToThreejs(char *filename);
void ExportShapeToX3D(char *filename, int diffR=1, int diffG=0, int diffB=0);
void SetDeviation(float aDeviation);
};
Expand Down
Loading

0 comments on commit d6a0e1b

Please sign in to comment.