fix:3d点云模块

main
zhoulexin 3 months ago
parent ecdbb44bc5
commit af698f336d

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>SUSTech POINTS</title> <title>标注实训平台</title>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="icon" type="image/png" href="/3Dpoints/static/icon2.png"> <link rel="icon" type="image/png" href="/3Dpoints/static/icon2.png">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
@ -57,8 +57,9 @@
</div> </div>
<div id="static-buttons"> <div id="static-buttons">
<div id="changed-mark" class="ui-button"> <span id="saveSuccess" style="color: green; display: none;"></span>
<div id='save-button'> <div id="changed-mark" class="ui-button" style="display: none;">
<div id='save-button' title="保存">
<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="svg-button"><g> <svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="svg-button"><g>
<path d="M 4 4 L 18 4 L 20 6 L 20 20 L 4 20 Z M 8 4 h 8 v 2 h -8 z M 6 10 h 12 V 18 h -12 z "></path> <path d="M 4 4 L 18 4 L 20 6 L 20 20 L 4 20 Z M 8 4 h 8 v 2 h -8 z M 6 10 h 12 V 18 h -12 z "></path>
</g></svg> </g></svg>
@ -68,7 +69,18 @@
<div id='changed-world-list'></div> <div id='changed-world-list'></div>
</div> </div>
</div> </div>
<div id="save-submit" class="ui-button" style="width: auto; display: none;">
提交
</div>
<div id="save-pass" class="ui-button" style="width: auto; display: none;">
通过
</div>
<div id="save-reject" class="ui-button" style="width: auto; display: none;">
打回
</div>
<div id="back" class="ui-button" style="width: auto;">
返回
</div>
<div id="log-button" class="ui-button"> <div id="log-button" class="ui-button">
<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" id="log-svg" class="svg-button"> <svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" id="log-svg" class="svg-button">
<g> <g>
@ -1260,17 +1272,17 @@
<div class="menu-button" id="exit">Exit</div> <div class="menu-button" id="exit">退出</div>
<div class="menu-button" id="prev">Previous</div> <!-- <div class="menu-button" id="prev">上一个</div> -->
<div class="menu-button" id="next">Next</div> <!-- <div class="menu-button" id="next">下一个</div> -->
<div class="menu-button" id="trajectory">Trajectory</div> <div class="menu-button" id="trajectory">轨迹</div>
<div class="menu-button" id="auto-annotate">Auto</div> <!-- <div class="menu-button" id="auto-annotate">自动</div> -->
<div class="menu-button" id="auto-annotate-translate-only">Auto (no rotation) </div> <!-- <div class="menu-button" id="auto-annotate-translate-only">自动(无旋转)</div> -->
<div class="menu-button" id="interpolate">Interpolate</div> <!-- <div class="menu-button" id="interpolate">插值</div> -->
<div class="menu-button" id="reload">Reload</div> <!-- <div class="menu-button" id="reload">重载</div> -->
<div class="menu-button" id="finalize">Finalize</div> <div class="menu-button" id="finalize">保存</div>
<!-- <div class="menu-button" id="save">Save</div> --> <!-- <div class="menu-button" id="save">Save</div> -->
@ -1336,7 +1348,6 @@
document.head.appendChild(script); document.head.appendChild(script);
}); });
} }
console.log(window.location.href)
try { try {
loadDynamicResources(); loadDynamicResources();
} catch (error) { } catch (error) {

@ -123,6 +123,7 @@ canvas {
color: inherit; color: inherit;
border-width: 0; border-width: 0;
display: inline-flex; display: inline-flex;
align-items: center;
} }
#object-category-selector, #object-category-selector,
@ -510,6 +511,7 @@ dynamic set obj-type css has higher priority than this one.
display: inline; display: inline;
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
color: #fff;
} }
.menu-button:hover { .menu-button:hover {
@ -616,6 +618,7 @@ dynamic set obj-type css has higher priority than this one.
} }
.ui-button { .ui-button {
cursor: pointer;
background-color: var(--widget-background-color); background-color: var(--widget-background-color);
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
@ -625,6 +628,7 @@ dynamic set obj-type css has higher priority than this one.
height: 20px; height: 20px;
width: 20px; width: 20px;
padding: 2px; padding: 2px;
margin: 0 5px;
} }
.ui-button:hover { .ui-button:hover {

@ -2,7 +2,7 @@ import * as THREE from "./lib/three.module.js";
import { globalObjectCategory } from "./obj_cfg.js"; import { globalObjectCategory } from "./obj_cfg.js";
import { saveWorldList } from "./save.js"; import { saveWorldList } from "./save.js";
import { intersect } from "./util.js"; import { intersect } from "./util.js";
import request from "./request.js"; import http from "./http.js";
function Annotation(sceneMeta, world, frameInfo) { function Annotation(sceneMeta, world, frameInfo) {
this.world = world; this.world = world;
@ -130,9 +130,7 @@ function Annotation(sceneMeta, world, frameInfo) {
if (b.follows) ann.follows = b.follows; if (b.follows) ann.follows = b.follows;
return ann; return ann;
}); });
anns.sort((a, b) => a.obj_id - b.obj_id); anns.sort((a, b) => a.obj_id - b.obj_id);
return anns; return anns;
}; };
@ -496,6 +494,7 @@ function Annotation(sceneMeta, world, frameInfo) {
// 标注信息 // 标注信息
this.load_annotation = function (on_load) { this.load_annotation = function (on_load) {
const microData = window.microApp.getData()
if (this.data.cfg.disableLabels) { if (this.data.cfg.disableLabels) {
on_load([]); on_load([]);
} else { } else {
@ -506,22 +505,35 @@ function Annotation(sceneMeta, world, frameInfo) {
if (this.readyState != 4) return; if (this.readyState != 4) return;
if (this.status == 200) { if (this.status == 200) {
let ann = _self.frameInfo.anno_to_boxes(this.responseText); // 未标注状态
if(!microData.labelState || microData.labelState === '0'){
document.getElementById("changed-mark").style.display = "block";
document.getElementById("save-submit").style.display = "block";
}
// 质检状态
if(microData.taskTag === '0'){
document.getElementById("save-pass").style.display = "block";
document.getElementById("save-reject").style.display = "block";
}
let ann = _self.frameInfo.anno_to_boxes(JSON.parse(this.responseText).data.label);
if (_self.world && _self.world.cameras) {
_self.world.cameras.setAnnotationData(JSON.parse(this.responseText).data);
}
if (_self.frameInfo) {
_self.frameInfo.setAnnotationData(JSON.parse(this.responseText).data);
}
on_load(ann); on_load(ann);
} }
// end of state change: it can be after some time (async) // end of state change: it can be after some time (async)
}; };
let frameId = this.frameInfo.frame?.frameId ?? this.frameInfo.frame
xhr.open( xhr.open(
"GET", "GET",
request + "/load_annotation" + `${http.requestHttp}/project/getFrameInfo?frameId=${frameId}`,
"?scene=" +
this.frameInfo.scene +
"&frame=" +
this.frameInfo.frame,
true true
); );
xhr.setRequestHeader('authorization', http.token);
xhr.send(); xhr.send();
} }
}; };

