소스 검색

transfromationTool换样式加功能。(用于裁剪).准备把剪裁下载的control换成firstPer的

xzw 2 년 전
부모
커밋
9b175019db

+ 9 - 5
src/ExtendPointCloudOctree.js

@@ -82,13 +82,17 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
      
    //panoEdit时比预测值小很多?
      
-    testMaxNodeLevel(){//手动使maxLevel达到最高,从而迫使updateNodeMaxLevel。  因为Potree.settings.pointDensity 不为 'high'时,maxLevel不是所加载的最高,就很容易加载不出下一个层级,导致无法知道nodeMaxLevel
+    testMaxNodeLevel(camera){//手动使maxLevel达到最高,从而迫使updateNodeMaxLevel。  因为Potree.settings.pointDensity 不为 'high'时,maxLevel不是所加载的最高,就很容易加载不出下一个层级,导致无法知道nodeMaxLevel
         if(this.testMaxNodeLevelDone ) return
         //if(this.nodeMaxLevel > this.nodeMaxLevelPredict.min  )return 
         
         
         if( this.nodeMaxLevel==0 )return true
-        if( !viewer.atDatasets.includes(this))return true //否则老远就count++
+        if(camera.type == "OrthographicCamera"){
+            if(!Potree.Utils.isInsideFrustum(this.pcoGeometry.tightBoundingBox, camera)){
+                return true 
+            }    
+        }else if( !viewer.atDatasets.includes(this))return true //否则老远就count++
         
         let levels = this.visibleNodes.map(e=>e.getLevel())
         let actMaxLevel = Math.max.apply(null, levels) //实际加载到的最高的node level
@@ -509,7 +513,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             }else{
                 
                 let base = this.material.spacing / Math.pow(2, this.maxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2.  (不同场景还是会有偏差)
-                base *= this.nodeMaxLevel > 0 ? Math.max(0.1, Math.pow(this.maxLevel / this.nodeMaxLevel, 1.3)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙
+                base *= this.nodeMaxLevel > 0 ? Math.max(0.1, Math.pow(this.maxLevel / this.nodeMaxLevel, 1.4)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙(但是ortho是不用缩小的,如果能分开判断就好了)
 
                 this.material.size = base * 5 * num/*  * window.devicePixelRatio */
                 //在t-8BCqxQAr93 会议室 和 t-e2Kb2iU 隧道 两个场景里调节,因为它们的spacing相差较大,观察会议室墙壁的龟裂程度
@@ -553,8 +557,8 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
                 this.material.opacity = value
             }else{
                 if(Potree.settings.sizeFitToLevel){//按照点云质量来调整的版本:
-                    let base = this.material.spacing / Math.pow(1.4, this.maxLevel) //随着level提高,点云重叠几率增多
-                    let minBase = this.material.spacing / Math.pow(1.4, this.nodeMaxLevel)
+                    let base = this.material.spacing / Math.pow(1.5, this.maxLevel) //随着level提高,点云重叠几率增多
+                    let minBase = this.material.spacing / Math.pow(1.5, this.nodeMaxLevel)
                     let ratio = Math.min(1 / base, 1 / minBase / 3) //ratio为一个能使opacity不大于1 的 乘量,minBase要除以一个数,该数调越大减弱效果越强。level越低opacity和面板越接,level越高效果越弱,以减免过度重叠后的亮度。
                     this.material.opacity = base * ratio * num
                     if(!canMoreThanOne){

+ 1 - 1
src/PotreeRendererNew.js

@@ -1297,7 +1297,7 @@ export class Renderer {
 			
 			if(camera instanceof THREE.OrthographicCamera){
 				shader.setUniform("uUseOrthographicCamera", true);
-				shader.setUniform("uOrthoWidth", camera.right - camera.left); 
+				shader.setUniform("uOrthoWidth", (camera.right - camera.left) / camera.zoom); //改
 				shader.setUniform("uOrthoHeight", camera.top - camera.bottom);
 			}else{
 				shader.setUniform("uUseOrthographicCamera", false);

+ 6 - 4
src/custom/modules/clipModel/Clip.js

@@ -335,12 +335,14 @@ var Clip = {
     } 
     
    
-    /* 
-    裁剪点云时,2D界面显示全部平面图,按楼层切换显示。 
-     */
     
 }
 
 
 
-export {Clip} 
+export {Clip} 
+
+
+/* 
+裁剪点云时,2D界面显示全部平面图,按楼层切换显示。 
+ */

+ 1 - 1
src/custom/modules/mergeModel/MergeEditor.js

@@ -58,7 +58,7 @@ let MergeEditor = {
             let ground = this.ground = new InfiniteGridHelper(1, 10000, new THREE.Color('#fff'), 10000, 0.2, 0.3)
             viewer.scene.scene.add(ground) 
             //再加两条线否则在正侧边看不到
-            let line1 = LineDraw.createLine([new THREE.Vector3(-10000, 0, 0),new THREE.Vector3(10000, 0, 0) ], {color:'#666', dontAlwaysSeen:true})
+            let line1 = LineDraw.createLine([new THREE.Vector3(-10000, 0, 0),new THREE.Vector3(10000, 0, 0) ], {color:'#666', })
             let line2 = LineDraw.createLine([new THREE.Vector3(0, -10000, 0),new THREE.Vector3(0, 10000, 0) ], {mat:line1.material})
             ground.renderOrder = Potree.config.renderOrders.model + 1//line1.renderOrder + 1  //要比模型低,否则模型透明时效果不对
             ground.add(line1)

+ 24 - 11
src/custom/modules/panoEdit/panoEditor.js

@@ -34,10 +34,18 @@ const pointColor = {
     selected:"#c60",
     default:'#17c'
 }
-const opacitys = {
-    default:1.3,
-    selected: 2.0
-}
+const opacitys = {//点云透明度
+    'topView':{
+        default:0.4,
+        selected: 0.6
+    },
+    'sideView':{//侧面重叠概率高
+        default:0.2,
+        selected: 0.5
+    }, 
+}//调这么低是因为有的重叠边缘太亮了
+
+
 const cameraProps = [ 
     { 
         name : 'top',    
@@ -368,7 +376,7 @@ class PanoEditor extends THREE.EventDispatcher{
             viewer.scene.pointclouds.forEach(e=>{
                 e.material.activeAttributeName = 'rgba' 
                 e.material.useFilterByNormal = false  
-                e.changePointOpacity(1,true)
+                e.changePointOpacity(1 )
                  
             })
             viewer.updateVisible(viewer.reticule, 'force', true)
@@ -475,11 +483,11 @@ class PanoEditor extends THREE.EventDispatcher{
                 e.material.activeAttributeName = 'color' 
                 e.material.useFilterByNormal = true  //defines :  use_filter_by_normal  attenuated_opacity
                       
-                
+                let opaProp = name == 'top' ? opacitys.topView : opacitys.sideView 
                 if(this.selectedPano && this.selectedClouds.includes(e) /* this.selectedPano.pointcloud == e */){
-                    e.changePointOpacity(opacitys.selected,true)
+                    e.changePointOpacity(opaProp.selected,true)
                 }else{
-                    e.changePointOpacity(opacitys.default,true)
+                    e.changePointOpacity(opaProp.default,true)
                 }
                 
             })
@@ -1066,6 +1074,8 @@ class PanoEditor extends THREE.EventDispatcher{
         if(this.selectedPano == pano && !force)return
         
         let lastSeletedPano = this.selectedPano
+        let opaProp = this.activeViewName == 'top' ? opacitys.topView : opacitys.sideView 
+        
         if(this.selectedPano){ 
             
             this.selectedPano.circle.material = circleMats['default' + '_'+ this.getPanoRtkState(this.selectedPano) ] 
@@ -1074,13 +1084,16 @@ class PanoEditor extends THREE.EventDispatcher{
             if(this.activeViewName == 'mainView'){
                  
             }else{
+                
                 this.selectedClouds.forEach(e=>{
-                    e.changePointOpacity(opacitys.default,true)
+                    e.changePointOpacity(opaProp.default,true)
                     e.material.color = pointColor.default;  
                 })
             }
              
         }
+        
+         
      
         this.selectedPano = pano || null
         
@@ -1094,7 +1107,7 @@ class PanoEditor extends THREE.EventDispatcher{
                 
             }else{
                 this.selectedClouds.forEach(e=>{
-                    e.changePointOpacity(opacitys.selected,true)
+                    e.changePointOpacity(opaProp.selected,true)
                     e.material.color = pointColor.selected;  
                 })
             }
@@ -1146,7 +1159,7 @@ class PanoEditor extends THREE.EventDispatcher{
             //假设每个pointcloud所带的点个数大致相同,那么当可见点云个数越多,所能展示的level越低,否则因总个数超过budget的话密度会参差不齐。
             let visiCount = viewer.scene.pointclouds.filter(e=>e.visible).length
             let maxCount = 70, minCount = 1,  minPer = 0.4, maxPer = 1
-            percent = maxPer - ( maxPer - minPer) * THREE.Math.clamp((visiCount - minCount)  / (maxCount - minCount),0,1) //dis2d越大,角度要越小  
+            percent = maxPer - ( maxPer - minPer) * THREE.Math.clamp((visiCount - minCount)  / (maxCount - minCount),0,1)   
             //pointcloud.changePointSize()
             //console.log('updatePointLevels', percent, visiCount) 
         

+ 44 - 23
src/custom/modules/panos/Images360.js

@@ -62,15 +62,30 @@ export class Images360 extends THREE.EventDispatcher{
         this.cubePanos = [];
         
         
-         
-        this.cube = new THREE.Mesh(new THREE.BoxBufferGeometry(1,1,1,1),new ModelTextureMaterial());
-        viewer.updateVisible(this.cube,'showSkybox', false )
+        {
+            this.cube = new THREE.Mesh(new THREE.BoxBufferGeometry(1,1,1,1),new ModelTextureMaterial());
+            viewer.updateVisible(this.cube,'showSkybox', false )
+             
+            this.cube.layers.set(Potree.config.renderLayers.skybox)
+            this.cube.name = 'skyboxCube'
+            viewer.scene.scene.add(this.cube)
+        }
+        if(Potree.settings.testCube){
+            this.cubeTest = this.cube.clone() 
+            this.cubeTest.material = new THREE.MeshBasicMaterial({
+                wireframe:true,
+                color:'#FF3377',
+                transparent:true,
+                opacity:0.7,
+                depthWrite:false,
+                depthTest:false,
+            }) 
+            viewer.scene.scene.add(this.cubeTest)
+            this.cubeTest.visible = true
+        }
         
+
          
-        this.cube.layers.set(Potree.config.renderLayers.skybox)
-        this.cube.name = 'skyboxCube'
-        viewer.scene.scene.add(this.cube)
-          
       
 		this._visible = true;
 		 
@@ -2008,10 +2023,11 @@ export class Images360 extends THREE.EventDispatcher{
             this.cube.geometry = geo
             this.cube.scale.set(1,1,1);
             this.cube.position.set(0,0,0)
-              
-         
-            //this.cube.scale.set(100,100,100);
-            //this.cube.position.copy(pano1.position).multiplyScalar(-100)   
+            
+            if(Potree.settings.testCube){
+                this.cubeTest.geometry = geo
+            }
+             
         }else{ 
             
             useBound(getPanoBound(pano0)) 
@@ -2228,7 +2244,7 @@ export class Images360 extends THREE.EventDispatcher{
 
     isNeighbour(pano0, pano1){//是否之间没有遮挡(在加载visibles之前,自己算) 最好pano0是currentPano
          
-        if(!pano0 || !pano1)return
+        if(!pano0 || !pano1 )return
         
         let margin = 0.1;
         
@@ -2298,20 +2314,25 @@ export class Images360 extends THREE.EventDispatcher{
                     } */
                 }    
             }else{
-                //使用点云判断(有深度贴图时不会执行到这)
-                ifNeighbour = !viewer.inputHandler.ifBlockedByIntersect(pano1.position, margin, true, pano0.position)
-                console.log('使用点云判断')
-                if(ifNeighbour){//点云模式下未加载的点云会判断为true
-                    let dir = new THREE.Vector3().subVectors(pano1.position,pano0.position).normalize()
-                    let dis = pano1.position.distanceTo(pano0.position)
-                    let hfov = cameraLight.getHFOVForCamera(viewer.mainViewport.camera , true  );
-                    let max = Math.cos(THREE.Math.degToRad(10))
-                    let min = Math.cos(THREE.Math.degToRad(80))
-                    if(this.getDirection().dot(dir) < THREE.Math.clamp(Math.cos(hfov/2/* THREE.Math.degToRad(40) */) * dis / 10, min, max )){//距离越远要求和视线角度越接近
-                        ifNeighbour = undefined //不确定
+                if(this.panos.length > 20){
+                    ifNeighbour = true  //数量过多会卡
+                }else{
+                    //使用点云判断(有深度贴图时不会执行到这)
+                    ifNeighbour = !viewer.inputHandler.ifBlockedByIntersect(pano1.position, margin, true, pano0.position)
+                    console.log('使用点云判断')
+                    if(ifNeighbour){//点云模式下未加载的点云会判断为true
+                        let dir = new THREE.Vector3().subVectors(pano1.position,pano0.position).normalize()
+                        let dis = pano1.position.distanceTo(pano0.position)
+                        let hfov = cameraLight.getHFOVForCamera(viewer.mainViewport.camera , true  );
+                        let max = Math.cos(THREE.Math.degToRad(10))
+                        let min = Math.cos(THREE.Math.degToRad(80))
+                        if(this.getDirection().dot(dir) < THREE.Math.clamp(Math.cos(hfov/2/* THREE.Math.degToRad(40) */) * dis / 10, min, max )){//距离越远要求和视线角度越接近
+                            ifNeighbour = undefined //不确定
+                        }
                     }
                 }
                 map0[pano1.id] = map1[pano0.id] = ifNeighbour //写简单点
+                
             }
             
                                                                       

+ 34 - 6
src/custom/objects/Axis.js

@@ -2,7 +2,11 @@
 
 import * as THREE from "../../../libs/three.js/build/three.module.js"; 
 import {MeshDraw,LineDraw} from '../utils/DrawUtil.js'
- 
+import {TextSprite} from "./TextSprite.js";
+
+
+
+
 /*  
 
                  z   
@@ -20,12 +24,22 @@ import {MeshDraw,LineDraw} from '../utils/DrawUtil.js'
 var lineLen = 2, stemLen = 4, arrowLen = 2, lineDisToStem = 5;
 var opacity = 0.5
 export default class Axis extends THREE.Object3D {// 坐标轴
-	constructor (position) {
+	constructor () {
 		super()
         this.getArrow() 
         this.createArrows()
         //this.position.copy(position) 点云的中心点就是在(0,0,0)
         //this.scale.set(2,2,2)
+        
+        /* viewer.addEventListener('camera_changed', e => {
+            if(e.viewport.name != 'MainView')return //只调整mainView,否则需要每次渲染前调整。缺点:地图上的大小变来变去
+            let s = Potree.math.getScaleForConstantSize( {//规定下最小最大像素 
+                width2d:50,    camera:e.camera , position:this.position,
+                resolution: e.viewport.resolution//2
+            }) 
+            this.scale.set(s,s,s)
+        }) */
+        
     }
     getArrow(){
         var arrowGroup = new THREE.Object3D()
@@ -55,14 +69,14 @@ export default class Axis extends THREE.Object3D {// 坐标轴
         var material = new THREE.MeshBasicMaterial({color:"#00d7df",side:2,transparent:true,opacity:0.8, depthWrite:false});
         let axis = Object.keys(Potree.config.axis)
         axis.forEach((axisText)=>{
-            let color =  Potree.config.axis[axisText].color
+            let color = new THREE.Color().set(Potree.config.axis[axisText].color)
             var group = this.arrowGroup.clone()
             
             group.children.forEach(e=>{
                 e.material = e.material.clone()
                 /* e.material.opacity = opacity
                 e.material.transparent = true */
-                e.material.color.set(color)
+                e.material.color.copy(color)
             })  
             
             var label = this.createLabel(axisText, color)  
@@ -80,8 +94,22 @@ export default class Axis extends THREE.Object3D {// 坐标轴
         }) 
         
     }
-
+    
     createLabel(text,color){
+        let label = new TextSprite({  //无法解决 因其祖先有设定quaternion, 无法对着镜头
+            backgroundColor: {r: 0, g: 0, b: 0, a:0},
+            textColor: {r: color.r * 255, g: color.g*255, b: color.b*255, a:1},
+            fontsize:120, 
+            //useDepth : true ,
+            renderOrder : 5,// pickOrder:5,  
+             
+             text, name:'axis' 
+        })
+        
+        label.scale.set(3,3,3)
+        return label
+    }  
+    /* createLabel(text,color){
         var canvas = document.createElement("canvas")
         var context = canvas.getContext("2d");
         canvas.width = 256,
@@ -108,7 +136,7 @@ export default class Axis extends THREE.Object3D {// 坐标轴
         sprite.scale.set(3,3,3)
         return sprite
        
-    }
+    }  */ 
    
 }
 

+ 17 - 6
src/custom/objects/Sprite.js

@@ -60,17 +60,22 @@ export default class Sprite extends THREE.Mesh{
     }
     
     realVisible(){
-        let parent = this
-        
-        let v
+        let v = true 
+        let parent = this 
+        let lastParent
         while(parent){
             if(parent.visible === false){
                 v = false
                 break; 
             }
+            lastParent = parent
             parent = parent.parent
         }
-        v = true;
+         
+        if(v && !(lastParent instanceof THREE.Scene)){//已被删除
+            v = false
+        }            
+         
         if(!this.latestRealVisi && v){//变为可见后先update 
             this.latestRealVisi = true
             setTimeout(()=>{
@@ -85,7 +90,9 @@ export default class Sprite extends THREE.Mesh{
     
     update(e){
         if(!e){
-            (this.viewports || viewer.viewports).forEach(view=>{
+            let viewports = this.viewports || viewer.viewports
+            if(!viewports)return
+            viewports.forEach(view=>{
                 this.update({viewport:view}) 
             })
             return;
@@ -96,7 +103,11 @@ export default class Sprite extends THREE.Mesh{
         
         let camera = e.viewport.camera
         //rotation
-        this.dontFixOrient || this.root.quaternion.copy(camera.quaternion)
+        
+        if(!this.dontFixOrient){        //orthoCamera一般要加dontFixOrient  
+            let parentQua = this.root.parent.getWorldQuaternion(new THREE.Quaternion)
+            this.root.quaternion.multiplyQuaternions(parentQua.invert(),camera.quaternion)    //乘上parentQua.invert()是为了中和掉父结点的qua,使只剩下camera.quaternion
+        }
         
         //scale
         var info = this.sizeInfo

+ 33 - 65
src/custom/potree.shim.js

@@ -858,6 +858,7 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 		
 		// use close near plane for frustum intersection
 		let frustumCam = camera.clone();
+        frustumCam.zoom = camera.zoom //add
 		frustumCam.near = Math.min(camera.near, 0.1);
 		frustumCam.updateProjectionMatrix();
 		let proj = camera.projectionMatrix;
@@ -1177,7 +1178,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 				let center = sphere.center;
 				let dd = sphere.center.distanceToSquared(camObjPos);
 				  
-                let addPow = 0.25   //0-0.5 数字越大近处加载越快。但会造成远处加载慢甚至因pointBudge限制不加载 
+                const addPow = 0.25   //0-0.5,正常原本是0. 数字越大近处加载越快。但会造成远处加载慢甚至因pointBudge限制不加载 
 				let distance = Math.pow(dd,0.5+addPow)//Math.sqrt(dd); //提高距离权重,为了提高近处加载速度。   某些场景近处加载慢优化明显,如SS-t-cqCAL6rJ5i 
 				
 				//let attenuateDis = 10;//add
@@ -1203,12 +1204,18 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 				}
 			} else {
 				// TODO ortho visibility
-				let bb = child.getBoundingBox();				
-				let distance = child.getBoundingSphere().center.distanceTo(camObjPos); //先加载中间然后四周
-				let diagonal = bb.max.clone().sub(bb.min).length();
-				//weight = diagonal / distance;
+				//let bb = child.getBoundingBox();
+                let sphere = child.getBoundingSphere();		
+                //let diagonal = bb.max.clone().sub(bb.min).length();
+                const reduce = 0  //0-0.5,正常原本是0.
+                if( sphere.radius *  /* Math.pow( */camera.zoom/* ,1-reduce) */   < pointcloud.minimumNodePixelSize   ){
+					continue;
+				}
+                		
+				let distance = sphere.center.distanceToSquared(camObjPos); //先加载中间然后四周 
+				weight = sphere.radius / distance;
                 
-				weight = diagonal;
+				//weight = diagonal;
 			}
 
 			priorityQueue.push({pointcloud: element.pointcloud, node: child, parent: node, weight: weight}); //貌似好像二叉堆中子节点和父节点没什么关系,就只是为了方便排序层层遍历
@@ -1692,21 +1699,20 @@ VolumeTool.prototype.startInsertion = function(args = {}){
     }
       
     volume.name = args.name || 'Volume';
-    
+    volume.isNew = true
       
     
     let camera = this.viewer.scene.getActiveCamera();
-    let updateScale = ()=>{ //保证在视野中的大小一致:
-    
+    let updateScale = ()=>{ //保证在视野中的大小一致: 
         let w = math.getScaleForConstantSize({
             width2d: 300,
             camera , position:volume.getWorldPosition(new THREE.Vector3()) ,
             resolution: viewer.mainViewport.resolution//2
-        })
+        }) 
         /* let wp = volume.getWorldPosition(new THREE.Vector3()).applyMatrix4(camera.matrixWorldInverse);
         // let pp = new THREE.Vector4(wp.x, wp.y, wp.z).applyMatrix4(camera.projectionMatrix);
         let w = Math.abs((wp.z / 3));*/
-        volume.scale.set(w, w, w);  
+        if(!isNaN(w))volume.scale.set(w, w, w);  
     }
 
     this.dispatchEvent({
@@ -1747,13 +1753,20 @@ VolumeTool.prototype.startInsertion = function(args = {}){
     };
     
     let cancel = ()=>{
-        end()
+        viewer.scene.removeVolume(volume);  //删除没完成的
+        end('remove') 
     }
-    let end = e => {
+    let end = (e) => {
+        if(e != 'remove' && !e.isAtDomElement)return
         volume.removeEventListener('drag', drag);
         volume.removeEventListener('drop', end);
         this.viewer.removeEventListener('cancel_insertions', cancel);
-        viewer.transformObject(volume)
+        volume.isNew = false
+        if(e != 'remove'){
+            viewer.transformObject(volume)
+            volume.dispatchEvent('createDone')
+            
+        }
     };
     
     volume.addEventListener('drag', drag);
@@ -1766,54 +1779,9 @@ VolumeTool.prototype.startInsertion = function(args = {}){
     return volume;
 }
 
-VolumeTool.prototype.loadFromData = function(data=[]){
-    data.forEach(v=>{
-        let volume = new Potree.BoxVolume({clip:true, clipTask:v.clipTask});
-        volume.scale.fromArray(v.scale);
-        volume.position.fromArray(v.position);
-        volume.rotation.fromArray(v.rotation);  
-        this.viewer.scene.addVolume(volume);
-        this.scene.add(volume);
-    })
-}
-VolumeTool.prototype.saveClipData = function(){//输出所有的clip volumeBox
-    let oldState = !viewer.clipUnabled;
-    viewer.setClipState(true)
-    let data = viewer.scene.volumes.filter(v=>v.clip && v instanceof Potree.BoxVolume).map(volume=>{
-        return {  
-            clipTask: volume.clipTask,
-            position: volume.position.toArray(),
-            rotation: volume.rotation.toArray(),
-            scale: volume.scale.toArray(),  
-        }
-    })
-    console.log(data)
-    console.log(JSON.stringify(data))
-    viewer.setClipState(oldState)
-    return data
-}
-
-LineGeometry.prototype.setPositions = function( array ) {
-
-    // converts [ x1, y1, z1,  x2, y2, z2, ... ] to pairs format
-      
-    const length = array.length - 3 > 0 ? array.length - 3 : 0; //xzw改 必须>0 
-    const points = new Float32Array( 2 * length );
-
-    for ( let i = 0; i < length; i += 3 ) {
-
-        points[ 2 * i ] = array[ i ];
-        points[ 2 * i + 1 ] = array[ i + 1 ];
-        points[ 2 * i + 2 ] = array[ i + 2 ];
-
-        points[ 2 * i + 3 ] = array[ i + 3 ];
-        points[ 2 * i + 4 ] = array[ i + 4 ];
-        points[ 2 * i + 5 ] = array[ i + 5 ];
-
-    }
-
-    LineSegmentsGeometry.prototype.setPositions.call(this, points );
-
-    return this;
-
-}  
+LineGeometry.prototype.setPositions = function( array  ) { //xzw改成类似LineSegments的多段线  (第二个点和第三个点之间是没有线段的, 所以不用在意线段顺序)
+    const points = new Float32Array( array ); 
+    LineSegmentsGeometry.prototype.setPositions.call(this, points ); 
+    return this; 
+}  
+ 

+ 5 - 13
src/custom/settings.js

@@ -285,7 +285,7 @@ const config = {//配置参数   不可修改
         optionalityFactor: 3
     } 
     ,
-    axis : {   'x':{color:'#d0021b'/* 'red' */}, 'y':{ color:'#86c542' /* 'green' */},  'z': {color:'#3399c8' /* 'blue' */}},  
+    axis : {   'x':{color:'#ea3f3f'/* '#d0021b' */  /* 'red' */}, 'y':{ color:'#86c215' /* '#86c542'  *//* 'green' */},  'z': {color:'#3396f8'/* '#3399c8' */ /* 'blue' */}, 'xyz':{color:'#ccc',}},  
     
     
     highQualityMaxZoom: 2,
@@ -439,22 +439,14 @@ let settings = {//设置   可修改
     
     
     testV4url:false, //v4的全景图等路径不一样 scene_view_data
+    
+    
+    //testCube:true,
 }
   
-
-//https://4dkk.4dage.com/images/imagesSS-V4-aaeaQxWA/tiles/4k/0_skybox2.jpg?x-oss-process=image/resize,h_512&time=20221024105628
-
-//JSON.parse(localStorage.getItem('setting'))
-
+ 
 settings.isLocalhost = settings.prefix.includes('localhost')
 
-/* 
-    关于maxLevel:
-    viewer.scene.pointclouds[0].root.getLevel() 是 0
-    hierarchyStepSize是什么?见 if ((this.level % this.pcoGeometry.hierarchyStepSize) === 0 && this.hasChildren
- 
- 
- */
  
  
 export {config, settings}

+ 15 - 39
src/custom/start.js

@@ -80,27 +80,18 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
             
             
             if(!ifReload){    
-                viewer.scene.view.setView({ 
-                    position: center.clone().add(new THREE.Vector3(10,5,10)), 
-                    target: center
-                })
-                 
                 viewer.dispatchEvent({type:'loadPointCloudDone'})
             
                 if(!Potree.settings.UserPointDensity){
                     Potree.settings.UserPointDensity = 'high'//'middle' 
-                }
+                }                                            
                  
                 Potree.Log('loadPointCloudDone  点云加载完毕', null, 10)  
-            }    
-            
-                                        
-                                                         
-                                                          
-            
+            }      
+             
             
             {//初始位置 
-                var urlFirstView = false
+               
                 var panoId = browser.urlHasValue('pano',true);
                 if(panoId !== ''){
                     var pos
@@ -119,17 +110,10 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                     
                     let pano = viewer.images360.findNearestPano(center)
                      
-                    /* pano && viewer.scene.view.setView({ 
-                        position: pano.position.clone().add(new THREE.Vector3(10,10,10)), 
-                        target: pano.position
-                    }) */
-                     
                     pano && viewer.images360.flyToPano({
                         pano,  duration:0,
-                        target : viewer.images360.bound.center     
-                    })
-                    
-                    
+                        target : viewer.images360.bound.center.setZ(pano.position.z)    //平视中心区域(但也不能保证这个方向一定能看到点云密集区,如果在边缘的话)  
+                    }) 
                 } 
             }
             
@@ -190,8 +174,10 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
         data.forEach((dataset,index)=>{  
             if(!ifReload){
                 var datasetCode = dataset.sceneCode || dataset.name //对应4dkk的场景码
-                var cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${datasetCode}/data/${datasetCode}/webcloud/cloud.js` 
-                var timeStamp = dataset.createTime ? dataset.createTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随createTime更新一次 
+                //var cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${datasetCode}/data/${datasetCode}/webcloud/cloud.js` 
+                var cloudPath = `${Potree.settings.urls.prefix1}/${dataset.webBin}`  //webBin添加原因:每次裁剪之类的操作会换路径,因为oss文件缓存太严重,更新慢
+                
+                var timeStamp = dataset.updateTime ? dataset.updateTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随updateTime更新一次 
                 //console.warn(dataset.name, 'timeStamp', timeStamp)
                 Potree.loadPointCloud(cloudPath, dataset.name ,datasetCode, timeStamp, e => {
                     let scene = viewer.scene;
@@ -498,7 +484,7 @@ export function mergeEditStart(dom){
         viewer.updateModelBound()//init
         //this.bound = new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1))
         
-        viewer.transformationTool.setModeEnable('scale',false)
+        viewer.transformationTool.setModeEnable(['translation','rotation'] )
         viewer.ssaaRenderPass.sampleLevel = 1 //  sampleLevel为1 的话,ground就不会变黑
         
         viewer.inputHandler.fixSelection = true //不通过点击屏幕而切换transfrom选中状态
@@ -553,8 +539,10 @@ export function mergeEditStart(dom){
         if(type == 'laser'){ 
             Potree.loadDatasets((data)=>{
                 let originDataset = data.find(e=>e.sceneCode == sceneCode);//只加载初始数据集  
-                let timeStamp = originDataset.createTime ? originDataset.createTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随createTime更新一次 
-                let cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${sceneCode}/data/${sceneCode}/webcloud/cloud.js` 
+                let timeStamp = originDataset.updateTime ? originDataset.updateTime.replace(/[^0-9]/ig,'') : '';  //每重算一次后缀随updateTime更新一次 
+                //let cloudPath = `${Potree.settings.urls.prefix1}/${Potree.settings.webSite}/${sceneCode}/data/${sceneCode}/webcloud/cloud.js` 
+                let cloudPath = `${Potree.settings.urls.prefix1}/${originDataset.webBin}`  //webBin添加原因:每次裁剪之类的操作会换路径,因为oss文件缓存太严重,更新慢
+                
                 loadCloud(cloudPath, originDataset.sceneName, sceneCode, timeStamp, originDataset.color)
             }, sceneCode, onError)
         
@@ -848,18 +836,6 @@ export function mergeEditStart(dom){
  
  
  
-window.testCubeGeo = function(state){
-    if(state === false){
-        return viewer.images360.cube.material.wireframe = false
-    }
-    viewer.images360.cube.material.wireframe = true
-    viewer.images360.cube.visible = true
-    Potree.settings.rotAroundPoint = false
-}
- 
- 
- 
- 
  
 /* var changeLog = ()=>{ //如果移动端加了test反而出不来bug的话,用这个
         

+ 1 - 1
src/custom/utils/CursorDeal.js

@@ -14,7 +14,7 @@ var CursorDeal = {
         {'disconnectPano':`url({Potree.resourcePath}/images/connect-dis.png),auto`},
          
         {'hoverLine':'pointer'},
-        
+        {'hoverTranHandle':'grab'},
         
         
         {"movePointcloud":'move'}, 

+ 5 - 6
src/custom/utils/DrawUtil.js

@@ -18,17 +18,16 @@ var LineDraw = {
         if(o.mat){
             mat = o.mat
         }else{
-            let prop = {
+            let prop = Object.assign({
                 lineWidth: o.lineWidth || 1,
                 //windows无效。 似乎mac/ios上粗细有效 ? 
-                color: o.color || defaultColor,
-                transparent: o.dontAlwaysSeen ? false : true,
-                depthTest: o.dontAlwaysSeen ? true : false, 
-            }
+                color: o.color || defaultColor, 
+                //depthTest : false, 
+            },o)
             if(o.deshed ){
                 prop.dashSize = o.dashSize || 0.1,
                 prop.gapSize = o.gapSize || 0.1
-            }
+            } 
             mat = new THREE[o.deshed ? "LineDashedMaterial" : "LineBasicMaterial"](prop) 
         }
          

+ 2 - 1
src/custom/utils/SplitScreen4Views.js

@@ -136,7 +136,8 @@ SplitScreen4Views.split = function(o={}){
                 
                 Potree.settings.pointDensity = 'fourViewports' //强制降低点云质量
                 
-                e.changePointOpacity(0.6/* newOpacityMap.get(e).get(viewport), true */);  //多数据集有的数据集很小,放大后显示特别淡
+                //侧面重叠概率更大,所以透明度调小
+                e.changePointOpacity(this.name == "mapViewport" ? 0.6 : 0.06/* newOpacityMap.get(e).get(viewport), true */);  //多数据集有的数据集很小,放大后显示特别淡
                 //console.log(e.name, viewport.name, e.temp.pointOpacity, e.material.opacity)
             }                 
         })  

+ 5 - 5
src/custom/utils/math.js

@@ -416,7 +416,7 @@ var math = {
     getScaleForConstantSize : function(){ //获得规定二维大小的mesh的scale值。可以避免因camera的projection造成的mesh视觉大小改变。  来源:tag.updateDisc
         var w;  
         var i = new THREE.Vector3, o = new THREE.Vector3, l = new THREE.Vector3, c = new THREE.Vector3, h = new THREE.Vector3
-        return function(op={}){
+        return function(op={}){ 
             if(op.width2d) w = op.width2d //如果恒定二维宽度
             else{//否则考虑上距离,加一丢丢近大远小的效果
                 var currentDis, nearBound, farBound
@@ -428,10 +428,10 @@ var math = {
                 w = op.maxSize - ( op.maxSize -  op.minSize) * THREE.Math.smoothstep(currentDis,  op.nearBound,  op.farBound);
                 //maxSize : mesh要表现的最大像素宽度;   nearBound: 最近距离,若比nearBound近,则使用maxSize
             }
-            i.copy(op.position).project(op.camera),  //tag中心在屏幕上的二维坐标
-            o.set(op.resolution.x / 2, op.resolution.y / 2, 1).multiply(i), //转化成px   -w/2 到 w/2的范围
-            l.set(w / 2, 0, 0).add(o),  //加上tag宽度的一半
-            c.set(2 / op.resolution.x, 2 / op.resolution.y, 1).multiply(l), //再转回  -1 到 1的范围
+            i.copy(op.position).project(op.camera);  //tag中心在屏幕上的二维坐标
+            o.set(op.resolution.x / 2, op.resolution.y / 2, 1).multiply(i); //转化成px   -w/2 到 w/2的范围
+            l.set(w / 2, 0, 0).add(o);  //加上tag宽度的一半
+            c.set(2 / op.resolution.x, 2 / op.resolution.y, 1).multiply(l); //再转回  -1 到 1的范围
             h.copy(c).unproject(op.camera);//再转成三维坐标,求得tag边缘的位置
             var g = h.distanceTo(op.position)//就能得到tag的三维半径
             //这里使用的都是resolution2, 好处是手机端不会太小, 坏处是pc更改网页显示百分比时显示的大小会变(或许可以自己算出设备真实的deviceRatio, 因window.screen是不会改变的),但考虑到用户可以自行调节字大小也许是好的

+ 25 - 9
src/custom/viewer/ViewerNew.js

@@ -649,7 +649,19 @@ export class Viewer extends ViewerBase{
         
         
         this.addEventListener('allLoaded', ()=>{
-            setTimeout(this.testPointcloudsMaxLevel.bind(this), 2000) //延迟一丢丢,等画面出现
+            setTimeout(this.testPointcloudsMaxLevel.bind(this), 1000) //延迟一丢丢,等画面出现
+            
+            
+            this.scene.pointclouds.forEach(pointcloud=>{
+                pointcloud.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)
+                    //console.log('pointcloud  isVisible', this.id, e.visible)  
+                    if(e.reason != 'displayMode' ){
+                         this.updateModelBound('visibleChanged')
+                    }
+                     
+                })
+            })
+            
         }) 
         
         
@@ -869,9 +881,9 @@ export class Viewer extends ViewerBase{
     //促使点云加载出最高级别        
     testPointcloudsMaxLevel(){ //所有点云都无需testMaxNodeLevel 就停止
         let camera_changed,  count = 0
-        let test = ()=>{
+        let test = (e={})=>{
             camera_changed = true
-            
+            let camera = e.camera || this.scene.getActiveCamera()
             
             Common.intervalTool.isWaiting('testPointcloudsMaxLevel', ()=>{  
                 if(!camera_changed && count>20 )return //只有当camera_changed后才继续循环, 除了最开始几次需要连续加载下
@@ -881,7 +893,7 @@ export class Viewer extends ViewerBase{
                 
                 var success = true    
                 viewer.scene.pointclouds.forEach(e=>{
-                    var wait = e.testMaxNodeLevel()
+                    var wait = e.testMaxNodeLevel(camera)
                     if(wait){
                         success = false; 
                     }
@@ -4074,8 +4086,10 @@ export class Viewer extends ViewerBase{
 		return this.bound.boundingBox.clone()//this.scene.getBoundingBox(pointclouds);
 	};
 
-    updateModelBound(){
-        this.bound = Utils.computePointcloudsBound(this.scene.pointclouds) 
+    updateModelBound(reason){ 
+        this.bound = Utils.computePointcloudsBound(this.scene.pointclouds.filter(pointcloud=> //只求可见
+            pointcloud.visible || pointcloud.unvisibleReasons && pointcloud.unvisibleReasons.length == 1 && pointcloud.unvisibleReasons[0].reason == 'displayMode'
+        )) 
         if(Potree.settings.boundAddObjs){//加上obj的bound 
             this.objs.children.forEach(e=>{ 
                 this.bound.boundingBox.union(e.boundingBox.clone().applyMatrix4(e.matrixWorld))
@@ -4087,10 +4101,10 @@ export class Viewer extends ViewerBase{
         viewer.farWhenShowPano = this.bound.boundSize.length() * 10//全景漫游时要能看到整个skybox 原本*2的但对于距离特远的数据集需要乘大一些否则会黑面
         
         
-        let boundPlane = new THREE.Box3()
+       /*  let boundPlane = new THREE.Box3()
         boundPlane.expandByPoint(this.bound.boundingBox.min.clone())//最低高度为bound的最低
         boundPlane.expandByPoint(this.bound.boundingBox.max.clone().setZ(this.bound.center.z))//最高高度为bound的中心高度
-        FirstPersonControls.boundPlane = boundPlane
+        FirstPersonControls.boundPlane = boundPlane */
         //FirstPersonControls.standardSpeed = THREE.Math.clamp( Math.sqrt(this.bound.boundSize.length() )/ 100 ,   0.02,0.5); //在这个boundPlane中的速度
         
 
@@ -4099,6 +4113,8 @@ export class Viewer extends ViewerBase{
             e.material.heightMax = this.bound.boundingBox.max.z
         })
         this.dispatchEvent({type:'updateModelBound'})
+        
+        
     }
     
     waitForLoad(object, isLoadedCallback){//等待加载时显示loading。主要是贴图
@@ -4215,7 +4231,7 @@ export class Viewer extends ViewerBase{
         }
         
         if(seleted && seleted != object){//要更换,先取消
-            return this.transformObject(null)
+            this.transformObject(null)
         }
         
         if(!object.boundingBox){

+ 10 - 15
src/materials/shaders/pointcloud_new.vs

@@ -742,7 +742,10 @@ float getPointSize(){
 		pointSize = size;
 	#elif defined attenuated_point_size
 		if(uUseOrthographicCamera){
-			pointSize = size * 10.0;  //加个乘数
+			//pointSize = size * 100.0;  //加个乘数
+            
+            pointSize = size / uOrthoWidth  * resolution.x; //改成近似adaptive_point_size根据窗口缩放
+            
 		}else{  //近大远小,模拟真实mesh,边缘放大
 			//pointSize = size * spacing * projFactor;  //spacing是attribute  为空  如果有这个值就能更自适应填补
             //pointSize = size * uOctreeSpacing * projFactor / 18.0; //直接用cloud的spacing里,不过因为都一样所以可能没有什么意义
@@ -991,22 +994,14 @@ void main() {
         //zoom不会改变z 所以这并不是用在分屏时候的
         //vOpacity = uOpacity * exp(-length(-mvPosition.xyz) / 1000.0);  // e为底的指数函数  opacityAttenuation = 1000
         vOpacity = uOpacity  * exp(gl_Position.z/50.0); 
-        vOpacity = clamp(vOpacity, 0.001, 1.0);          
-        /*if(filtered_by_normal){//垂直朝相机时降低透明度 
-            vOpacity *= 0.2; 
-            vOpacity = clamp(vOpacity, 0.0001, 0.1);    
-        } */  
-    #else
-        vOpacity = uOpacity;
-        /*if(filtered_by_normal){//垂直朝相机时降低透明度 
-        /*if(filtered_by_normal){//垂直朝相机时降低透明度 
-            vOpacity *= 0.3; 
-            vOpacity = clamp(vOpacity, 0.0001, 0.1);    
-        }*/ 
+        vOpacity = clamp(vOpacity, 0.001, 1.0);  
         
-        vOpacity *= max(0.1,  (1.0 - normalZ));
+    #else
+        vOpacity = uOpacity; 
+         
     #endif
-	 
+    
+    vOpacity *= max(0.1,  (1.0 - normalZ));//垂直朝相机时降低透明度 
 
     // POINT SIZE
     float pointSize = getPointSize();

+ 14 - 17
src/navigation/FirstPersonControlsNew.js

@@ -455,18 +455,21 @@ export class FirstPersonControls extends THREE.EventDispatcher {
             let intersect = e.intersect || e.dragViewport.lastIntersect
             //在数据集外部时绕中心点旋转,在数据集内部时绕intersect点旋转(其他数据集的点也可以) 或者 原地旋转镜头
             let rotAroundPoint = Potree.settings.rotAroundPoint && e.dragViewport.camera.type != 'OrthographicCamera' &&  (viewer.atDatasets.length == 0 || intersect) && this.canMovePos(viewport) && !viewer.images360.isAtPano() && !this.viewer.inputHandler.pressedKeys[32]
-            this.rotateStartInfo = {  
-                rotAroundPoint, //定点旋转 
-                /* intersectPos : e.intersect && e.intersect.location,
-                pointer :  e.intersect && e.intersect.location.clone().project(e.dragViewport.camera) //intersect点在屏幕中的位置 */
-            }
+            let rotCenter2d, rotCenter
             if(rotAroundPoint){
                 let pivotType = viewer.atDatasets.length > 0 ? 'intersect' :  viewer.inputHandler.selection.length ? 'selection' : 'boundCenter'  
-                this.rotateStartInfo.rotCenter = pivotType == 'intersect' ? intersect.location : pivotType == 'selection' ? viewer.inputHandler.selection[0].position : viewer.bound.center
-                this.rotateStartInfo.rotCenter2d = this.rotateStartInfo.rotCenter.clone().project(e.dragViewport.camera) //点在屏幕中的位置
-                //console.log('pivotType',pivotType,  this.rotateStartInfo.rotCenter2d)
+                rotCenter = pivotType == 'intersect' ? intersect.location : pivotType == 'selection' ? viewer.inputHandler.selection[0].position : viewer.bound.center
+                if(rotCenter){
+                    rotCenter2d = rotCenter.clone().project(e.dragViewport.camera) //点在屏幕中的位置
+                }else{
+                    rotAroundPoint = false
+                } 
+            }
+            this.rotateStartInfo = {  
+                rotAroundPoint, //定点旋转 
+                rotCenter,
+                rotCenter2d
             }
-            
             //缺点:多数据集绕中心点转很难操作,感觉可以也改为绕lastIntersect
             
             //console.log('prepareRotate' )
@@ -534,15 +537,9 @@ export class FirstPersonControls extends THREE.EventDispatcher {
             viewport.setMoveSpeed(s)   
             
         }else{
-            /* if(viewport == viewer.mainViewport && FirstPersonControls.boundPlane){
-                let s = FirstPersonControls.boundPlane.distanceToPoint(viewer.mainViewport.view.position)
-                s = Math.sqrt(s) / 10;
-                s = Math.max(FirstPersonControls.standardSpeed , s)
-                s  *= Potree.config.moveSpeedAdujust;
-                viewer.setMoveSpeed(s)
-            } */
+             
             //根据和漫游点的最短距离算moveSpeed。缺点:对于导入的无漫游点的数据集没有意义。
-            if(viewport == viewer.mainViewport && FirstPersonControls.boundPlane){
+            if(viewport == viewer.mainViewport && viewer.images360){
                 let position = viewer.mainViewport.view.position 
              
                 //let pointclouds = [viewer.atDatasets, ...viewer.scene.pointclouds.filter(pointcloud=>pointcloud.bound2.distanceToPoint(position) < )]

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 519 - 307
src/utils/TransformationToolNew.js


+ 23 - 9
src/utils/VolumeNew.js

@@ -3,13 +3,20 @@ import * as THREE from "../../libs/three.js/build/three.module.js";
 import {TextSprite} from "../TextSprite.js";
 import DepthBasicMaterial from "../custom/materials/DepthBasicMaterial.js";
 
+import {LineDraw} from "../custom/utils/DrawUtil.js"; 
+
+
 const boxOpacity = {
     hovered : 0.1,
-    selected : 0.3
+    selected : 0.2 
+}
+const LineOpacity = {
+    default : 0.6,
+    selected: 1,
 }
 const colors = {
-    2: 0x00ff80, //可见
-    3: 0xff3158, //不可见
+    2: 0x2ee4ce,//0x00ff80, //可见
+    3: 0xffc23b,//0xff3158, //不可见
     4: 0xffffff, //
 }
 
@@ -128,8 +135,9 @@ export class BoxVolume extends Volume{
 		boxGeometry.computeBoundingBox();
         
 		let boxFrameGeometry = new THREE.Geometry();
-		{
-			let Vector3 = THREE.Vector3;
+		let Vector3 = THREE.Vector3;
+        {
+			
 
 			boxFrameGeometry.vertices.push(
 
@@ -180,10 +188,14 @@ export class BoxVolume extends Volume{
 		this.box = new THREE.Mesh(boxGeometry, this.material);
 		this.box.geometry.computeBoundingBox();
 		this.boundingBox = this.box.geometry.boundingBox;
-		this.add(this.box);
-
-		this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: colors[this.clipTask]/* 0xff2050 */}));
-		// this.frame.mode = THREE.Lines;
+		this.add(this.box); 
+         
+		//this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: colors[this.clipTask], opacity:LineOpacity.default/* 0xff2050 */}));
+		this.frame = LineDraw.createFatLine(
+                boxFrameGeometry.vertices, 
+                { color: colors[this.clipTask], opacity:LineOpacity.default, lineWidth:1,  dontAlwaysSeen:true}   )
+                      
+        // this.frame.mode = THREE.Lines;
 		this.add(this.frame);
 
 		this.update();  
@@ -211,6 +223,8 @@ export class BoxVolume extends Volume{
         
         this.box.material.color.set(colors[this.clipTask])
         this.frame.material.color.set(colors[this.clipTask])
+        this.frame.material.opacity = this.selected ? LineOpacity.selected : LineOpacity.default
+        this.frame.material.lineWidth = this.selected ? 2 : 1
 	}
 
 	raycast (raycaster, intersects) {

+ 1 - 1
src/viewer/sidebarNew.js

@@ -263,7 +263,7 @@ export class Sidebar{
         })
         
         pannel.find('button[name=save]').on('click',(e)=>{
-            let data = viewer.volumeTool.saveClipData();   
+            let data = clipping.saveClipData();   
         })
          
     }