Skip to content

Commit 3435e91

Browse files
committed
Make both a PlainGeometry and PlainBufferGeometry.
1 parent 9c33ca8 commit 3435e91

File tree

4 files changed

+125
-62
lines changed

4 files changed

+125
-62
lines changed

examples/Examples.ipynb

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
{
3131
"data": {
3232
"application/vnd.jupyter.widget-view+json": {
33-
"model_id": "29cc65e6687a4d0b8521f061b4df0984"
33+
"model_id": "5a0317efcb07469392f4d41f1dad3b59"
3434
}
3535
},
3636
"metadata": {},
@@ -99,7 +99,7 @@
9999
{
100100
"data": {
101101
"application/vnd.jupyter.widget-view+json": {
102-
"model_id": "a875f24e139343708b61edf0346dd948"
102+
"model_id": "dbbdb66ec0214df4ae0a2b8af5f483a5"
103103
}
104104
},
105105
"metadata": {},
@@ -108,7 +108,7 @@
108108
{
109109
"data": {
110110
"application/vnd.jupyter.widget-view+json": {
111-
"model_id": "78c0d687a9a2446bb140ab604c57e3aa"
111+
"model_id": "4149a2737a234f1db7c3813346685f5e"
112112
}
113113
},
114114
"metadata": {},
@@ -325,15 +325,24 @@
325325
"display(renderer)"
326326
]
327327
},
328+
{
329+
"cell_type": "markdown",
330+
"metadata": {},
331+
"source": [
332+
"# Indexed Geometries\n",
333+
"\n",
334+
"The PlainGeometry lets you specify vertices and faces for a surface."
335+
]
336+
},
328337
{
329338
"cell_type": "code",
330-
"execution_count": 16,
339+
"execution_count": 11,
331340
"metadata": {},
332341
"outputs": [
333342
{
334343
"data": {
335344
"application/vnd.jupyter.widget-view+json": {
336-
"model_id": "e447091aeb744189850523e511566d2c"
345+
"model_id": "a8630625d64d4f3f82d1a707b97d809d"
337346
}
338347
},
339348
"metadata": {},
@@ -344,11 +353,7 @@
344353
"from pythreejs import *\n",
345354
"import numpy as np\n",
346355
"from IPython.display import display\n",
347-
"from ipywidgets import HTML, Text\n",
348-
"from traitlets import link, dlink\n",
349356
"\n",
350-
"\n",
351-
"#vcm = LineBasicMaterial(vertexColors='VertexColors')\n",
352357
"vertices = np.asarray([\n",
353358
"[0, 0, 0],\n",
354359
"[0, 0, 1],\n",
@@ -375,11 +380,11 @@
375380
" [5, 6, 7]\n",
376381
" ])\n",
377382
"\n",
378-
"vertexcolors = np.asarray([(1,1,1)]*8)\n",
379-
"\n",
380-
"cubeGeometry = PlainGeometry(vertices=vertices, faces=faces, faceColors = vertexcolors)\n",
383+
"vertexcolors = np.asarray([(0,0,0), (0,0,1), (0,1,0), (1,0,0), (0,1,1), (1,0,1), (1,1,0), (1,1,1)])\n",
384+
"facecolors = [[vertexcolors[i] for i in f] for f in faces]\n",
385+
"cubeGeometry = PlainGeometry(vertices=vertices, faces=faces, faceColors = facecolors)\n",
381386
"\n",
382-
"myobjectCube = Mesh(geometry=cubeGeometry, material = PhongMaterial( vertexColors = 'VertexColors'))\n",
387+
"myobjectCube = Mesh(geometry=cubeGeometry, material = LambertMaterial(vertexColors = 'VertexColors'))\n",
383388
"cCube = PerspectiveCamera(position=[3, 3, 3], fov=20,\n",
384389
" children=[DirectionalLight(color='#ffffff', position=[-3, 5, 1], intensity=0.5)])\n",
385390
"sceneCube = Scene(children=[myobjectCube, AmbientLight(color='#dddddd')])\n",
@@ -391,51 +396,73 @@
391396
]
392397
},
393398
{
394-
"cell_type": "code",
395-
"execution_count": 12,
399+
"cell_type": "markdown",
396400
"metadata": {},
397-
"outputs": [
398-
{
399-
"data": {
400-
"text/plain": [
401-
"array([[ 0., 0., 0.],\n",
402-
" [ 0., 0., 1.],\n",
403-
" [ 0., 1., 0.],\n",
404-
" [ 0., 1., 1.],\n",
405-
" [ 1., 0., 0.],\n",
406-
" [ 1., 0., 1.],\n",
407-
" [ 1., 1., 0.],\n",
408-
" [ 1., 1., 1.]], dtype=float32)"
409-
]
410-
},
411-
"execution_count": 12,
412-
"metadata": {},
413-
"output_type": "execute_result"
414-
}
415-
],
416401
"source": [
417-
"cubeGeometry.vertices"
402+
"# Buffer Geometries\n",
403+
"\n",
404+
"The PlainBufferGeometry object uses several tricks to speed up both the transfer of data and the rendering of the data."
418405
]
419406
},
420407
{
421408
"cell_type": "code",
422-
"execution_count": 7,
409+
"execution_count": 13,
423410
"metadata": {},
424411
"outputs": [
425412
{
426413
"data": {
427-
"text/plain": [
428-
"'7.0.0.dev0'"
429-
]
414+
"application/vnd.jupyter.widget-view+json": {
415+
"model_id": "7ab6910f90c24b52bfc1a9146e55f948"
416+
}
430417
},
431-
"execution_count": 7,
432418
"metadata": {},
433-
"output_type": "execute_result"
419+
"output_type": "display_data"
434420
}
435421
],
436422
"source": [
437-
"import ipywidgets\n",
438-
"ipywidgets.__version__"
423+
"from pythreejs import *\n",
424+
"import numpy as np\n",
425+
"from IPython.display import display\n",
426+
"\n",
427+
"vertices = np.asarray([\n",
428+
"[0, 0, 0],\n",
429+
"[0, 0, 1],\n",
430+
"[0, 1, 0],\n",
431+
"[0, 1, 1],\n",
432+
"[1, 0, 0],\n",
433+
"[1, 0, 1],\n",
434+
"[1, 1, 0],\n",
435+
"[1, 1, 1]\n",
436+
"], dtype='float32')\n",
437+
"\n",
438+
"faces = np.asarray([\n",
439+
" [0, 1, 3],\n",
440+
" [0, 2, 3],\n",
441+
" [0, 2, 4],\n",
442+
" [2, 4, 6],\n",
443+
" [0, 1, 4],\n",
444+
" [1, 4, 5],\n",
445+
" [2, 3, 6],\n",
446+
" [3, 6, 7],\n",
447+
" [1, 3, 5],\n",
448+
" [3, 5, 7],\n",
449+
" [4, 5, 6],\n",
450+
" [5, 6, 7]\n",
451+
" ])\n",
452+
"\n",
453+
"vertexcolors = np.asarray([(0,0,0), (0,0,1), (0,1,0), (1,0,0), (0,1,1), (1,0,1), (1,1,0), (1,1,1)])\n",
454+
"\n",
455+
"cubeGeometry = PlainBufferGeometry(vertices=vertices, faces=faces, colors = vertexcolors)\n",
456+
"\n",
457+
"myobjectCube = Mesh(geometry=cubeGeometry, material = LambertMaterial(vertexColors = 'VertexColors'))\n",
458+
"cCube = PerspectiveCamera(position=[3, 3, 3], fov=20,\n",
459+
" children=[DirectionalLight(color='#ffffff', position=[-3, 5, 1], intensity=0.5)])\n",
460+
"sceneCube = Scene(children=[myobjectCube, AmbientLight(color='#dddddd')])\n",
461+
"\n",
462+
"rendererCube = Renderer(camera=cCube, background='black', background_opacity=1,\n",
463+
" scene = sceneCube, controls=[OrbitControls(controlling=cCube)])\n",
464+
"\n",
465+
"display(rendererCube)"
439466
]
440467
},
441468
{

js/src/jupyter-threejs.js

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -591,14 +591,14 @@ define(["jupyter-js-widgets", "underscore", "three", "ndarray"],
591591

592592
var PlainGeometryView = ThreeView.extend({
593593
update: function() {
594-
var geometry = new THREE.BufferGeometry();
594+
var geometry = new THREE.Geometry();
595595
var vertices = this.model.get('vertices');
596596
var faces = this.model.get('faces');
597597
var colors = this.model.get('colors');
598598
var faceColors = this.model.get('faceColors');
599599
var faceNormals = this.model.get('faceNormals');
600600
var faceVertexUvs = this.model.get('faceVertexUvs');
601-
/*
601+
602602
if (faceNormals.length === 0) {
603603
faceNormals = void 0;
604604
}
@@ -616,14 +616,7 @@ define(["jupyter-js-widgets", "underscore", "three", "ndarray"],
616616
var i, len;
617617
var f;
618618
var face;
619-
*/
620-
geometry.addAttribute('position', new THREE.BufferAttribute(vertices.data, 3));
621-
geometry.addAttribute('color', new THREE.BufferAttribute(faceColors.data, 3));
622-
geometry.setIndex(new THREE.BufferAttribute(faces.data, 1));
623-
geometry.computeVertexNormals();
624-
geometry.computeBoundingSphere();
625-
626-
/*for(i = 0, len=vertices.shape[0]; i<len; i+=1) {
619+
for(i = 0, len=vertices.shape[0]; i<len; i+=1) {
627620
geometry.vertices.push(toVec(vertices.pick(i)));
628621
}
629622
for(i=0, len=faces.shape[0]; i<len; i+=1) {
@@ -646,22 +639,35 @@ define(["jupyter-js-widgets", "underscore", "three", "ndarray"],
646639
for(i=0, len=colors.length; i<len; i+=1) {
647640
geometry.colors.push(new THREE.Color(colors[i]));
648641
}
649-
*/
650642
// TODO: faceVertexUvs
651-
geometry.attributes.position.needsUpdate = true;
652-
geometry.attributes.color.needsUpdate = true;
653-
/*geometry.elementsNeedUpdate = true;
643+
geometry.elementsNeedUpdate = true;
654644
geometry.uvsNeedUpdate = true;
655645
geometry.normalsNeedUpdate = true;
656646
geometry.tangentsNeedUpdate = true;
657647
geometry.colorsNeedUpdate = true;
658648
geometry.lineDistancesNeedUpdate = true;
659-
*/
660649
this.replace_obj(geometry);
661650
},
662651
});
663652

664653

654+
var PlainBufferGeometryView = ThreeView.extend({
655+
update: function() {
656+
var geometry = new THREE.BufferGeometry();
657+
var vertices = this.model.get('vertices');
658+
var faces = this.model.get('faces');
659+
var colors = this.model.get('colors');
660+
geometry.addAttribute('position', new THREE.BufferAttribute(vertices.data, 3));
661+
geometry.addAttribute('color', new THREE.BufferAttribute(colors.data, 3));
662+
geometry.setIndex(new THREE.BufferAttribute(faces.data, 1));
663+
geometry.computeVertexNormals();
664+
geometry.computeBoundingSphere();
665+
geometry.attributes.position.needsUpdate = true;
666+
geometry.attributes.color.needsUpdate = true;
667+
this.replace_obj(geometry);
668+
},
669+
});
670+
665671
var FaceGeometryView = ThreeView.extend({
666672
update: function() {
667673
// Construct triangles
@@ -1686,6 +1692,8 @@ define(["jupyter-js-widgets", "underscore", "three", "ndarray"],
16861692
return {shape: obj.shape, dtype: obj.dtype, buffer: obj.data}
16871693
}
16881694

1695+
var array_serialization = { deserialize: JSONToArray, serialize: arrayToJSON };
1696+
16891697
var PlainGeometryModel = GeometryModel.extend({
16901698
defaults: _.extend({}, GeometryModel.prototype.defaults, {
16911699
_model_name: 'PlainGeometryModel',
@@ -1700,9 +1708,26 @@ define(["jupyter-js-widgets", "underscore", "three", "ndarray"],
17001708
})
17011709
}, {
17021710
serializers: _.extend({
1703-
vertices: { deserialize: JSONToArray, serialize: arrayToJSON },
1704-
faces: { deserialize: JSONToArray, serialize: arrayToJSON },
1705-
faceColors: { deserialize: JSONToArray, serialize: arrayToJSON },
1711+
vertices: array_serialization,
1712+
faces: array_serialization,
1713+
faceColors: array_serialization,
1714+
}, GeometryModel.serializers)
1715+
});
1716+
1717+
var PlainBufferGeometryModel = GeometryModel.extend({
1718+
defaults: _.extend({}, GeometryModel.prototype.defaults, {
1719+
_model_name: 'PlainBufferGeometryModel',
1720+
_view_name: 'PlainBufferGeometryView',
1721+
1722+
vertices: ndarray(new Float32Array(), [0,3]),
1723+
colors: ndarray(new Uint8Array(), [0,3,3]),
1724+
faces: ndarray(new Uint32Array(), [0, 3]),
1725+
})
1726+
}, {
1727+
serializers: _.extend({
1728+
vertices: array_serialization,
1729+
faces: array_serialization,
1730+
colors: array_serialization,
17061731
}, GeometryModel.serializers)
17071732
});
17081733

@@ -2098,6 +2123,8 @@ define(["jupyter-js-widgets", "underscore", "three", "ndarray"],
20982123
PickerModel : PickerModel,
20992124
PlainGeometryView : PlainGeometryView,
21002125
PlainGeometryModel : PlainGeometryModel,
2126+
PlainBufferGeometryView : PlainBufferGeometryView,
2127+
PlainBufferGeometryModel : PlainBufferGeometryModel,
21012128
PlaneGeometryView : PlaneGeometryView,
21022129
PlaneGeometryModel : PlaneGeometryModel,
21032130
PointLight : PointLight,

pythreejs/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
Picker,
1616
Geometry,
1717
PlainGeometry,
18+
PlainBufferGeometry,
1819
SphereGeometry,
1920
CylinderGeometry,
2021
BoxGeometry,
@@ -84,6 +85,7 @@
8485
"Picker",
8586
"Geometry",
8687
"PlainGeometry",
88+
"PlainBufferGeometry",
8789
"SphereGeometry",
8890
"CylinderGeometry",
8991
"BoxGeometry",

pythreejs/pythreejs.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ class PlainGeometry(Geometry):
274274
vertices = Array(dtype='float32').tag(sync=True, **array_serialization).valid(shape_constraints(None,3))
275275
faces = Array(dtype='uint32').tag(sync=True, **array_serialization).valid(shape_constraints(None,3))
276276
# list of [[v1_r,v1_g,v1_b], [v2_r,v2_g,v2_b], [v3_r,v3_g,v3_b]] for each face
277-
faceColors = Array(dtype='float32').tag(sync=True, **array_serialization).valid(shape_constraints(None,3))
277+
faceColors = Array(dtype='float32').tag(sync=True, **array_serialization).valid(shape_constraints(None, 3, 3))
278278
#vertices = List(vector3(CFloat)).tag(sync=True)
279279
colors = List(Color).tag(sync=True)
280280
#faces = List(List(CFloat)).tag(sync=True)
@@ -284,6 +284,13 @@ class PlainGeometry(Geometry):
284284
faceNormals = Tuple().tag(sync=True)
285285
# todo: faceVertexUvs = List(vector3(vector2(CFloat))).tag(sync=True)
286286

287+
class PlainBufferGeometry(Geometry):
288+
_view_name = Unicode('PlainBufferGeometryView').tag(sync=True)
289+
_model_name = Unicode('PlainBufferGeometryModel').tag(sync=True)
290+
291+
vertices = Array(dtype='float32').tag(sync=True, **array_serialization).valid(shape_constraints(None,3))
292+
faces = Array(dtype='uint32').tag(sync=True, **array_serialization).valid(shape_constraints(None,3))
293+
colors = Array(dtype='float32', help="Vertex colors").tag(sync=True, **array_serialization).valid(shape_constraints(None,3))
287294

288295
class SphereGeometry(Geometry):
289296
_view_name = Unicode('SphereGeometryView').tag(sync=True)

0 commit comments

Comments
 (0)