@ -513,7 +513,7 @@ function BoxEditorManager(
// next/prev call will not update onExit // next/prev call will not update onExit
this.onExit = onExit; this.onExit = onExit;
} }
let sceneName = sceneMeta.scene; let sceneName = sceneMeta.sceneId;
this.editingTarget.data = data; this.editingTarget.data = data;
this.editingTarget.sceneMeta = sceneMeta; this.editingTarget.sceneMeta = sceneMeta;
@ -1349,28 +1349,28 @@ function BoxEditorManager(
this.showTrajectory(); this.showTrajectory();
}; };
this.toolbox.querySelector("#reload").onclick = (e) => { // this.toolbox.querySelector("#reload").onclick = (e) => {
let selectedEditors = this.activeEditorList(); // let selectedEditors = this.activeEditorList();
this.reloadAnnotation(selectedEditors); // this.reloadAnnotation(selectedEditors);
}; // };
this.toolbox.querySelector("#interpolate").onclick = async () => { // this.toolbox.querySelector("#interpolate").onclick = async () => {
//this.boxOp.interpolate_selected_object(this.editingTarget.scene, this.editingTarget.objTrackId, ""); // //this.boxOp.interpolate_selected_object(this.editingTarget.scene, this.editingTarget.objTrackId, "");
let applyIndList = this.activeEditorList().map((e) => true); //all shoud be applied. // let applyIndList = this.activeEditorList().map((e) => true); //all shoud be applied.
this.interpolate(applyIndList); // this.interpolate(applyIndList);
}; // };
this.toolbox.querySelector("#auto-annotate").onclick = async () => { // this.toolbox.querySelector("#auto-annotate").onclick = async () => {
let applyIndList = this.activeEditorList().map((e) => true); //all shoud be applied. // let applyIndList = this.activeEditorList().map((e) => true); //all shoud be applied.
this.autoAnnotate(applyIndList); // this.autoAnnotate(applyIndList);
}; // };
this.toolbox.querySelector("#auto-annotate-translate-only").onclick = // this.toolbox.querySelector("#auto-annotate-translate-only").onclick =
async () => { // async () => {
let applyIndList = this.activeEditorList().map((e) => true); //all shoud be applied. // let applyIndList = this.activeEditorList().map((e) => true); //all shoud be applied.
this.autoAnnotate(applyIndList, "dontrotate"); // this.autoAnnotate(applyIndList, "dontrotate");
}; // };
this.toolbox.querySelector("#exit").onclick = () => { this.toolbox.querySelector("#exit").onclick = () => {
this.hide(); this.hide();
@ -1380,13 +1380,13 @@ function BoxEditorManager(
if (this.onExit) this.onExit(); if (this.onExit) this.onExit();
}; };
this.toolbox.querySelector("#next").onclick = () => { // this.toolbox.querySelector("#next").onclick = () => {
this.nextBatch(); // this.nextBatch();
}; // };
this.toolbox.querySelector("#prev").onclick = () => { // this.toolbox.querySelector("#prev").onclick = () => {
this.prevBatch(); // this.prevBatch();
}; // };
this.nextBatch = function () { this.nextBatch = function () {
let maxFrameIndex = this.editingTarget.sceneMeta.frames.length - 1; let maxFrameIndex = this.editingTarget.sceneMeta.frames.length - 1;

@ -2,6 +2,7 @@ import { World } from "./world.js";
import { Debug } from "./debug.js"; import { Debug } from "./debug.js";
import { logger } from "./log.js"; import { logger } from "./log.js";
import request from "./request.js"; import request from "./request.js";
import http from "./http.js";
// 请求数据集合 // 请求数据集合
class Data { class Data {
@ -10,10 +11,13 @@ class Data {
} }
async readSceneList() { async readSceneList() {
const req = new Request(request + "/get_all_scene_desc"); // const req = new Request(request + "/get_all_scene_desc");
const dataId = window.microApp.getData().dataId
const req = new Request(`${http.requestHttp}/project/getScene?dataId=${dataId}`);
let init = { let init = {
method: "GET", method: "GET",
//body: JSON.stringify({"points": data}) //body: JSON.stringify({"points": data})
headers: { "authorization": http.token },
}; };
// we defined the xhr // we defined the xhr
@ -25,10 +29,18 @@ class Data {
return response.json(); return response.json();
} }
}) })
.then((ret) => { .then((res) => {
console.log(ret); let obj = {}
this.sceneDescList = ret; if(res.code === 401){
return ret; window.location.href = '/login'
}
if(res.code === 200){
res.data.forEach(item=>{
obj[item.sceneName] = item.sceneId
})
}
this.sceneDescList = obj
return res;
}) })
.catch((reject) => { .catch((reject) => {
console.log("error read scene list!"); console.log("error read scene list!");
@ -50,7 +62,6 @@ class Data {
async getWorld(sceneName, frame, on_preload_finished) { async getWorld(sceneName, frame, on_preload_finished) {
// find in list // find in list
if (!this.meta[sceneName]) { if (!this.meta[sceneName]) {
await this.readSceneMetaData(sceneName); await this.readSceneMetaData(sceneName);
} }
@ -424,12 +435,16 @@ class Data {
if (this.status == 200) { if (this.status == 200) {
let sceneMeta = JSON.parse(this.responseText); let sceneMeta = JSON.parse(this.responseText);
self.meta[sceneName] = sceneMeta; sceneMeta.data.calib = JSON.parse(sceneMeta.data.calib);
self.meta[sceneName] = sceneMeta.data;
console.log(self.meta[sceneName] )
resolve(sceneMeta); resolve(sceneMeta);
} }
}; };
xhr.open("GET", `${request}/scenemeta?scene=${sceneName}`, true); // xhr.open("GET", `${request}/scenemeta?scene=${sceneName}`, true);
xhr.open("GET", `${http.requestHttp}/project/getSceneInfo?sceneId=${sceneName}`, true);
xhr.setRequestHeader('authorization', http.token);
xhr.send(); xhr.send();
}); });
} }

@ -26,6 +26,7 @@ import { globalKeyDownManager } from "./keydown_manager.js";
import { vector_range } from "./util.js"; import { vector_range } from "./util.js";
import { checkScene } from "./error_check.js"; import { checkScene } from "./error_check.js";
const microData = window.microApp.getData()
function Editor(editorUi, wrapperUi, editorCfg, data, name = "editor") { function Editor(editorUi, wrapperUi, editorCfg, data, name = "editor") {
// create logger before anything else. // create logger before anything else.
create_logger( create_logger(
@ -978,12 +979,12 @@ function Editor(editorUi, wrapperUi, editorCfg, data, name = "editor") {
if (!meta) { if (!meta) {
this.editorUi.querySelector("#frame-selector").innerHTML = this.editorUi.querySelector("#frame-selector").innerHTML =
"<option>结构</option>"; "<option>结构</option>";
meta = await this.data.readSceneMetaData(sceneName); let res = await this.data.readSceneMetaData(sceneName);
meta = res.data
} }
var frame_selector_str = meta.frames var frame_selector_str = meta.frames
.map(function (f) { .map(function (f) {
return "<option value=" + f + ">" + f + "</option>"; return "<option value=" + f.frameId + ">" + f.frameName + "</option>";
}) })
.reduce(function (x, y) { .reduce(function (x, y) {
return x + y; return x + y;
@ -1328,7 +1329,6 @@ function Editor(editorUi, wrapperUi, editorCfg, data, name = "editor") {
this.handleRightClick = function (event) { this.handleRightClick = function (event) {
// select new object // select new object
if (!this.data.world) { if (!this.data.world) {
return; return;
} }
@ -2396,7 +2396,7 @@ function Editor(editorUi, wrapperUi, editorCfg, data, name = "editor") {
// }; // };
this.on_load_world_finished = function (world) { this.on_load_world_finished = function (world) {
document.title = "SUSTech POINTS-" + world.frameInfo.scene; // document.title = "SUSTech POINTS-" + world.frameInfo.scene;
// switch view positoin // switch view positoin
this.moveAxisHelper(world); this.moveAxisHelper(world);
this.moveRangeCircle(world); this.moveRangeCircle(world);

@ -0,0 +1,3 @@
const fileHttp = window.location.hostname === 'localhost' ||
window.location.hostname === '192.168.5.177' ? 'http://192.168.5.10:9100/' : '/img/'
export default fileHttp

@ -1,5 +1,6 @@
import { CubeRefractionMapping } from "./lib/three.module.js"; import { CubeRefractionMapping } from "./lib/three.module.js";
import { saveWorldList } from "./save.js"; import { saveWorldList } from "./save.js";
import http from "./http.js";
var Header = function ( var Header = function (
ui, ui,
@ -44,14 +45,9 @@ var Header = function (
let scene_selector_str = "<option>场景</option>"; let scene_selector_str = "<option>场景</option>";
for (let scene in sceneDescList) { for (let scene in sceneDescList) {
if (data.sceneDescList[scene]) if (data.sceneDescList[scene])
scene_selector_str += scene_selector_str += `<option value="${data.sceneDescList[scene]}">
"<option value=" + ${scene}
scene + </option>`
">" +
scene +
" - " +
data.sceneDescList[scene].scene +
"</option>";
else else
scene_selector_str += scene_selector_str +=
"<option value=" + scene + ">" + scene + "</option>"; "<option value=" + scene + ">" + scene + "</option>";
@ -66,7 +62,13 @@ var Header = function (
let curentValue = this.sceneSelectorUi.value; let curentValue = this.sceneSelectorUi.value;
this.data.readSceneList().then((sceneDescList) => { this.data.readSceneList().then((sceneDescList) => {
this.updateSceneList(sceneDescList); let obj = {}
if(sceneDescList.code === 200){
sceneDescList.data.forEach(item=>{
obj[item.sceneName] = item.sceneId
})
}
this.updateSceneList(obj);
this.sceneSelectorUi.value = curentValue; this.sceneSelectorUi.value = curentValue;
}); });
}; };
@ -187,6 +189,60 @@ var Header = function (
this.ui.querySelector("#save-button").onclick = () => { this.ui.querySelector("#save-button").onclick = () => {
saveWorldList(this.data.worldList); saveWorldList(this.data.worldList);
}; };
this.ui.querySelector("#save-submit").onclick = () => {
let confirm = window.confirm("确认提交?")
const microData = window.microApp.getData()
if(confirm){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.status == 200){
console.log('提交成功')
window.microApp.dispatch({ type: 'pointCloudBack', time: new Date() })
}
}
xhr.open(
"POST",
`${http.requestHttp}/project/label`,
true
);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('authorization', http.token);
xhr.send(JSON.stringify({
dataId:microData.dataId,
type:1,
label:'',
taskId:microData.taskId,
}));
}
};
// 通过
this.ui.querySelector("#save-pass").onclick = () => {
qc(1)
};
// 打回
this.ui.querySelector("#save-reject").onclick = () => {
qc(0)
};
function qc(type){
const microData = window.microApp.getData()
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.status == 200){
window.microApp.dispatch({ type: 'pointCloudBack', time: new Date() })
}
}
xhr.open(
"POST",
`${http.requestHttp}/project/qc?dataId=${microData.dataId}&type=${type}&taskId=${microData.taskId}`,
true
);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('authorization', http.token);
xhr.send();
}
this.ui.querySelector("#back").onclick = () => {
window.microApp.dispatch({ type: 'pointCloudBack', time: new Date() })
};
}; };
export { Header }; export { Header };

@ -0,0 +1,9 @@
const http = {
requestHttp: location.host.indexOf('localhost:8080')!=-1 ||
location.host.indexOf('localhost:8081')!=-1 ||
location.host.indexOf('192.168.5.177:8080')!=-1 ||
location.host.indexOf('192.168.5.177:8081')!=-1 ?
'http://192.168.5.171:8080' : '/api',
token: `Bearer ${localStorage.getItem('token')}`
}
export default http

@ -532,6 +532,7 @@ class ImageContext extends MovableView {
// active img is set by global, it's not set sometimes. // active img is set by global, it's not set sometimes.
var img = this.world.cameras.getImageByName(this.name); var img = this.world.cameras.getImageByName(this.name);
console.log(img,'img+++++++++++++++++++++')
if (img) { if (img) {
svgimage.setAttribute("xlink:href", img.src); svgimage.setAttribute("xlink:href", img.src);
} }

@ -63,177 +63,188 @@ function Lidar(sceneMeta, world, frameInfo) {
}; };
this.preload = function (on_preload_finished) { this.preload = function (on_preload_finished) {
console.log('载入钱')
this.on_preload_finished = on_preload_finished; this.on_preload_finished = on_preload_finished;
var loader = new PCDLoader(); var loader = new PCDLoader();
var _self = this; var _self = this;
loader.load(
this.frameInfo.get_pcd_path(), // 定义实际的点云加载函数
//ok const doPcdLoad = function() {
function (pcd) { loader.load(
_self.points_parse_time = new Date().getTime(); _self.frameInfo.get_pcd_path(),
console.log( //ok
_self.points_load_time, function (pcd) {
_self.frameInfo.scene, _self.points_parse_time = new Date().getTime();
_self.frameInfo.frame, console.log(
"parse pionts ", _self.points_load_time,
_self.points_parse_time - _self.create_time, _self.frameInfo.scene,
"ms" _self.frameInfo.frame,
); "parse pionts ",
// if (_self.frameInfo.transform_matrix){ _self.points_parse_time - _self.create_time,
"ms"
// var arr = position;
// var num = position.length;
// var ni = 3;
// for (var i=0; i<num/ni; i++){
// var np = _self.frameInfo.transform_point(_self.frameInfo.transform_matrix, arr[i*ni+0], arr[i*ni+1], arr[i*ni+2]);
// arr[i*ni+0]=np[0];
// arr[i*ni+1]=np[1];
// arr[i*ni+2]=np[2];
// }
// //points.geometry.computeBoundingSphere();
// }
if (_self.data.cfg.enableFilterPoints) {
// do some filtering work here
pcd = _self.remove_high_ponts(pcd, _self.data.cfg.filterPointsZ);
}
let position = pcd.position;
// build geometry
_self.world.data.dbg.alloc();
var geometry = new THREE.BufferGeometry();
if (position.length > 0)
geometry.setAttribute(
"position",
new THREE.Float32BufferAttribute(position, 3)
);
let normal = pcd.normal;
// normal and colore are note used in av scenes.
if (normal.length > 0)
geometry.setAttribute(
"normal",
new THREE.Float32BufferAttribute(normal, 3)
); );
// if (_self.frameInfo.transform_matrix){
let color = pcd.color; // var arr = position;
if (color.length == 0) { // var num = position.length;
color = []; // var ni = 3;
// by default we set all points to same color
for (let i = 0; i < position.length; ++i) {
color.push(_self.data.cfg.point_brightness);
}
// if enabled intensity we color points by intensity.
if (
_self.data.cfg.color_points == "intensity" &&
pcd.intensity.length > 0
) {
// map intensity to color
for (var i = 0; i < pcd.intensity.length; ++i) {
let intensity = pcd.intensity[i];
intensity *= 8;
if (intensity > 1) intensity = 1.0; // for (var i=0; i<num/ni; i++){
// var np = _self.frameInfo.transform_point(_self.frameInfo.transform_matrix, arr[i*ni+0], arr[i*ni+1], arr[i*ni+2]);
// arr[i*ni+0]=np[0];
// arr[i*ni+1]=np[1];
// arr[i*ni+2]=np[2];
// }
//color.push( 2 * Math.abs(0.5-intensity)); // //points.geometry.computeBoundingSphere();
// }
color[i * 3] = intensity; if (_self.data.cfg.enableFilterPoints) {
color[i * 3 + 1] = intensity; // do some filtering work here
color[i * 3 + 2] = 1 - intensity; pcd = _self.remove_high_ponts(pcd, _self.data.cfg.filterPointsZ);
}
} }
// save color, in case color needs to be restored. let position = pcd.position;
pcd.color = color;
} // build geometry
_self.world.data.dbg.alloc();
geometry.setAttribute( var geometry = new THREE.BufferGeometry();
"color", if (position.length > 0)
new THREE.Float32BufferAttribute(color, 3) geometry.setAttribute(
); "position",
new THREE.Float32BufferAttribute(position, 3)
geometry.computeBoundingSphere(); );
// build material
let normal = pcd.normal;
var material = new THREE.PointsMaterial({ // normal and colore are note used in av scenes.
size: _self.data.cfg.point_size, if (normal.length > 0)
vertexColors: THREE.VertexColors, geometry.setAttribute(
}); "normal",
new THREE.Float32BufferAttribute(normal, 3)
);
let color = pcd.color;
if (color.length == 0) {
color = [];
// by default we set all points to same color
for (let i = 0; i < position.length; ++i) {
color.push(_self.data.cfg.point_brightness);
}
/* // if enabled intensity we color points by intensity.
if (
if ( color.length > 0 ) { _self.data.cfg.color_points == "intensity" &&
material.vertexColors = color; pcd.intensity.length > 0
} else { ) {
//material.color.setHex(0xffffff); // map intensity to color
material.color.r = 0.6; for (var i = 0; i < pcd.intensity.length; ++i) {
material.color.g = 0.6; let intensity = pcd.intensity[i];
material.color.b = 0.6; intensity *= 8;
}
*/
//material.size = 2; if (intensity > 1) intensity = 1.0;
material.sizeAttenuation = false;
// build mesh //color.push( 2 * Math.abs(0.5-intensity));
var mesh = new THREE.Points(geometry, material); color[i * 3] = intensity;
mesh.name = "pcd"; color[i * 3 + 1] = intensity;
color[i * 3 + 2] = 1 - intensity;
}
}
//return mesh; // save color, in case color needs to be restored.
// add to parent. pcd.color = color;
_self.world.webglGroup.add(mesh); }
_self.points = mesh; geometry.setAttribute(
_self.pcd = pcd; "color",
//_self.points_backup = mesh; new THREE.Float32BufferAttribute(color, 3)
);
_self.build_points_index(); geometry.computeBoundingSphere();
_self.points_load_time = new Date().getTime(); // build material
var material = new THREE.PointsMaterial({
size: _self.data.cfg.point_size,
vertexColors: THREE.VertexColors,
});
/*
if ( color.length > 0 ) {
material.vertexColors = color;
} else {
//material.color.setHex(0xffffff);
material.color.r = 0.6;
material.color.g = 0.6;
material.color.b = 0.6;
}
*/
//material.size = 2;
material.sizeAttenuation = false;
// build mesh
var mesh = new THREE.Points(geometry, material);
mesh.name = "pcd";
//return mesh;
// add to parent.
_self.world.webglGroup.add(mesh);
_self.points = mesh;
_self.pcd = pcd;
//_self.points_backup = mesh;
_self.build_points_index();
_self.points_load_time = new Date().getTime();
console.log(
_self.points_load_time,
_self.frameInfo.scene,
_self.frameInfo.frame,
"loaded pionts ",
_self.points_load_time - _self.create_time,
"ms"
);
console.log( _self._afterPreload();
_self.points_load_time, },
_self.frameInfo.scene,
_self.frameInfo.frame,
"loaded pionts ",
_self.points_load_time - _self.create_time,
"ms"
);
_self._afterPreload(); // on progress,
}, function () {},
// on progress, // on error
function () {}, function () {
//error
console.log("load pcd failed.");
_self._afterPreload();
},
// on error // on file loaded
function () { function () {
//error _self.points_readfile_time = new Date().getTime();
console.log("load pcd failed."); console.log(
_self._afterPreload(); _self.points_load_time,
}, _self.frameInfo.scene,
_self.frameInfo.frame,
"read file ",
_self.points_readfile_time - _self.create_time,
"ms"
);
}
);
};
// on file loaded // 如果已经有注释数据,立即加载点云
function () { if (this.frameInfo.annotationData !== null) {
_self.points_readfile_time = new Date().getTime(); doPcdLoad();
console.log( } else {
_self.points_load_time, // 否则保存回调,等待注释数据到达后再执行
_self.frameInfo.scene, this.frameInfo.loadCallback = doPcdLoad;
_self.frameInfo.frame, }
"read file ",
_self.points_readfile_time - _self.create_time,
"ms"
);
}
);
}; };
this.deleteAll = function () { this.deleteAll = function () {

@ -1,5 +1,6 @@
import * as THREE from "./lib/three.module.js"; import * as THREE from "./lib/three.module.js";
const microData = window.microApp.getData()
function Mouse( function Mouse(
view, view,
op_state, op_state,
@ -24,6 +25,10 @@ function Mouse(
this.domElement.addEventListener( this.domElement.addEventListener(
"mousedown", "mousedown",
(e) => { (e) => {
// 已标注或者质检中不可编辑
if(microData.labelState === '1' || microData.taskTag === '0'){
return
}
this.onMouseDown(e); this.onMouseDown(e);
}, },
true true
@ -85,6 +90,7 @@ function Mouse(
}; };
this.onMouseDown = function (event) { this.onMouseDown = function (event) {
in_select_mode = false; in_select_mode = false;
if (event.which == 3) { if (event.which == 3) {

@ -1,4 +1,4 @@
const request = location.host.indexOf('localhost:8080')!=-1 ? const request = location.host.indexOf('localhost:8080')!=-1 || location.host.indexOf('192.168.5.177:8080')!=-1 ?
'/3d-point-cloud' : '/3d-point-cloud' :
location.host.indexOf('localhost:8081')!=-1 || location.host.indexOf('192.168.5.177:8081')!=-1 ? location.host.indexOf('localhost:8081')!=-1 || location.host.indexOf('192.168.5.177:8081')!=-1 ?
'' : '/3Dpoints' '' : '/3Dpoints'

@ -2,6 +2,7 @@ import { Editor } from "./editor.js";
import { checkScene } from "./error_check.js"; import { checkScene } from "./error_check.js";
import { logger } from "./log.js"; import { logger } from "./log.js";
import request from "./request.js"; import request from "./request.js";
import http from "./http.js";
function reloadWorldList(worldList, done) { function reloadWorldList(worldList, done) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
@ -86,23 +87,28 @@ function doSaveWorldList(worldList, done) {
} }
} }
console.log(worldList.length, "frames");
let ann = worldList.map((w) => { let ann = worldList.map((w) => {
return { return {
scene: w.frameInfo.scene, frameId: w.frameInfo.frame?.frameId??w.frameInfo.frame,
frame: w.frameInfo.frame, label: JSON.stringify(w.annotation.toBoxAnnotations()),
annotation: w.annotation.toBoxAnnotations(),
}; };
}); });
console.log(ann,'ann')
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("POST", request + "/saveworldlist", true); xhr.open("POST", http.requestHttp + "/project/frameSave", true);
xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Content-Type","application/json")
xhr.setRequestHeader('authorization', http.token);
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
if (this.readyState != 4) return; if (this.readyState != 4) return;
if (this.status == 200) { if (this.status == 200) {
document.getElementById('saveSuccess').style.display = "block";
document.getElementById('saveSuccess').innerText = "保存成功!";
let timeout = setTimeout(() => {
document.getElementById('saveSuccess').style.display = "none";
clearTimeout(timeout);
}, 3000);
worldList.forEach((w) => { worldList.forEach((w) => {
w.annotation.resetModified(); w.annotation.resetModified();
}); });
@ -123,13 +129,22 @@ function doSaveWorldList(worldList, done) {
`save failed, status : ${this.status}` `save failed, status : ${this.status}`
); );
} }
// end of state change: it can be after some time (async)
}; };
const uniqueArray = deduplicatePreferString(ann)
var b = JSON.stringify(ann); xhr.send(JSON.stringify({frameSaveDTOList:uniqueArray}));
//console.log(b); }
xhr.send(b); function deduplicatePreferString(array) {
const map = new Map();
array.forEach(item => {
const key = String(item.id);
// 如果还没有这个key或者已存在的不是string类型而当前的是string类型
if (!map.has(key) || (typeof map.get(key).id !== 'string' && typeof item.id === 'string')) {
map.set(key, item);
}
});
return Array.from(map.values());
} }
// function saveWorld(world, done){ // function saveWorld(world, done){

@ -7,6 +7,7 @@ import { Annotation } from "./annotation.js";
import { EgoPose } from "./ego_pose.js"; import { EgoPose } from "./ego_pose.js";
import { logger } from "./log.js"; import { logger } from "./log.js";
import request from "./request.js"; import request from "./request.js";
import fileHttp from "./fileHttp.js";
import { import {
euler_angle_to_rotate_matrix, euler_angle_to_rotate_matrix,
euler_angle_to_rotate_matrix_3by3, euler_angle_to_rotate_matrix_3by3,
@ -21,12 +22,14 @@ function FrameInfo(data, sceneMeta, sceneName, frame) {
this.dir = ""; this.dir = "";
this.scene = sceneName; this.scene = sceneName;
this.frame = frame; this.frame = frame;
this.annotationData = null;
this.pcd_ext = ""; this.pcd_ext = "";
this.loadCallback = null;
(this.frame_index = this.sceneMeta.frames.findIndex(function (x) { (this.frame_index = this.sceneMeta.frames.findIndex(function (x) {
return x == frame; return x == frame;
})), })),
(this.transform_matrix = this.sceneMeta.point_transform_matrix), (this.transform_matrix = this.sceneMeta.point_transform_matrix),
(this.annotation_format = this.sceneMeta.boxtype), //xyz(24 number), csr(center, scale, rotation, 9 number) (this.annotation_format = this.sceneMeta.boxType), //xyz(24 number), csr(center, scale, rotation, 9 number)
// this.set = function(scene, frame_index, frame, transform_matrix, annotation_format){ // this.set = function(scene, frame_index, frame, transform_matrix, annotation_format){
// this.scene = scene; // this.scene = scene;
// this.frame = frame; // this.frame = frame;
@ -36,15 +39,18 @@ function FrameInfo(data, sceneMeta, sceneName, frame) {
// }; // };
(this.get_pcd_path = function () { (this.get_pcd_path = function () {
if (this.annotationData) {
return fileHttp + this.annotationData.lidarPcdPath;
}
return ( return (
request + "/data/" + this.scene + "/lidar/" + this.frame + this.sceneMeta.lidar_ext request + "/data/" + this.scene + "/lidar/" + this.frame + this.sceneMeta.lidarExt
); );
}); });
this.get_radar_path = function (name) { this.get_radar_path = function (name) {
return `${request}/data/${this.scene}/radar/${name}/${this.frame}${this.sceneMeta.radar_ext}`; return `${request}/data/${this.scene}/radar/${name}/${this.frame}${this.sceneMeta.radarExt}`;
}; };
this.get_aux_lidar_path = function (name) { this.get_aux_lidar_path = function (name) {
return `${request}/data/${this.scene}/aux_lidar/${name}/${this.frame}${this.sceneMeta.radar_ext}`; return `${request}/data/${this.scene}/aux_lidar/${name}/${this.frame}${this.sceneMeta.radarExt}`;
}; };
this.get_anno_path = function () { this.get_anno_path = function () {
@ -55,6 +61,17 @@ function FrameInfo(data, sceneMeta, sceneName, frame) {
} }
}; };
// 设置注释数据并触发回调
this.setAnnotationData = function(data) {
this.annotationData = data;
// 如果已经有加载回调但尚未执行,则执行它
if (this.loadCallback && !this.loadCallback.executed) {
this.loadCallback.executed = true;
this.loadCallback();
}
};
this.anno_to_boxes = function (text) { this.anno_to_boxes = function (text) {
var _self = this; var _self = this;
if (this.annotation_format == "psr") { if (this.annotation_format == "psr") {
@ -166,6 +183,11 @@ function FrameInfo(data, sceneMeta, sceneName, frame) {
function Images(sceneMeta, sceneName, frame) { function Images(sceneMeta, sceneName, frame) {
this.loaded = function () { this.loaded = function () {
// 如果没有相机名称,则认为已加载完成
if (!this.names || this.names.length === 0) {
return true;
}
for (var n in this.names) { for (var n in this.names) {
if (!this.loaded_flag[this.names[n]]) return false; if (!this.loaded_flag[this.names[n]]) return false;
} }
@ -175,61 +197,94 @@ function Images(sceneMeta, sceneName, frame) {
this.names = sceneMeta.camera; //["image","left","right"], this.names = sceneMeta.camera; //["image","left","right"],
this.loaded_flag = {}; this.loaded_flag = {};
// this.active_name = ""; this.content = {};
// this.active_image = function(){ this.on_all_loaded = null;
// return this.content[this.active_name]; this.annotationData = null;
// }; this.sceneName = sceneName;
this.frame = frame;
this.sceneMeta = sceneMeta;
this.loadCallback = null;
this.active_name = null;
this.getImageByName = function (name) { this.getImageByName = function (name) {
return this.content[name]; return this.content[name];
}; };
// this.activate = function(name){ // 设置注释数据并触发图像加载
// this.active_name = name; this.setAnnotationData = function(data) {
// }; this.annotationData = data;
this.content = {}; // 如果已经有加载回调但尚未执行,则执行它
this.on_all_loaded = null; if (this.loadCallback && !this.loadCallback.executed) {
this.loadCallback.executed = true;
this.loadCallback();
}
};
(this.load = function (on_all_loaded, active_name) { this.load = function (on_all_loaded, active_name) {
this.on_all_loaded = on_all_loaded; this.on_all_loaded = on_all_loaded;
this.active_name = active_name;
// if global camera not set, use first camera as default.
// if (active_name.length > 0)
// this.active_name = active_name;
// else if (this.names && this.names.length>0)
// this.active_name = this.names[0];
var _self = this; var _self = this;
// 定义实际的图像加载函数
const doImageLoad = function() {
// 如果 global camera 未设置,使用第一个相机作为默认
// if (active_name.length > 0)
// this.active_name = active_name;
// else if (this.names && this.names.length>0)
// this.active_name = this.names[0];
if (_self.names) {
_self.names.forEach(function (cam) {
_self.content[cam] = new Image();
_self.content[cam].onload = function () {
_self.loaded_flag[cam] = true;
_self.on_image_loaded();
};
_self.content[cam].onerror = function () {
_self.loaded_flag[cam] = true;
_self.on_image_loaded();
};
// 使用注释数据构造图像路径(如果可用)
if (_self.annotationData) {
_self.content[cam].src = fileHttp + _self.annotationData[`${cam}ImgPath`]
} else {
// 回退到原来的路径
_self.content[cam].src =
"data/example/camera/" +
cam +
"/000965" +
_self.sceneMeta.cameraExt;
}
console.log("image set", _self.content[cam].src);
});
} else {
// 没有相机名称,直接调用完成回调
if (_self.on_all_loaded) {
_self.on_all_loaded();
}
}
};
if (this.names) { // 如果已经有注释数据,立即加载图像
this.names.forEach(function (cam) { if (this.annotationData) {
_self.content[cam] = new Image(); doImageLoad();
_self.content[cam].onload = function () { } else {
_self.loaded_flag[cam] = true; // 否则保存回调,等待注释数据到达后再执行
_self.on_image_loaded(); this.loadCallback = doImageLoad;
};
_self.content[cam].onerror = function () {
_self.loaded_flag[cam] = true;
_self.on_image_loaded();
};
_self.content[cam].src =
"data/" +
sceneName +
"/camera/" +
cam +
"/" +
frame +
sceneMeta.camera_ext;
console.log("image set");
});
} }
}), };
(this.on_image_loaded = function () {
if (this.loaded()) { this.on_image_loaded = function () {
if (this.loaded()) {
if (this.on_all_loaded) {
this.on_all_loaded(); this.on_all_loaded();
} }
}); }
};
} }
function World(data, sceneName, frame, coordinatesOffset, on_preload_finished) { function World(data, sceneName, frame, coordinatesOffset, on_preload_finished) {

Loading…
Cancel
Save