Prism.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import {Measure} from "../../objects/tool/Measure.js";
  2. import math from "../../utils/math.js";
  3. import * as THREE from "../../../../libs/three.js/build/three.module.js";
  4. let areaPlaneMats = {
  5. }
  6. export class Prism extends Measure{
  7. constructor(args){
  8. super(args)
  9. this.isPrism = true
  10. this.volumeInfo = {}
  11. this.needsCompute = true
  12. /*this.createPrismLines(new THREE.Color('#FFF') )
  13. this.lineMesh.material.transparent = true
  14. this.lineMesh.material.opacity = 0.5
  15. Potree.Utils.setObjectLayers(this.lineMesh, 'measure' ) */
  16. this.setClipBox()
  17. this.setTopOrBtm('zMin')
  18. this.setTopOrBtm('zMax')
  19. this.setHorizonHeight('btm')
  20. let update =()=>{
  21. this.setHorizonHeight(this.horizonType, true)//更新
  22. this.needsCompute = true
  23. this.getBound()
  24. this.dispatchEvent('updated')
  25. }
  26. this.addEventListener('marker_dropped'/* 'marker_moved' */,update)
  27. this.addEventListener('changeByHistory',update)
  28. this.addEventListener('changed',update)
  29. /* this.addEventListener('createDone',()=>{
  30. this.setHorizonHeight()//更新
  31. this.updateAreaPlane()
  32. }) */
  33. this.updateAreaPlane()
  34. this.getBound()
  35. this.addEventListener('needsCompute',()=>{
  36. this.needsCompute = true
  37. },10)
  38. //Potree.Utils.setObjectLayers(this.lineMesh, 'bothMapAndScene' )
  39. }
  40. set needsCompute(state){
  41. if(state == 'byVolume'){
  42. this.needsCompute_ = this.volumeInfo.Vupper == void 0
  43. }else{
  44. this.needsCompute_ = !!state
  45. //console.error('needsCompute', state)
  46. }
  47. }
  48. get needsCompute(){
  49. return this.needsCompute_
  50. }
  51. setHorizonHeight(v){
  52. let old = this.horizonZ
  53. if(typeof v == 'number'){
  54. this.horizonType = 'number'
  55. this.horizonZ = v
  56. }else{
  57. if(v){
  58. this.horizonType = v
  59. }
  60. if(!this.horizonType) this.horizonType = 'btm'
  61. if(this.horizonType == 'number')return
  62. let zs = this.points.map(p=>p.z).sort((a,b)=>a-b)
  63. this.horizonZ = this.horizonType == 'btm' ? zs[0] : zs[this.points.length-1]
  64. }
  65. //this.horizonZ = THREE.Math.clamp(this.horizonZ, this.zMin, this.zMax )
  66. if(this.horizonZ != old ){
  67. this.needsCompute = true
  68. this.update() //update areaPlane and areaLabel pos
  69. this.dispatchEvent('horizonZChanged')
  70. }
  71. //console.log(this.horizonZ)
  72. }
  73. setBaseModel(model, modelHaventLoad){//三种状态:使用model、使用基准高度、 什么都没有(不允许计算、不高亮、等待模型上传)
  74. this.baseModel = model
  75. this.modelHaventLoad = modelHaventLoad
  76. Potree.Utils.updateVisible(this.areaPlane,'unuseHorizonH',!model && !modelHaventLoad)
  77. }
  78. setClipBox(boxes){//clipBoxes_out
  79. this.clipBoxes = boxes || []
  80. }
  81. setTopOrBtm(name,v){
  82. if(v != void 0 ){
  83. this[name] = v
  84. this.updatePrismLines()
  85. }else{
  86. this[name] = viewer.bound.boundingBox[name == 'zMin' ? 'min' : 'max'].z
  87. }
  88. this.getBound()
  89. this.needsCompute = true
  90. }
  91. getBound(){
  92. let bound = Potree.math.getBound(this.points)
  93. bound.min.z = this.zMin
  94. bound.max.z = this.zMax
  95. this.prismBound = bound
  96. }
  97. setVolumeInfo(volumeInfo){
  98. this.volumeInfo = volumeInfo
  99. this.getVolumeString()
  100. this.needsCompute = false //但得到的不一定是对的可能 检查下
  101. }
  102. getVolumeString(){
  103. if(!this.volumeInfo || this.volumeInfo.Vupper == void 0)return;
  104. this.VupperString = this.getConvertString(this.volumeInfo.Vupper, 'volume', true)
  105. this.VlowerString = this.getConvertString(this.volumeInfo.Vlower, 'volume', true)
  106. this.highestString = this.getConvertString(this.volumeInfo.highest, 'distance', true)
  107. this.lowestString = this.getConvertString(this.volumeInfo.lowest, 'distance', true)
  108. }
  109. getConvertString(num, type, restrictUnit){
  110. if(!restrictUnit)return super.getConvertString(num, type)
  111. return viewer.unitConvert.convert(num, type, Potree.settings.precision, this.unitSystem, null ,
  112. {//在pdf里的高度要统一单位
  113. 'imperial': {restrictUnit: 'Foot'}, //ft
  114. 'metric': {restrictUnit: 'Meter'}
  115. }
  116. )
  117. }
  118. setUnitSystem(unitSystem){
  119. let old = this.unitSystem
  120. super.setUnitSystem(unitSystem)
  121. if(unitSystem != old){
  122. this.getVolumeString()
  123. }
  124. }
  125. getCenter(type){
  126. if(type == 'areaPlaneCenter'){//areaPlane中心
  127. return this.areaPlaneCenter
  128. }
  129. return super.getCenter() //点的中心
  130. }
  131. update(){
  132. super.update.apply(this, arguments)
  133. this.updatePrismLines()
  134. }
  135. getTransformationMatrix(pointcloud) {//剪裁矩阵
  136. let invMatrix = new THREE.Matrix4;
  137. //把当前z移动到-0.5 ~ 0.5所需要的变换
  138. let minZ = this.zMin//viewer.bound.boundingBox.min.z
  139. let maxZ = this.zMax//viewer.bound.boundingBox.max.z
  140. let s = 1/(maxZ-minZ)
  141. let pos = new THREE.Vector3(0,0, -0.5 - minZ * s ),
  142. scale = new THREE.Vector3(1,1,s);
  143. invMatrix.compose( pos, new THREE.Quaternion, scale ); //先缩放后位移
  144. return (new THREE.Matrix4).multiplyMatrices(invMatrix, pointcloud.transformMatrix).transpose()
  145. }
  146. changeStyleForScreenshot(state, {hideLabel,showName}={}){//截图前变一下外观。根据高度变化颜色
  147. let config = Potree.settings.prismHeightColor
  148. let color//, lineWidth = this.edges[0].material.lineWidth
  149. if(this.volumeInfo.Vupper > 0.01 && this.volumeInfo.Vlower > 0.01){
  150. color = config.every.color
  151. }else if(this.volumeInfo.Vupper > this.volumeInfo.Vlower){
  152. for(let i = config.dig.length-1; i>=0; i--){
  153. if(this.volumeInfo.Vupper >= config.dig[i].min){
  154. color = config.dig[i].color
  155. break
  156. }
  157. }
  158. }else{
  159. for(let i = config.fill.length-1; i>=0; i--){
  160. if(this.volumeInfo.Vlower >= config.fill[i].min){
  161. color = config.fill[i].color
  162. break
  163. }
  164. }
  165. }
  166. color = new THREE.Color(color[0]/255,color[1]/255,color[2]/255)
  167. let name = color.getHexString()
  168. if(state){
  169. Potree.Utils.updateVisible(this.areaPlane,'screenshot', true, 2, 'add') //强制显示
  170. let mat = areaPlaneMats[name]
  171. if(!mat){
  172. mat = new THREE.MeshBasicMaterial({
  173. color, transparent:true, opacity:0.6,
  174. side:THREE.DoubleSide,
  175. })
  176. areaPlaneMats[name] = mat
  177. }
  178. this.oldAreaPlaneMat = this.areaPlane.material
  179. this.areaPlane.material = mat
  180. if(hideLabel){
  181. Potree.Utils.updateVisible(this.areaLabel, 'screenshot-single',false)
  182. }
  183. if(showName){
  184. this.areaLabel.setText([this.name, this.area.string])
  185. /* let btm = this.areaPlaneCenter.clone().setY(this.prismBound.min.y) //置于土方2d块底部
  186. this.areaLabel.setPos(btm)
  187. this.areaLabel.sprite.position.y = -0.25 */
  188. }
  189. this.markers.forEach(marker=>Potree.Utils.updateVisible(marker,'screenshot-Prism',false))
  190. this.edges.forEach(edge=>Potree.Utils.updateVisible(edge,'screenshot-Prism',false))
  191. //Potree.Utils.updateVisible(this.lineMesh,'screenshot-Prism',false)
  192. this.styleRecover = ()=>{
  193. this.areaPlane.material = this.oldAreaPlaneMat
  194. if(hideLabel){
  195. Potree.Utils.updateVisible(this.areaLabel, 'screenshot-single', true)
  196. }
  197. if(showName){
  198. this.areaLabel.setText(this.area.string)
  199. /* this.areaLabel.setPos(this.areaPlaneCenter)
  200. this.areaLabel.sprite.position.y = 0 */
  201. }
  202. this.markers.forEach(marker=>Potree.Utils.updateVisible(marker,'screenshot-Prism',true))
  203. this.edges.forEach(edge=>Potree.Utils.updateVisible(edge,'screenshot-Prism',true))
  204. //Potree.Utils.updateVisible(this.lineMesh,'screenshot-Prism',true)
  205. this.styleRecover = null
  206. }
  207. }else{
  208. this.styleRecover && this.styleRecover()
  209. Potree.Utils.updateVisible(this.areaPlane, 'screenshot', false, 2, 'cancel')
  210. }
  211. }
  212. dispose(){
  213. super.dispose()
  214. this.clipBoxes.forEach(e=>viewer.scene.removeVolume(e))
  215. }
  216. setEditState(state){//编辑页面or截图
  217. state = !!state
  218. this.editing = state
  219. this.dontHighlight = !state
  220. this.clipBoxes.forEach(box=>{
  221. Potree.Utils.updateVisible(box,'hidden',state), box.clip = state
  222. })
  223. }
  224. /* {
  225. fill: [
  226. {color: [236, 213, 143, 1], min: 0, max: 5},
  227. {color: [223, 118, 21, 1], min: 5, max: 10},
  228. // 没有min表示大于
  229. {color: [186, 57, 57, 1], min: 10}
  230. ],
  231. dig: [
  232. {color: [144, 193, 190, 1], min: 0, max: 5},
  233. {color: [76, 155, 211, 1], min: 5, max: 10},
  234. // 没有min表示大于
  235. {color: [79, 76, 211, 1], min: 10}
  236. ],
  237. // 填挖并存
  238. every: { color: [49, 200, 181, 1] }
  239. } */
  240. }