PIPELINE:
Windows:
--Run Agisoft to create the point cloud and mesh
--export point cloud .obj (see comments below)
--export mesh .ply (see comments below)
Ubuntu:
--Note that Agisoft is also available for Linux
--Make sure, that the website template for the Potree project website generation is available at "PotreeConverter/PotreeConverter/resources". Since the potree converter requires a template. The template path is set in the convert_obj2xyz_potree.sh script
--Generate website with ./convert_obj2xyz_potree.sh point_cloud_file_without_postfix
--Add mesh/annotations/etc. to website (see comments below "Potree structure")
--------------------------------------------------------------------------------------------------------------------------------
####Comments####
EXPORTS:
agisoft coords problem (export pcd):
--export pointcloud as obj: only pts no normals and local coordinate form! uncheck normals
THREE visualization problem (export mesh):
--export mesh as ply in agisoft!( default is obj)
Potree structure:
--ADD ALL STUFF to the main HTML page / check model path, includes etc
--potree is only for point clouds
--potree can be called in as in java script part of the main html template (see entry below)
--meshes have to be independently treated as Potree only considers point clouds (see below)
--Everything is visualized with THREE: potree pcds and meshed etc.
Run potree website:
-- execute "gulp watch" at Potree location (where gulpfile.js is located at Potree location)
-- default: this will make all potree projects (at potree location) accessible from localhost
-- in order to allow access from outside, open gulpfile.js near line 104:
in "connect.server( ... ) set host as 0.0.0.0, i.e. >> server = connect.server({host:"0.0.0.0", port: 1234}); <<
by default (only localhost access) set >> server = connect.server({port: 1234}); <<
-- if required copy new potree projects in "potree location" in order to make project accessible
-- open potree project via the html file in the potree "location directory"
--------------------------------------------------------------------------------------------------------------------------------
WEBSITE in IFrame
--------------------------------------------------------------------------------------------------------------------------------
WEBSITE modifications
################################################################################################################################
MODIFY/REMOVE SLIDEBAR:
-- remove classification etc. from website located in bunker_valentin_page_template/libs/potree/sidebar.html
################################################################################################################################
ADD ANNOTATION (shows main part of potree pointcloud init as well): click first on a single point measure in model (of Potree shown in Browser) then add coords to annotation see below:
Potree.loadPointCloud("pointclouds/Bunker-1lapse-50m-SpeedManual-Pics2secs-A-GATE_ONLY_mesh_xyz_rgb/cloud.js", "Bunker-1lapse-50m-SpeedManual-Pics2secs-A-GATE_ONLY_mesh_xyz_rgb", e => {
let pointcloud = e.pointcloud;
let material = pointcloud.material;
viewer.scene.addPointCloud(pointcloud);
material.pointColorType = Potree.PointColorType.RGB; // any Potree.PointColorType.XXXX
material.size = 1;
material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
material.shape = Potree.PointShape.SQUARE;
//ADD ANNOTATION
----->>>>>> viewer.scene.addAnnotation( new THREE.Vector3(67.671, -89.121, -64.219), {"title": "TEST ANNOTATION"});
viewer.fitToScreen();
});
viewer.scene.addAnnotation( new THREE.Vector3(67.671, -89.121, -64.219), {"title": "TEST ANNO"});
//viewer.scene.addAnnotation( new THREE.Vector3(73.264, -86.802, -76.854), {"title": "Ecke1215",
// "actions": [{
// "icon": Potree.resourcePath + "/icons/goto.svg",
// "onclick": function(){
// //viewer.setScene(sceneSG);
//
// }
// }]
// });
{
let aTrees = new Potree.Annotation({
position: [73.264, -86.802, -76.854],
title: "Ecke33",
description: `Point cloud of a small section in Sorvilier, Switzerland.
Courtesy of sigeom.sa`,
});
aTrees.domElement.off("mouseenter");
aTrees.domElement.off("mouseleave");
aTrees.addEventListener("click", () => {
aTrees.setHighlighted(!aTrees.isHighlighted);
});
viewer.scene.annotations.add(aTrees);
}
################################################################################################################################
ADD MESH
HEADER:
var loader = new THREE.PLYLoader();
loader.load("models/stanford_bunny_reduced.ply", (geometry) => {
geometry.computeVertexNormals();
// place three instances of this bunny into the scene
let mesh1;
{
let material = new THREE.MeshNormalMaterial();
mesh1 = new THREE.Mesh( geometry, material );
mesh1.position.set(67.671, -89.121, -64.219);
mesh1.scale.multiplyScalar(10);
mesh1.rotation.set(Math.PI / 2, Math.PI, 0)
viewer.scene.scene.add(mesh1);
}
// Add entries to object list in sidebar
viewer.onGUILoaded(() => {
let tree = $(`#jstree_scene`);
let parentNode = "other";
let bunny1ID = tree.jstree('create_node', parentNode, {
"text": "Bunny 1",
"icon": `icons/triangle.svg`,
"data": mesh1
},
"last", false, false);
tree.jstree(mesh1.visible ? "check_node" : "uncheck_node", bunny1ID);
});
});
OR
var loader = new THREE.PLYLoader();
loader.load("models/Bunker-1lapse-50m-SpeedManual-Pics2secs-A-GATE_ONLY_mesh.ply", (geometry) => {
geometry.computeVertexNormals();
// place three instances of this bunny into the scene
let mesh1; {
let material = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0x111111,
shininess: 200,
vertexColors: THREE.VertexColors
})
mesh1 = new THREE.Mesh(geometry, material);
mesh1.position.set(0, 0, 0);
mesh1.scale.multiplyScalar(1);
//mesh1.rotation.set(Math.PI / 2, Math.PI, 0)
viewer.scene.scene.add(mesh1);
}
viewer.onGUILoaded(() => {
let tree = $(`#jstree_scene`);
let parentNode = "other";
let bunkerID = tree.jstree('create_node', parentNode, {
"text": "Bunker Surface Color",
"icon": `icons/triangle.svg`,
"data": mesh1
},
"last", false, false);
tree.jstree(mesh1.visible ? "check_node" : "uncheck_node", bunkerID);
});
});
var loader = new THREE.PLYLoader();
loader.load("models/Bunker-1lapse-50m-SpeedManual-Pics2secs-A-GATE_ONLY_mesh.ply", (geometry) => {
geometry.computeVertexNormals();
// place three instances of this bunny into the scene
let mesh1; {
let material = new THREE.MeshNormalMaterial();
mesh1 = new THREE.Mesh(geometry, material);
mesh1.position.set(0, 0, 0);
mesh1.scale.multiplyScalar(1);
//mesh1.rotation.set(Math.PI / 2, Math.PI, 0)
viewer.scene.scene.add(mesh1);
}
viewer.onGUILoaded(() => {
let tree = $(`#jstree_scene`);
let parentNode = "other";
let bunkerID = tree.jstree('create_node', parentNode, {
"text": "Bunker Surface Normals",
"icon": `icons/triangle.svg`,
"data": mesh1
},
"last", false, false);
tree.jstree(mesh1.visible ? "check_node" : "uncheck_node", bunkerID);
});
});
NO SCALE AND ROT EXAMPLE
var loader = new THREE.PLYLoader();
loader.load("scene_mesh_textured.ply", (geometry) => {
geometry.computeVertexNormals();
// place three instances of this bunny into the scene
let mesh1;
{
let material = new THREE.MeshNormalMaterial();
mesh1 = new THREE.Mesh( geometry, material );
mesh1.position.set(0,0,0);
mesh1.scale.multiplyScalar(1);
//mesh1.rotation.set(Math.PI / 2, Math.PI, 0)
viewer.scene.scene.add(mesh1);
}
});
################################################################################################################################
ADD COORD AXIS
axes = new THREE.AxisHelper( 100 );
viewer.scene.scene.add(axes );
################################################################################################################################
COLOR GRADIENTS
{ // Annotation with action icons
// Create title element with jquery
let schemes = [{
name: "SPECTRAL",
icon: `${Potree.resourcePath}/icons/gradients_spectral.png`
}, {
name: "YELLOW_GREEN",
icon: `${Potree.resourcePath}/icons/gradients_yellow_green.png`
}, {
name: "PLASMA",
icon: `${Potree.resourcePath}/icons/gradients_plasma.png`
}, {
name: "GRAYSCALE",
icon: `${Potree.resourcePath}/icons/gradients_grayscale.png`
}, {
name: "RAINBOW",
icon: `${Potree.resourcePath}/icons/gradients_rainbow.png`
}, ];
let elTitle = $(`Gradient Schemes:`);
for (let scheme of schemes) {
let button = $(``);
button.click(() => {
for (let pointcloud of viewer.scene.pointclouds) {
pointcloud.material.pointColorType = Potree.PointColorType.ELEVATION;
pointcloud.material.gradient = Potree.Gradients[scheme.name];
}
});
elTitle.append(button);
}
// Give the annotation a meaningful string representation for the sidebar
elTitle.toString = () => "Gradient Color Selection";
// Same as with other annotations, except title is a jquery object this time.
let aActions = new Potree.Annotation({
position: [0, 0, 0],
title: elTitle,
});
viewer.scene.annotations.add(aActions);
}
################################################################################################################################
line 479
pointcloud.material.pointColorType = Potree.PointColorType.ELEVATION;
pointcloud.material.gradient = Potree.Gradients["SPECTRAL"];
################################################################################################################################
ADD Camera target and position to annotation
1)open potree viewer (html file in potree project)
2)move to desired camera pose
3)copy camera pose and target from scene->objects->camera->properties
4)if using potree/annotations/annotation.txt simply copy/paste cam pose and tgt accordingly
5)else
let annotation = new Potree.Annotation({
position: curr_pos,
cameraPosition: curr_cam_pos,
cameraTarget: curr_cam_tgt,
title: curr_title,
description: curr_description,
});
viewer.scene.annotations.add(annotation);
###############################
move potree model to origin (https://github.com/potree/PotreeConverter/issues/74)
put this into the point cloud loader ... Potree.loadPointCloud(...
pointcloud.applyMatrix(new THREE.Matrix4().set(
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
));
pointcloud.moveToOrigin();
pointcloud.moveToGroundPlane();