Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
daerduoCarey committed Apr 19, 2019
0 parents commit 7dbfa6b
Show file tree
Hide file tree
Showing 250 changed files with 33,132 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
@@ -0,0 +1,8 @@
.DS_STORE
.idea
*.obj
*.ply
*.mp4
part_hier_templates
partnet_videos
dump.sql
44 changes: 44 additions & 0 deletions README.md
@@ -0,0 +1,44 @@
# PartNet: A Large-scale Benchmark for Fine-grained and Hierarchical Part-level 3D Object Understanding

![Annotation System Overview](https://github.com/daerduoCarey/partnet_anno_system/blob/master/images/gui.png)

**Figure 1. The PartNet Annotation System Overview.**

## Annotation System

This repo contains the web-based part segmentation annotation interface for PartNet.

Our 3D web-based GUI is build upon Node.js, Express.js and Three.js frameworks. Please check the README in `client` and `server` folders for setup instructions.


## Paper and Dataset

PartNet is accepted to CVPR 2019. See you at Long Beach, LA.

Our team: [Kaichun Mo](https://cs.stanford.edu/~kaichun), [Shilin Zhu](http://cseweb.ucsd.edu/~shz338/), [Angel X. Chang](https://angelxuanchang.github.io/), [Li Yi](https://cs.stanford.edu/~ericyi/), [Subarna Tripathi](https://subarnatripathi.github.io/), [Leonidas J. Guibas](https://geometry.stanford.edu/member/guibas/) and [Hao Su](http://cseweb.ucsd.edu/~haosu/) from Stanford, UCSD, SFU and Intel AI Lab.

Arxiv Version: https://arxiv.org/abs/1812.02713

Project Page: https://cs.stanford.edu/~kaichun/partnet/

Video: https://youtu.be/7pEuoxmb-MI

Please refer to [this repo](https://github.com/daerduocarey/partnet_dataset) for the PartNet dataset utilities and [this repo](https://github.com/daerduocarey/partnet_seg_exps) for the segmentation experiments (Section 5) in the paper.

## Citations

@article{mo2018partnet,
title={{PartNet}: A Large-scale Benchmark for Fine-grained and Hierarchical Part-level {3D} Object Understanding},
author={Mo, Kaichun and Zhu, Shilin and Chang, Angel and Yi, Li and Tripathi, Subarna and Guibas, Leonidas and Su, Hao},
booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
year={2019}
}

## License

MIT Licence

## Updates

* [April 18, 2019] PartNet Annotation System v1.0 release.

2 changes: 2 additions & 0 deletions client/.gitignore
@@ -0,0 +1,2 @@
node_modules
build
57 changes: 57 additions & 0 deletions client/README.md
@@ -0,0 +1,57 @@
## Client-side Code

### Installation

The client side use `node.js` and `browserify`.

First, install `node.js` and `browserify` as follows.

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
source ~/.bashrc
nvm install node
npm install -g browserify

The part hier visualization uses [Bootstrap Tree View](https://github.com/jonmiles/bootstrap-treeview). Please install

npm install -g bower
npm install bootstrap-treeview
Next, install `node.js` dependent modules as defined in `package.json`.

npm install
Finally, compile the client-side javascript dependencies using `browserify` by running the following.

./build.sh

This will generate a `build/ShapeNetPP.bundle.js` that includes all node-js modules defined by `require`.


### Usage

Set up config files,

cp config/backend.js.template config/backend.js
[fill in the information in this file]

To run the system, please go to server-side code, set up server-side and run

cd ../server
# read README for the server side to install
npm start
Open browser, and go to

http://localhost:3000


### Interface Descriptions

There are three main webpages that construct the system: login page, viewer page, and annotator page.

* The login page provides you functions to register yourself as a worker and log in to annotate.
* The viewer page lists all annotations that have been done and provides functions to label new shapes. Each worker can see the models annotated by himself or herself only. We reserve a special username *admin* that can manage all annotations from all workers. Admin account also has the privilege to download the annotations.
* The annotator page is the main page where annotation for a model happens. It provides many utilities to view the 3D model, view part templates, annotate a part in the template, click-and-group parts, and split parts by cutting. Please click *help* on the top-left corner on the webpage for keyboard shortcuts.

We strongly recommend you to refer to [the paper](https://arxiv.org/abs/1812.02713) and [the Youtube annotation video](https://youtu.be/7pEuoxmb-MI) for mode detailed demonstrations.

121 changes: 121 additions & 0 deletions client/admin_list_viewer.js
@@ -0,0 +1,121 @@
window.load_cat_names = function() {
console.log('[load_cat_names] start!');

var keys = ['Bag', 'Bed', 'Bottle', 'Bowl', 'Chair', 'Clock', 'Dishwasher', 'Display', 'Door', 'Earphone',
'Faucet', 'Hat', 'Keyboard', 'Knife', 'Lamp', 'Laptop', 'Microwave', 'Mug', 'Refrigerator', 'Scissors',
'StorageFurniture', 'Table', 'TrashCan', 'Vase'];

keys.forEach(function(item) {
var option = document.createElement('option');
option.value = item;
option.text = item;
$('#select_cat_name').append(option);
});
};

window.post = function(path, params, method) {
method = method || "post"; // Set method to post by default if not specified.

// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
form.setAttribute("target", "_blank");

for (var key in params) {
if (params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);

form.appendChild(hiddenField);
}
}

document.body.appendChild(form);
form.submit();
};

window.gen_visu_list = function() {
var table = document.getElementById("myTable").getElementsByTagName('tbody')[0];
var cat_name = document.getElementById('select_cat_name').value;

if ($.fn.DataTable.isDataTable("#myTable")) {
$('#myTable').DataTable().clear().destroy();
}

table.innerHTML = '';

$.getJSON('annotation/get_all_annotations_admin/'+cat_name, function(data) {
for (let item of data.anno_list) {
var anno_id = item.anno_id;
var model_id = item.model_id;
var anno_version = item.version;
var user_id = item.user_id;

var row = table.insertRow(-1);

row.insertCell(0).innerHTML = anno_id;
row.insertCell(1).innerHTML = anno_version;

row.insertCell(2).innerHTML = model_id;

var img_html = '<img src="annotation/get_snapshot/' + anno_id + '-' + anno_version + '"></img>';
row.insertCell(3).innerHTML = img_html;

var view_html = '<button type="button" onclick="view_model(\''+anno_id+'\')">View</button>';
row.insertCell(4).innerHTML = view_html;

var modify_html = '<button type="button" onclick="modify_model(\''+anno_id+'\')">Modify</button>';
row.insertCell(5).innerHTML = modify_html;

var delete_html = '<button type="button" onclick="delete_model(\''+anno_id+'\')">Delete</button>';
row.insertCell(6).innerHTML = delete_html;

var download_html = '<button type="button" onclick="window.open(\'/annotation/download/'+anno_id+'\', \'_blank\'); return false;">Download</button>';
row.insertCell(7).innerHTML = download_html;
}

$('#myTable').DataTable({
createdRow: function( row, data, dataIndex ) {
if ( data[2] == "0" ) {
$(row).addClass('highlightRow');
}
}
});
});
};

window.view_model = function(anno_id) {
post('/part_annotator', {anno_id: anno_id, allow_edit: false, load_parent_anno: true});
};

window.modify_model = function(anno_id) {
post('/part_annotator', {anno_id: anno_id, allow_edit: true, load_parent_anno: true});
};

window.delete_model = function(anno_id) {
var prompt_str, alert_str;
prompt_str = 'Are you sure to delete this annotation? All related information will be removed.';
alert_str = 'Deleted! The webpage will refresh automatically.';
if (confirm(prompt_str)) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
console.log('anno deleted: ' + anno_id);
alert(alert_str);
gen_visu_list();
}
};
xmlhttp.open("GET", 'annotation/delete/' + anno_id, true);
xmlhttp.send();
}
};

window.view_template = function() {
console.log('View template');
var cat_name = document.getElementById('select_cat_name').value;
window.open('/template_viewer/'+cat_name);
};
1 change: 1 addition & 0 deletions client/build.sh
@@ -0,0 +1 @@
rm -rf build && mkdir build && browserify admin_list_viewer.js template_viewer.js part_hier_annotator.js > build/ShapeNetPP.bundle.js
1 change: 1 addition & 0 deletions client/config/.gitignore
@@ -0,0 +1 @@
backend.js
32 changes: 32 additions & 0 deletions client/config/backend.js.template
@@ -0,0 +1,32 @@
var be_config = exports;

// Host and Port Information (SET UP HERE!)
be_config.remoteHost = '[TODO: e.g. http://localhost]';
be_config.remotePort = '[TODO]';

// get annotation info (Don't Change!)
be_config.get_anno_info = '/annotation/get_info';
be_config.save_anno_json = '/annotation/save_json';
be_config.get_anno_json = '/annotation/get_json';
be_config.save_anno_snapshot = '/annotation/save_snapshot';
be_config.update_anno_version = '/annotation/update_version';
be_config.get_anno_obj_list = '/annotation/get_obj_list';
be_config.save_anno_obj_list = '/annotation/save_obj_list';
be_config.get_qa_data = '/annotation/get_qa';
be_config.save_qa_data = '/annotation/save_qa';

// get files (Don't Change!)
be_config.get_original_part = '/file/original-part';
be_config.get_remesh_part = '/file/remesh-part';
be_config.get_new_part = '/file/new-part';
be_config.get_original_scene_graph = '/file/original-scene-graph';
be_config.get_remesh_cut_json = '/file/remesh-cut-output-json';
be_config.get_model_screenshot = '/file/model-sceneshot';

// remesh related (Don't Change!)
be_config.request_remesh = '/remesh';
be_config.submit_remesh = '/submit_remesh_cut';

// user anno list viewer (Don't Change!)
be_config.anno_list_viewer = '/part_anno_list_viewer';

10 changes: 10 additions & 0 deletions client/config/colors.js
@@ -0,0 +1,10 @@
var colors = exports;
colors.colors = [ 0xff0000, 0x00ffff, 0x00ff00,
0x0000ff, 0xffff00, 0xff00ff,
0x800080, 0xadd8e6, 0x0000a0,
0xa52a2a, 0x0000a0, 0x808000,
0xd1c69e, 0x670000, 0x4d0000,
0xdcf5e9, 0xaa93e2, 0x008080,
0xf9d3d3, 0xffc0cb, 0xd95e40,
0xb59265
];
11 changes: 11 additions & 0 deletions client/css/Treant.css
@@ -0,0 +1,11 @@
/* required LIB STYLES */
/* .Treant se automatski dodaje na svaki chart conatiner */
.Treant { position: relative; overflow: hidden; padding: 0 !important; }
.Treant > .node,
.Treant > .pseudo { position: absolute; display: block; visibility: hidden; }
.Treant.Treant-loaded .node,
.Treant.Treant-loaded .pseudo { visibility: visible; }
.Treant > .pseudo { width: 0; height: 0; border: none; padding: 0; }
.Treant .collapse-switch { width: 3px; height: 3px; display: block; border: 1px solid black; position: absolute; top: 1px; right: 1px; cursor: pointer; }
.Treant .collapsed .collapse-switch { background-color: #868DEE; }
.Treant > .node img { border: none; float: left; }
44 changes: 44 additions & 0 deletions client/css/custom-color-plus-scrollbar.css
@@ -0,0 +1,44 @@
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { margin:0; padding:0; }
table { border-collapse:collapse; border-spacing:0; }
fieldset,img { border:0; }
address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
caption,th { text-align:left; }
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
q:before,q:after { content:''; }
abbr,acronym { border:0; }

body { background: #fff; }
/* optional Container STYLES */
.chart { height: 200px; margin: 5px; width: 1000px; margin: 5px auto; border: 3px solid #DDD; border-radius: 3px; }
.Treant > .node { }
.Treant > p { font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-weight: bold; font-size: 12px; }
.node-name { font-weight: bold;}

.nodeExample1 {
padding: 2px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #262626;
border: 1px solid #000;
width: 200px;
font-family: Tahoma;
font-size: 12px;
color: #ffffff;
}

.nodeExample1 img {
margin-right: 10px;
}

.Treant > a:link {
color: #ffffff;
}

.Treant > a:visited {
color: #ffffff;
}

.Treant > a:link:hover {
color: #636363;
}
4 changes: 4 additions & 0 deletions client/css/font-awesome.min.css

Large diffs are not rendered by default.

0 comments on commit 7dbfa6b

Please sign in to comment.