ソースを参照

fix: lessCurvePoints getExtrudeGeo

xzw 7 ヶ月 前
コミット
c4f93f5006

+ 26 - 9
libs/three.js/build/three.module.js

@@ -30829,7 +30829,7 @@ class ExtrudeBufferGeometry extends BufferGeometry {
 
 			if ( extrudePath ) {
 
-				extrudePts = extrudePath.getSpacedPoints( steps );
+				extrudePts = options.dontSmooth ?  extrudePath.points.slice() : extrudePath.getSpacedPoints( steps ); //add!!!!!!!!! 不要平均分,直接用原来的点
 
 				extrudeByPath = true;
 				bevelEnabled = false; // bevels not supported for path extrusion
@@ -30838,7 +30838,7 @@ class ExtrudeBufferGeometry extends BufferGeometry {
 
 				// TODO1 - have a .isClosed in spline?
 
-				splineTube = extrudePath.computeFrenetFrames( steps, false );
+				splineTube = extrudePath.computeFrenetFrames( steps, false, options.dontSmooth ); ///xzw add true !!!!! 
 
 				// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
 
@@ -37552,7 +37552,7 @@ Object.assign( Curve.prototype, {
 
 	},
 
-	computeFrenetFrames: function ( segments, closed ) {
+	computeFrenetFrames: function ( segments, closed, getCtrlPointsDirect ) {//xzw add getCtrlPointsDirect
 
 		// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
 
@@ -37566,15 +37566,32 @@ Object.assign( Curve.prototype, {
 		const mat = new Matrix4();
 
 		// compute the tangent vectors for each segment on the curve
+        
+        
+        if(getCtrlPointsDirect){//xzw 直接返回控制点所在的 
+            this.getCurveLengths() 
+            segments = this.cacheLengths.length 
+            let lengthSum = this.cacheLengths[this.cacheLengths.length - 1] //xzw add  计算控制点处所在处的比例
+            
+            for ( let i = 0; i <= segments; i ++ ) {
 
-		for ( let i = 0; i <= segments; i ++ ) {
-
-			const u = i / segments;
+                const u = i == 0 ? 0 : this.cacheLengths[i-1] / lengthSum;
+                
+                tangents[ i ] = this.getTangentAt( u, new Vector3() );
+                tangents[ i ].normalize();
+            }
+        }else{
+            for ( let i = 0; i <= segments; i ++ ) {//这是平均分线长度
 
-			tangents[ i ] = this.getTangentAt( u, new Vector3() );
-			tangents[ i ].normalize();
+                const u = i / segments;
+                
+     
+                tangents[ i ] = this.getTangentAt( u, new Vector3() );
+                tangents[ i ].normalize();
 
-		}
+            }
+        }
+        
 
 		// select an initial normal vector perpendicular to the first tangent vector,
 		// and in the direction of the minimum tangent xyz component

+ 12 - 5
src/custom/objects/tool/Path.js

@@ -559,12 +559,13 @@ export class Path extends ctrlPolygon{
             this.curve = null
         }else{
             if(Potree.settings.pathSmooth){//使用曲线
-                let curve = new THREE.CatmullRomCurve3(points, false    )  
+                let curve = this.curve = new THREE.CatmullRomCurve3(points, false    )  
                 curve.UtoTMapArr = [] //用于存储 getSpacedPoints得到的点对应points的百分比对应
-                //window.arcLengthDivisions  && (curve.arcLengthDivisions = arcLengthDivisions) //默认200,但改为1也没变化呀
                 let oldCount = count
-                count = Math.max(2, Math.round(this.getTotalDistance() * 400)),  points = curve.getSpacedPoints(count-1) //拆分为更密集的点
-                this.curve = curve
+                count = Math.max(2, Math.round(this.getTotalDistance() * 200)),  points = curve.getSpacedPoints(count-1) //拆分为更密集的点
+        
+                /* //window.arcLengthDivisions  && (curve.arcLengthDivisions = arcLengthDivisions) //默认200,但改为1也没变化呀
+                let oldCount = count 
                 //减少点数(拐弯的部分紧凑些,直线部分宽松些):
                 let lastVec  
                 let newPoints = []
@@ -595,7 +596,13 @@ export class Path extends ctrlPolygon{
                     }  
                 }  
                 points = newPoints 
-                count = points.length
+                */
+                
+                let result = MeshDraw.lessCurvePoints(points, oldCount, 0.05, curve.UtoTMapArr) 
+                this.UtoTMapArr = result.newUtoTMapArr
+                points = result.newPoints  
+                count = points.length 
+                
                 //delete curve.UtoTMapArr 
             }
             let lastSideVec

ファイルの差分が大きいため隠しています
+ 139 - 3
src/custom/start.js


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

@@ -311,6 +311,53 @@ var MeshDraw = {
 		
 	},
     
+    
+    lessCurvePoints: function(points, oldCount, minRad=0.03, UtoTMapArr){//减少点数(拐弯的部分紧凑些,直线部分宽松些):
+        
+        let count = points.length  
+        let newUtoTMapArr = [] 
+        let newPoints = [] 
+        let pointIndexs = [] 
+        let lastVec
+        let startTime = performance.now()
+        /* if(UtoTMapArr){
+            for(let n=1;n<oldCount-1;n++){ 
+                pointIndexs.push(  UtoTMapArr.findIndex(e=>e>= n / (oldCount-1) ) )
+            }   
+        } */   
+        //console.log('cost dur:', performance.now() - startTime )    
+        let nextUtoTIndex = 1 
+        for(let i=0;i<count;i++){
+            let point = points[i];
+            let last = points[i-1]
+            let next = points[i+1]
+            
+            if(i == 0 || i == count-1 ) {
+                newPoints.push(point) //直接加入
+                UtoTMapArr && newUtoTMapArr.push(i == 0 ? 0 : 1) 
+            }else{ 
+                let curVec = new THREE.Vector3().subVectors(next,point)
+                if(!lastVec) lastVec = curVec
+                if(i>1){// 和上一个加入点的vec之间的夹角如果过大就加入 
+                     
+                    let reachNextUToT //找出新点中对应原先控制点的index,这些点必须加入拐点,否则会出现控制点偏移path(当它所在部分接近直线时)
+                    while(UtoTMapArr[i] > nextUtoTIndex / (oldCount-1)){//可能多个控制点对应一个点,当控制点很近时
+                        reachNextUToT = true
+                        nextUtoTIndex ++ 
+                    } 
+                
+                    if(/* pointIndexs.includes(i) || */  reachNextUToT ||  curVec.angleTo(lastVec) > minRad){//最小角度    (注意原始点不能太稀疏)
+                        newPoints.push(point)
+                        UtoTMapArr && newUtoTMapArr.push(UtoTMapArr[i])
+                        lastVec = curVec
+                       
+                    }  
+                }
+            }  
+        }   
+            
+        return {newUtoTMapArr, newPoints}
+    },
      
     getExtrudeGeo:  function(shapes, holes, options={openEnded:false, shapeDontClose:false}){//获得挤出棱柱,可以选择传递height,或者extrudePath
         var shape = this.getShape(shapes, holes) //points是横截面 [vector2,...]
@@ -350,28 +397,52 @@ var MeshDraw = {
                 }) 
                 options.extrudePath = path               
             }
+            
+            
+            if(!options.dontSmooth){
+                //平滑连续的曲线(但经常会有扭曲的问题,tension:0能缓解, 另外shape和path都最好在原点附近,也就是点需减去bound.min )
+                options.extrudePath = new THREE.CatmullRomCurve3(options.extrudePath, options.closed ,  'catmullrom'  /* 'centripetal' */  , options.tension)//tension:张力, 越大弯曲越大。 随着长度增长,该值需要减小,否则会扭曲
+                if(options.lessPoints !== false ){//曲线但压缩直线部分点数量
+                    options.extrudePath.UtoTMapArr = [] //用于存储 getSpacedPoints得到的点对应points的百分比对应
+                    let count = Math.max(2, Math.round(length* (options.lessSpace || 200)  )) //为了防止有大拐弯才设置这么高
+                    let points = options.extrudePath.getSpacedPoints(count-1) //拆分为更密集的点 
+                    let result = this.lessCurvePoints(points, options.extrudePath.points.length,  options.minRad,   options.extrudePath.UtoTMapArr  )  //传UtoTMapArr的话点太多了卡住了
+                    //options.extrudePath = points
+                    options.extrudePath = result.newPoints 
+                    options.dontSmooth = true        
+                } 
+            }
+            
+              
+            
             if(options.dontSmooth){
                 let curvePath = new THREE.CurvePath()//通用的曲线路径对象,它可以包含直线段和曲线段。在这里只做折线
+                curvePath.points = options.extrudePath//add
                 for (let i = 0; i < options.extrudePath.length - 1; i++){ 
                     let curve3 = new THREE.LineCurve3(options.extrudePath[i], options.extrudePath[i + 1]);//添加线段
                     curvePath.add(curve3);
                 } 
-                options.extrudePath = curvePath
-            }else{ 
-                //平滑连续的曲线(但经常会有扭曲的问题,tension:0能缓解, 另外shape和path都最好在原点附近,也就是点需减去bound.min )
-                options.extrudePath = new THREE.CatmullRomCurve3(options.extrudePath, options.closed ,  'catmullrom'  /* 'centripetal' */  , options.tension)//tension:拐弯剧烈程度,但随着长度增长,该值需要减小,否则会扭曲
-                                     
+                options.steps = options.extrudePath.length - 1  
+                options.extrudePath = curvePath 
+                options.tension = 0
+                //已修改过three,原本会平分细分,现在dontSmooth时会直接按照控制点来分段
             } 
         }
         
  
         var extrudeSettings = $.extend(options,{
-            steps: options.steps != void 0 ? options.steps : ( options.extrudePath ? Math.round(length/(options.spaceDis || 0.3)) : 1), //分成几段    spaceDis每段长度
+            steps: options.steps != void 0 ? options.steps : ( options.extrudePath ? Math.round(length/(options.spaceDis || 0.2)) : 1), //分成几段    spaceDis每段长度
             bevelEnabled: false, //不加的话,height为0时会有圆弧高度
             //openEnded默认false 
         }) 
         var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings ); //修改了three.js文件,  buildLidFaces处,创建顶底面加了选项,可以选择开口。 
         return geometry;
+        
+        
+        /*     tension = 0:曲线会变成一条直线,没有弯曲。
+        tension = 0.5:曲线会经过所有控制点,并保持自然的弯曲。  
+        tension > 0.5:曲线会更平滑,远离控制点之间的路径。
+        tension < 0.5:曲线会更贴近控制点之间的路径,弯曲更明显。 */
     },
     
     

+ 8 - 8
src/custom/viewer/ViewerNew.js

@@ -6619,11 +6619,11 @@ export class Viewer extends ViewerBase{
                 
                 
                 var index = 0
-                var addMesh = ({color, path, height,fromDataset, radius=0.08, datasetId=Potree.settings.originDatasetId, spaceDis, tension=0.1, visiEntity}={})=>{//height:在path之上的高度,负数代表在path之下
+                function addMesh({color, path, height,fromDataset, radius=0.08, datasetId=Potree.settings.originDatasetId,  tension=0.3, visiEntity}={}){//height:在path之上的高度,负数代表在path之下
                     var name = 'tube_'+index
-                    
+                    let options = arguments[0]
                 
-                    let radialSegments = 30//THREE.Math.clamp( Math.round(radius * 800), 10, 40)
+                    let radialSegments = 5//THREE.Math.clamp( Math.round(radius * 800), 10, 40)
                     let radSegments = Math.PI*2 / radialSegments
                     var circlePts = [];//横截面
                     for(let i=0;i<radialSegments;i++){
@@ -6640,27 +6640,27 @@ export class Viewer extends ViewerBase{
                             pos = Potree.Utils.datasetPosTransform({ fromDataset: true, position:e, datasetId}) 
                         }else{
                             pos = new THREE.Vector3().copy(e)
-                        }
+                        } 
                          
                         return pos.setZ(pos.z+height)
                     })
                     console.log(linePath)
-                    let geo = MeshDraw.getExtrudeGeo( circlePts, null,{ extrudePath:linePath, tension, spaceDis}   )
+                    let geo = MeshDraw.getExtrudeGeo( circlePts, null, Object.assign(options,  { extrudePath:linePath, tension })   )
                     var mesh = new THREE.Mesh(geo,mat);
                     mesh.name = name
                     window[name] = mesh
-                    
+                     
                     mesh.boundingBox = boundingBox
                     mesh.matrixAutoUpdate = false
                     fromDataset || mesh.matrix.copy(viewer.scene.pointclouds[0].transformMatrix)
                     mesh.matrixWorldNeedsUpdate = true
                     
-                    this.scene.scene.add(mesh);
+                    viewer.scene.scene.add(mesh);
                      
                      
                      
                     if(visiEntity){
-                        this.modules.SiteModel.bus.addEventListener('buildingChange',(e)=>{
+                        viewer.modules.SiteModel.bus.addEventListener('buildingChange',(e)=>{
                             Potree.Utils.updateVisible(mesh,'isInEntity', e.entity && e.entity.name == visiEntity)
                         })
                     }