Skip to content

Commit

Permalink
Improved dash3D usability, including persistent view settings encoded…
Browse files Browse the repository at this point in the history
… in URL, handling custom number of viewports viewports, better layout. (#538)

Fixed bug

Signed-off-by: Maria Masha Shugrina <mshugrina@nvidia.com>

Tiny changes after MR review

Signed-off-by: Maria Masha Shugrina <mshugrina@nvidia.com>

Co-authored-by: Maria Masha Shugrina <mshugrina@nvidia.com>
  • Loading branch information
shumash and Maria Masha Shugrina committed Mar 30, 2022
1 parent d20107d commit e53dd7b
Show file tree
Hide file tree
Showing 14 changed files with 892 additions and 842 deletions.
19 changes: 17 additions & 2 deletions kaolin/experimental/dash3d/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import os
import sys

import flask
from flask import Flask, render_template
from tornado.wsgi import WSGIContainer
from tornado.web import Application, FallbackHandler
Expand All @@ -28,6 +29,16 @@
logger = logging.getLogger(__name__)


def get_max_viewports(urlargs):
default_val = 3
try:
res = int(urlargs.get("maxviews", default_val))
res = max(1, min(8, res))
except Exception as e:
res = default_val
return res


def create_server(logdir):
""" Create the server, including websocket handler through tornado, and flask http server.
Expand All @@ -49,9 +60,13 @@ def create_server(logdir):
@app.route('/')
def index():
helper.parser.check_for_updates()

urlargs = dict(flask.request.args)
max_viewports = get_max_viewports(urlargs)
return render_template('home.html', logdir=helper.logdir,
nmeshes=helper.parser.num_mesh_categories(),
npointclouds=helper.parser.num_pointcloud_categories())
nmeshes=min(helper.parser.num_mesh_items(), max_viewports),
npointclouds=min(helper.parser.num_pointcloud_items(), max_viewports),
urlargs=urlargs)

# Tornado server to handle websockets
container = WSGIContainer(app)
Expand Down
49 changes: 38 additions & 11 deletions kaolin/experimental/dash3d/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ nvidia.Controller.prototype.getViewContainerId = function(type, i) {
};

nvidia.Controller.prototype.initRenderers = function() {
let camera = null;
for (let t = 0; t < this.supported_types.length; ++t) {
const type = this.supported_types[t];
this.renderers[type] = [];
Expand All @@ -55,7 +56,11 @@ nvidia.Controller.prototype.initRenderers = function() {
// Then assume existence of ids: {type}-header{i}, {type}-view{i}, {type}-info{i}
for (let i = 0; i < containers.length; ++i) {
const id = this.getViewContainerId(type, i);
this.renderers[type].push(new nvidia.ThreeJsRenderer(id));
const new_renderer = new nvidia.ThreeJsRenderer(id, camera);
if (this.shouldLinkCameras() && camera === null) {
camera = new_renderer.camera;
}
this.renderers[type].push(new_renderer);
}
}
};
Expand Down Expand Up @@ -98,7 +103,7 @@ nvidia.Controller.prototype.initViews = function() {
cat_selectors.empty();
cat_selectors.off("change");

if (!categories) {
if (!categories || categories.length == 0) {
nvidia.util.timed_log("No entries for type " + type);
continue;
}
Expand All @@ -112,26 +117,36 @@ nvidia.Controller.prototype.initViews = function() {
end_time = Math.max(categories[i]["end_time"], end_time);
}

const nviews = Math.min(categories.length, renderers.length);
// Select an initial set of categories and ids to display.
// Currently selects 0th id from all categories, if there are enough viewports.
// If more viewports remain, selects subsequent ids from the last category if it has them.
// Better logic is definitely possible, but none would fit all scenarios.
let id_idx = 0;
const nviews = renderers.length;
for (let i = 0; i < nviews; ++i) {
const cat = categories[i];
let cat_idx = Math.min(i, categories.length - 1);
let cat = categories[cat_idx];

if (i >= categories.length) {
id_idx = Math.min(cat["ids"].length - 1, id_idx + 1);
}
this.active_views[type].push({
category: cat["category"],
id: cat["ids"][0],
id: cat["ids"][id_idx],
time: cat["end_time"]
});

const hsel = "#" + this.getHeaderId(type, i);
const cat_dropdown = $(hsel + " .cat");
cat_dropdown.val(i);
cat_dropdown.val(cat_idx);

const id_dropdown = $(hsel + " .id");
id_dropdown.off("change");
id_dropdown.empty();
$.each(cat["ids"], function(v) {
id_dropdown.append($("<option></option>")
.attr("value", v).text("id " + v)); });
id_dropdown.val(cat["ids"][0]);
id_dropdown.val(cat["ids"][id_idx]);

const callback_maker = function(controller, typename, view_idx) {
return function() { controller.onViewDropdownChange(typename, view_idx); }
Expand All @@ -142,8 +157,6 @@ nvidia.Controller.prototype.initViews = function() {
if (cat["ids"].length < 2) {
id_dropdown.hide();
}

// TODO: reset renderer as well
}
}
$("#timeslider").attr("max", end_time).val(end_time);
Expand All @@ -154,6 +167,20 @@ nvidia.Controller.prototype.initSidebarEvents = function() {
// Note: this is very DOM-dependent
$("#timeslider").on("change", function(c) {
return function(e) { c.onTimeSliderValueChange($("#timeslider").val()); }; }(this));

$("#radius").on("change", function(e) {nvidia.util.updateCurrentUrlParam("radius", $(this).val());});
$("#linkcam").on("change", function(e) {nvidia.util.updateCurrentUrlParam("linkcam", this.checked);});
$("#maxviews").on("change", function(e) {nvidia.util.updateCurrentUrlParam("maxviews", $(this).val());});

$("#refresh").click(function(e) { location.reload(); });
};

nvidia.Controller.prototype.getSphereRadius = function() {
return $("#radius").val();
};

nvidia.Controller.prototype.shouldLinkCameras = function() {
return $("#linkcam")[0].checked;
};

nvidia.Controller.prototype.onTimeSliderValueChange = function(time) {
Expand Down Expand Up @@ -270,7 +297,7 @@ nvidia.Controller.prototype.parseBinaryGeometry = function(binary_data) {
"time": snap_time
};
} else if (data_type === 1) {
const geos = nvidia.geometry.PtCloudsFromBinary(binary_data, 4 * 4);
const geos = nvidia.geometry.PtCloudsFromBinary(binary_data, 4 * 4, this.getSphereRadius());
return {
"type": "pointcloud",
"geos": geos,
Expand Down Expand Up @@ -300,4 +327,4 @@ nvidia.Controller.prototype.onclose = function() {

if (typeof module !== 'undefined') {
module.exports = nvidia.Controller;
}
}
3 changes: 1 addition & 2 deletions kaolin/experimental/dash3d/src/geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ nvidia.geometry.GetBoundingBox = function(geometries) {
/**
* Parse point clouds from binary data written by the web server.
*/
nvidia.geometry.PtCloudsFromBinary = function(binary_data, initial_offset) {
nvidia.geometry.PtCloudsFromBinary = function(binary_data, initial_offset, sphere_radius) {
let global_info = new Int32Array(binary_data, initial_offset, 4);
const n_clouds = global_info[0];
const texture_mode = global_info[1];
Expand All @@ -72,7 +72,6 @@ nvidia.geometry.PtCloudsFromBinary = function(binary_data, initial_offset) {
let geometries = [];
let read_start = initial_offset + 4 * 4; // 4 * 4 bytes used for n_clouds read above

const sphere_radius = 0.02; // TODO: make adaptive
for (let m = 0; m < n_clouds; ++m) {
let meta = new Int32Array(binary_data, read_start, 2);
read_start += 2 * 4;
Expand Down
21 changes: 13 additions & 8 deletions kaolin/experimental/dash3d/src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

var nvidia = nvidia || {};

nvidia.ThreeJsRenderer = function(elemid) {
nvidia.ThreeJsRenderer = function(elemid, optional_camera) {
this.meshes = [];
this.container = document.getElementById(elemid);

Expand Down Expand Up @@ -50,13 +50,17 @@ nvidia.ThreeJsRenderer = function(elemid) {
console.log('Initialized green plastic shader');
};}(this));

this.init();
this.init(optional_camera);
};

nvidia.ThreeJsRenderer.prototype.init = function() {
nvidia.ThreeJsRenderer.prototype.init = function(optional_camera) {
var aspect = 1.0; // width/height
this.camera = new THREE.PerspectiveCamera(20, 1.0, 0.1, 10000);
this.camera.position.y = 0.5;
if (optional_camera) {
this.camera = optional_camera;
} else {
this.camera = new THREE.PerspectiveCamera(20, 1.0, 0.1, 10000);
this.camera.position.y = 0.5;
}

this.scene = new THREE.Scene();
this.scene.background = new THREE.Color( 0xffffff );
Expand Down Expand Up @@ -128,12 +132,13 @@ nvidia.ThreeJsRenderer.prototype.init = function() {
self.render();
});

this.setManualCamera();
if (!optional_camera) {
this.setManualCamera();
}

this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.update();


var renderer = this;
var animate = function() {
requestAnimationFrame( animate );
Expand Down Expand Up @@ -202,4 +207,4 @@ nvidia.ThreeJsRenderer.prototype.render = function() {

if (typeof module !== 'undefined') {
module.exports = nvidia.ThreeJsRenderer;
}
}
31 changes: 30 additions & 1 deletion kaolin/experimental/dash3d/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ input[type=checkbox]:checked {
padding: 0;
}

button {
color: white;
background-color: var(--nvidia-color);
}

.nav-container {
margin: 0 0;
justify-content: left;
}

.nav-logo {
margin: 5px 10px 0 0;
}

/* SIDEBAR ------------------------------------------*/

html{
Expand Down Expand Up @@ -101,6 +115,21 @@ html{
word-break: break-all;
}

.optrow {
margin: 10px 0;
}

.opt {
display: inline-block;
margin: 0 10px 0 0;
}

.rightbuttonrow {
display: flex;
justify-content: right;
margin: 10px 0;
}

/* VIEWS ------------------------------------------*/

.info {
Expand Down Expand Up @@ -145,4 +174,4 @@ html{

input[type="range"] {
padding: 0;
}
}
21 changes: 20 additions & 1 deletion kaolin/experimental/dash3d/src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,25 @@ nvidia.util.downloadURL = function(filename, url) {
document.body.removeChild(a);
};

nvidia.util.updateCurrentUrlParam = function(key, val) {
let url = new URL(window.location.href);
let params = url.searchParams;

if (val == params.get(key)) {
return false;
}

if (val === undefined || val === false) {
params.delete(key);
} else {
params.set(key, val);
}

let new_url = url.toString();
window.history.replaceState({}, document.title, new_url);
return true;
};

if (typeof module !== 'undefined') {
module.exports = nvidia.util;
}
}

0 comments on commit e53dd7b

Please sign in to comment.