Measure.js 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604
  1. import * as THREE from "../../../../libs/three.js/build/three.module.js";
  2. import {TextSprite} from "../TextSprite.js";
  3. import {Utils} from "../../../utils.js";
  4. import Label from "../Label.js";
  5. import {LineDraw} from "../../utils/DrawUtil.js";
  6. import math from "../../utils/math.js";
  7. import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
  8. import Sprite from '../Sprite.js'
  9. import {config} from '../../settings.js'
  10. import {ctrlPolygon} from './ctrlPolygon.js'
  11. let texLoader = new THREE.TextureLoader()
  12. let defaultColor = new THREE.Color(config.measure.default.color);
  13. let highlightColor = new THREE.Color(config.measure.highlight.color);
  14. let color = new THREE.Color(config.measure.color)
  15. let textColor = new THREE.Color(config.measure.textColor)
  16. var markerMats = {}
  17. var lineMats ;
  18. var planeMats
  19. const lineDepthInfo = {
  20. clipDistance : 4,//消失距离
  21. occlusionDistance: 1,//变为backColor距离
  22. }
  23. const planeDepthInfo = {
  24. clipDistance : 30,//消失距离
  25. occlusionDistance: 4,//变为backColor距离
  26. maxOcclusionFactor:0.3,
  27. maxClipFactor:0.1
  28. }
  29. const textSizeRatio = math.linearClamp(window.innerWidth * window.innerHeight , 360*720, 1920*1080, 0.75, 1) //pc字显示大一些
  30. const markerSizeInfo = {
  31. minSize : 30*2 , maxSize : 60*2, nearBound : 0.2, farBound : 4,
  32. }
  33. const labelSizeInfo = {width2d:190}
  34. const mainLabelProp = {
  35. //backgroundColor: {r: defaultColor.r*255, g: defaultColor.g*255, b: defaultColor.b*255, a:config.measure.default.opacity},
  36. backgroundColor: {r: 0, g: 0, b: 0, a:0},
  37. textColor: {r: textColor.r*255, g: textColor.g*255, b: textColor.b*255, a: 1.0},
  38. textBorderColor: {r:255, g: 255, b:255, a: 1.0},
  39. textBorderThick:3,
  40. fontsize: 15 * textSizeRatio,
  41. borderRadius : 12, margin:{x:20,y:4},
  42. renderOrder : Potree.config.renderOrders.measureLabel,
  43. pickOrder:Potree.config.renderOrders.measureLabel,
  44. disToLine:-0.15,
  45. useDepth : true ,
  46. // 2023.10 尽量不让数字被挡住
  47. clipDistance : 50,//消失距离
  48. occlusionDistance: 10,//变为backColor距离
  49. maxOcclusionFactor:0.2,
  50. maxClipFactor:0.1
  51. }
  52. const subLabelProp = {
  53. backgroundColor: {r: 255, g: 255, b: 255, a:config.measure.default.opacity},
  54. textColor: {r: 0.3, g: 0.3, b:0.3, a: 1.0},
  55. fontsize:15 * textSizeRatio, borderRadius : 12, margin:{x:20,y:4},
  56. renderOrder : Potree.config.renderOrders.measureLabelSub,
  57. pickOrder:Potree.config.renderOrders.measureLabelSub,
  58. }
  59. const angle = THREE.Math.degToRad(5);//显示水平垂直辅助线的最小角度
  60. const guideShowMinAngle = {min: angle, max: Math.PI/2 - angle}
  61. export class Measure extends ctrlPolygon{
  62. constructor (prop) {
  63. prop.dimension = '2d'
  64. super('measure',prop);
  65. this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
  66. this.name = this.measureType + this.constructor.counter //'Measure_' + this.constructor.counter;
  67. //this.color = '#FF4399'
  68. this.color = new THREE.Color(this.color)
  69. this.markerLabels = [];
  70. this.edgeLabels = [];
  71. this.angleLabels = [];
  72. this.coordinateLabels = [];
  73. this.area = {value:0,string:''}
  74. if( this.showArea ){
  75. this.areaLabel = this.createAreaLabel();
  76. this.add(this.areaLabel)
  77. }
  78. //add:
  79. if(this.atPlane || this.faceDirection){ //是一个平面上的话
  80. if(this.guideLinePoints){
  81. this.createGuideLines()
  82. }else{
  83. this.createGuideLine();
  84. }
  85. }
  86. if(this.measureType == 'Distance' /* || this.measureType.includes('MulDistance') */){
  87. this.createHorVerGuideLine()
  88. }
  89. this.selectStates = {}
  90. this.setUnitSystem(prop.unit || viewer.unitConvert.UnitService.defaultSystem)
  91. Potree.Utils.setObjectLayers(this, 'measure' )
  92. //addMarkers:
  93. this.initData(prop)
  94. this.pointsPos2d = new Map //屏幕上的二维坐标
  95. this.points_datasets || (this.points_datasets = []) //存每个点是哪个数据集
  96. //这版应该没多数据集,不需要更新这个:
  97. /* this.addEventListener('marker_dropped',(e)=>{
  98. this.updateDatasetBelong(e.index)
  99. }) */
  100. this.addEventListener('isVisible', ()=>{
  101. viewer.mapViewer && viewer.mapViewer.dispatchEvent({type:'content_changed'})
  102. })
  103. }
  104. initData(prop){
  105. let makeIt = super.initData(prop)
  106. if(makeIt){
  107. this.edges.forEach(edge=>{edge.dispatchEvent('addHoverEvent') })
  108. if(this.measureType == 'MulDistance_shape'){
  109. this.markers.forEach(e=>e.visible = false)
  110. }
  111. }else{
  112. this.failBuilded = true
  113. }
  114. }
  115. updateDatasetBelong(changeIndex){//更新所属数据集
  116. if(Potree.settings.editType == "merge"){//无地图
  117. /* this.dataset_points = this.points.map((e,i)=>{
  118. return Potree.Utils.datasetPosTransform({toDataset:true, datasetId:this.points_datasets[i], position:e.clone()})
  119. }) */
  120. this.dataset_points[changeIndex] = Potree.Utils.datasetPosTransform({toDataset:true, datasetId:this.points_datasets[changeIndex], position:this.points[changeIndex].clone()})
  121. return
  122. }
  123. let old = this.datasetId
  124. let maxCount = {id:null,count:0}
  125. let datasets = {}
  126. this.points_datasets.forEach(e=>{
  127. if(e == void 0)return
  128. if(datasets[e]){
  129. datasets[e] ++
  130. }else{
  131. datasets[e] = 1
  132. }
  133. })
  134. for(let i in datasets) {
  135. if(datasets[i]>maxCount.count){
  136. maxCount = {id:i, count:datasets[i]}
  137. }
  138. }
  139. this.datasetId = maxCount.count > 0 ? maxCount.id : null
  140. //if(this.datasetId != old){
  141. //this.dispatchEvent({type:'changeDatasetId'})
  142. if(this.datasetId == void 0){
  143. this.dataset_points = null //可能为空或[null,null...]
  144. }else{
  145. this.dataset_points = this.points.map(e=>{
  146. return Potree.Utils.datasetPosTransform({toDataset:true,datasetId:this.datasetId, position:e.clone()})
  147. })
  148. }
  149. //}
  150. }
  151. transformByPointcloud(){//每次移动点云 or 加载测量线时要获取一下当前position //有地图时
  152. if(this.datasetId == void 0)return
  153. this.points = this.dataset_points.map(e=>{
  154. return Potree.Utils.datasetPosTransform({fromDataset:true, datasetId:this.datasetId, position:e.clone()})
  155. })
  156. this.getPoint2dInfo(this.points)
  157. this.update({ifUpdateMarkers:true})
  158. this.setSelected(false)//隐藏edgelabel
  159. }
  160. update(options={}) {
  161. super.update(options)
  162. if(this.showCoordinates && this.points.length>0){
  163. let position = this.points[0];
  164. this.markers[0].position.copy(position);
  165. { // coordinate labels
  166. let coordinateLabel = this.coordinateLabels[0];
  167. let lonlat = viewer.transform.lonlatToLocal.inverse(position.toArray())
  168. let EPSG4550 = viewer.transform.lonlatTo4550.forward(lonlat)
  169. let pos = [
  170. position.toArray(),
  171. lonlat,
  172. EPSG4550
  173. ]
  174. //let msg = position.toArray().map(p => Utils.addCommas(p.toFixed(2))).join(" / ");
  175. let msg = pos.map(a=>
  176. a.map(p => Utils.addCommas(p.toFixed(10))).join(", ")
  177. ).join("<br>")
  178. coordinateLabel.setText(msg);
  179. coordinateLabel.setPos(position)
  180. coordinateLabel.setVisible(true)//this.showCoordinates;
  181. }
  182. return
  183. }
  184. /* viewer.addEventListener('camera_changed',(e)=>{
  185. if(e.changeInfo.positionChanged){
  186. setLabelPos()
  187. }
  188. }) */
  189. let setEdgeLabel = (label,p1,p2,distance)=>{//设置label位置和字
  190. this.setEdgeLabelPos(label,p1,p2)
  191. distance = distance == void 0 ? p1.distanceTo(p2) : distance;
  192. var text = this.labelText || viewer.unitConvert.convert(distance, 'distance', Potree.settings.precision , this.unitSystem, 0.001 , true, true)//distance要传0.1 这个factor
  193. label.setText(text)
  194. }
  195. let lastIndex = this.points.length - 1;
  196. for (let index = 0; index <= lastIndex; index++) {
  197. let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
  198. let previousIndex = (index === 0) ? lastIndex : index - 1;
  199. //if(!this.closed && nextIndex == 0 )break; //add
  200. let point = this.points[index];
  201. let nextPoint = this.points[nextIndex];
  202. let previousPoint = this.points[previousIndex];
  203. if(this.showDistances || this.labelText){ // edge labels
  204. let edgeLabel = this.edgeLabels[index];
  205. let distance = point.distanceTo(nextPoint)
  206. let text = this.labelText || distance
  207. edgeLabel.shouldVisi = distance>0 && (index < lastIndex || this.isRect || this.closed && !this.isNew )
  208. /* this.closed || */edgeLabel.setVisible(edgeLabel.shouldVisi)
  209. if(edgeLabel.shouldVisi){
  210. this.lineDir = new THREE.Vector3().subVectors(point,nextPoint).normalize() //[point,nextPoint]
  211. setEdgeLabel(edgeLabel,point,nextPoint,text)
  212. }
  213. }
  214. }
  215. if(this.measureType == 'Distance' && this.points.length>1){//设置水平垂直辅助线
  216. var pTop, pBtm
  217. if(this.points[0].z > this.points[1].z ){
  218. pTop = this.points[0];
  219. pBtm = this.points[1];
  220. }else{
  221. pTop = this.points[1];
  222. pBtm = this.points[0];
  223. }
  224. let projectPos = new THREE.Vector3(pTop.x, pTop.y, pBtm.z);//两条guideline的交点
  225. {//倾斜角度太小的时候不显示
  226. let tan = pTop.distanceTo(projectPos) / pBtm.distanceTo(projectPos)
  227. let angle = Math.atan(tan);
  228. this.shouldShowHorVerGuide = angle > guideShowMinAngle.min && angle < guideShowMinAngle.max
  229. }
  230. LineDraw.updateLine(this.verGuideEdge, [pTop, projectPos])
  231. LineDraw.updateLine(this.horGuideEdge, [pBtm, projectPos])
  232. setEdgeLabel(this.verEdgeLabel,pTop,projectPos)
  233. setEdgeLabel(this.horEdgeLabel,pBtm,projectPos)
  234. this.verGuideEdge.visible = this.horGuideEdge.visible = this.shouldShowHorVerGuide
  235. this.verEdgeLabel.visible = this.horEdgeLabel.visible = this.shouldShowHorVerGuide
  236. }
  237. if(this.showArea && this.point2dInfo){ // update area
  238. /* if(this.points.length>2){
  239. this.area = {value:0};
  240. this.areaLabel.setVisible(false)
  241. }else{ */
  242. let area = Math.abs(math.getArea(this.point2dInfo.points2d))//this.getArea();
  243. let msg = viewer.unitConvert.convert(area, 'area', Potree.settings.precision, this.unitSystem/* , 0.1 */ )
  244. this.area = {value:area, string:msg}
  245. this.areaLabel.setPos(this.center);
  246. this.areaLabel.setText(msg);
  247. this.areaLabel.setVisible(true)
  248. //}
  249. }
  250. };
  251. setEdgeLabelPos(label,p1,p2){ //调整label的位置,使倾斜后看起来在线的中心,而不要挡住端点
  252. let center = new THREE.Vector3().addVectors(p1,p2).multiplyScalar(0.5);
  253. if(this.lineDir && this.lineDir.length() > 0){
  254. if(viewer.mainViewport.camera.type == 'OrthographicCamera'){
  255. label.setPos(center)
  256. }else{
  257. //根据视线和线的夹角(后又加入相机和两个端点距离差)来决定标签偏移位置。+
  258. let eyePos = viewer.mainViewport.camera.position;
  259. let dir = viewer.mainViewport.view.direction //new THREE.Vector3().subVectors(center,eyePos).normalize()
  260. /*let centerDir = new THREE.Vector3().subVectors(center,eyePos).normalize()
  261. if(centerDir.dot(dir)<0){//中点在相机后方,就不设置
  262. label.setPos(center)
  263. return
  264. } */
  265. let cos = dir.dot(this.lineDir)
  266. let nearPoint = cos > 0 ? p2 : p1 //近端点。
  267. let far = cos > 0 ? p1 : p2 //远端点。
  268. let nearPointDir = new THREE.Vector3().subVectors(nearPoint,eyePos)//.normalize()
  269. //使label在中点和近端点中变化, 近端点可能到了相机后方,需要投影到相机所在平面上
  270. if(nearPointDir.dot(dir)<0){//近端点到了相机后方,前移。
  271. //let hfov = cameraLight.getHFOVForCamera(viewer.mainViewport.camera , true ); //暂且只看水平fov
  272. //if(nearPointDir.dot(dir)<Math.cos(hfov/2)){//近端点在镜头外,前移。 --但是这个就得把点转化成在镜头边缘而非左右两边(camDirPlane上)
  273. let ray = new THREE.Raycaster()
  274. ray.set(nearPoint, cos>0?this.lineDir:this.lineDir.clone().negate())
  275. let camDirPlane = new THREE.Plane().setFromNormalAndCoplanarPoint(dir, eyePos)
  276. nearPoint = ray.ray.intersectPlane(camDirPlane, new THREE.Vector3())
  277. if(!nearPoint){//线是垂直的,视线是水平的时候
  278. return label.setPos(center)
  279. }
  280. }
  281. //防止离远了之后也偏移很多,但远了之后相机到端点vec和到中点的vec的夹角接近,不需要怎么偏移的。
  282. let dis1 = nearPoint.distanceToSquared(eyePos)
  283. let dis2 = far.distanceToSquared(eyePos)
  284. let diff = Math.abs(dis1/dis2)
  285. diff<1 && (diff = 1/diff)
  286. diff = math.linearClamp(diff,0, 30, 0,1 )
  287. let efficiency = 0.7; // 0-1 数值越高,r越容易接近1或-1,label越容易在倾斜后靠近近端点。
  288. //let r = 0.5*efficiency*cos + 0.5
  289. let r = 0.5*efficiency*diff*cos + 0.5
  290. r = THREE.Math.clamp(r,0.1,0.9)
  291. //视线越接近线的方向,标签应该越往近端点偏移,防止看起来几乎在远端。
  292. if(cos > 0){
  293. center = p1.clone().multiplyScalar(1-r).add(nearPoint.clone().multiplyScalar(r)); //label在线上滑动,使尽量保持在视觉中心
  294. }else{
  295. center = nearPoint.clone().multiplyScalar(1-r).add(p2.clone().multiplyScalar(r)); //label在线上滑动,使尽量保持在视觉中心
  296. }
  297. label.setPos(center)
  298. }
  299. //归零
  300. this.orient2dInfo = null
  301. this.markers.forEach(e=>e.needsUpdate=true)
  302. }else{
  303. label.setPos(center)
  304. }
  305. }
  306. addMarker (o={}) {
  307. let marker = new Sprite({mat:this.getMarkerMaterial('default'), sizeInfo: markerSizeInfo, name:"measure_point"} )
  308. if(this.measureType != 'MulDistance_shape')marker.posShift = new THREE.Vector3(0.2,0,0);//使箭头中心对准端点位置(因贴图里箭头不在中心,如果单纯改贴图会导致raycaster热区偏移,所以修改mesh位置)
  309. Potree.Utils.setObjectLayers(marker, 'measure' )
  310. marker.pickOrder = marker.renderOrder = Potree.config.renderOrders.measureMarker;
  311. marker.markerSelectStates = {}
  312. marker.addEventListener('startDragging',(e)=>{
  313. console.log('marker startdragging')
  314. viewer.inputHandler.dispatchEvent( {type: 'measuring',v:true, cause:'startDragging', situation:'dragging', object:this})
  315. })
  316. marker.addEventListener('drop',(e)=>{
  317. console.log('marker drop')
  318. this.lastDropTime = Date.now()
  319. viewer.inputHandler.dispatchEvent({type: 'measuring', v:false, cause:'stopDragging', situation:'dragging', object:this} )
  320. if(Potree.settings.adsorption){
  321. this.isNew || viewer.viewports.forEach((viewport)=>{
  322. this.getPointsPos2d(viewport, true )//forceUpdate
  323. })
  324. }
  325. })
  326. marker.measure = this
  327. let edge
  328. { // edges
  329. edge = LineDraw.createFatLine( [ ],{material: this.getLineMat(this.clickSelected?'edgeSelect':'edgeDefault')} )
  330. edge.pickOrder = 0
  331. Potree.Utils.setObjectLayers(edge, 'measure' )
  332. let addHoverEvent = ()=>{ //当非isNew时才添加事件
  333. let mouseover = (e) => {this.setSelected(true, 'edge')};
  334. let mouseleave = (e) => {this.setSelected(false, 'edge')};
  335. edge.addEventListener('mouseover', mouseover);
  336. edge.addEventListener('mouseleave', mouseleave);
  337. edge.removeEventListener('addHoverEvent', addHoverEvent);
  338. //2023.10.25add:
  339. edge.addEventListener('click',()=>{
  340. let now = Date.now()
  341. if(now-this.lastDropTime < 50)return ;//点击到marker了
  342. if(!this.isNew) this.focus()
  343. })
  344. }
  345. edge.addEventListener('addHoverEvent', addHoverEvent);
  346. }
  347. super.addMarker({point:o.point, marker:marker, edge})
  348. if(this.showEdges){ // edge labels
  349. const edgeLabel = this.createEdgeLabel('edgeLabel', !this.closed)
  350. edgeLabel.measure = this
  351. this.edgeLabels.push(edgeLabel);
  352. }
  353. if(this.showCoordinates){ // coordinate labels
  354. let coordinateLabel = new Label({
  355. className:'measure_pointPos',
  356. camera: viewer.scene.getActiveCamera()
  357. })
  358. coordinateLabel.setVisible(false)
  359. this.coordinateLabels.push(coordinateLabel);
  360. }
  361. let event = {
  362. type: 'marker_added',
  363. measurement: this,
  364. marker: marker
  365. };
  366. this.dispatchEvent(event);
  367. //this.setMarker(this.points.length - 1, point);
  368. this.update()//更新一下倒数第二条线
  369. return marker;//add
  370. };
  371. editStateChange(state){ //主要针对edgeLabels显示切换,编辑时显示
  372. super.editStateChange(state)
  373. if(!state){
  374. this.editStateTimer = setTimeout(()=>{
  375. if(!this.isEditing){
  376. this.dispatchEvent({type:'editStateChange',state:false})
  377. this.setEdgesDisplay(false)
  378. this.areaPlane && Potree.Utils.updateVisible(this.areaPlane, 'intersectLastLine', true)
  379. this.areaLabel && Potree.Utils.updateVisible(this.areaLabel, 'intersectLastLine', true)
  380. }
  381. },100)
  382. }else{
  383. if(!this.isEditing){
  384. this.dispatchEvent({type:'editStateChange',state:true})
  385. this.setEdgesDisplay(true)
  386. clearTimeout(this.editStateTimer)
  387. }
  388. }
  389. this.isEditing = state
  390. viewer.dispatchEvent({type:'MeasureDragChange',state})
  391. }
  392. setMarkerSelected(marker, state, hoverObject){
  393. //console.warn(marker.id , state, hoverObject)
  394. marker.markerSelectStates[hoverObject] = state
  395. let absoluteState = false
  396. for(var i in marker.markerSelectStates){
  397. if(marker.markerSelectStates[i] == 'hover'){
  398. absoluteState = true; break;
  399. }
  400. }
  401. if(this.measureType == 'MulDistance_shape'){
  402. if(state == 'hover' && hoverObject == 'single'){
  403. marker.material = this.getMarkerMaterial('select')
  404. }else{
  405. marker.material = this.getMarkerMaterial('default') //路径选中后marker是非选中状态, 但是颜色一样
  406. }
  407. }else{
  408. if(absoluteState){
  409. marker.material = this.getMarkerMaterial('select')
  410. }else{
  411. marker.material = this.getMarkerMaterial('default')
  412. }
  413. }
  414. if(absoluteState){
  415. marker.renderOrder = marker.pickOrder = Potree.config.renderOrders.measureMarker+1
  416. }else{
  417. marker.renderOrder = marker.pickOrder = Potree.config.renderOrders.measureMarker
  418. }
  419. marker.selected = absoluteState
  420. viewer.mapViewer && viewer.mapViewer.dispatchEvent('content_changed')
  421. viewer.dispatchEvent('content_changed')
  422. }
  423. setEdgesDisplay(state, ignoreGuideLine){
  424. this.closed && this.edgeLabels.forEach(e=>e.setVisible(!!(state && e.shouldVisi)) )
  425. if(!ignoreGuideLine && this.measureType == 'Distance'){
  426. this.horEdgeLabel.visible = this.verEdgeLabel.visible = this.horGuideEdge.visible = this.verGuideEdge.visible = !!(state && this.shouldShowHorVerGuide)
  427. }
  428. }
  429. setSelected(state, hoverObject){//add
  430. //console.log('setSelected', state, hoverObject)
  431. hoverObject && (this.selectStates[hoverObject] = state)
  432. let absoluteState = false
  433. for(var i in this.selectStates){
  434. if(this.selectStates[i]){
  435. absoluteState = true; break;
  436. }
  437. }
  438. if(absoluteState){
  439. this.markers.forEach(e=>this.setMarkerSelected(e, 'hover', 'selectAll' ) )
  440. this.edges.forEach(e=>{
  441. e.renderOrder = Potree.config.renderOrders.lines + 1
  442. e.material = this.getLineMat('edgeSelect')
  443. })
  444. this.areaPlane && (this.areaPlane.material = planeMats.selected)
  445. //this.areaLabel && this.areaLabel.elem.addClass('highLight')
  446. //this.closed || this.edgeLabels.forEach(e=>e.elem.addClass('highLight') )
  447. this.setEdgesDisplay(true, hoverObject=="screenshot")
  448. this.areaLabel && this.setLabelHightState(this.areaLabel, true)
  449. this.closed || this.edgeLabels.forEach(e=>this.setLabelHightState(e, true) )
  450. }else{
  451. this.markers.forEach(e=>this.setMarkerSelected(e, 'unhover', 'selectAll' ))
  452. this.edges.forEach(e=>{
  453. e.renderOrder = Potree.config.renderOrders.lines
  454. e.material = this.getLineMat('edgeDefault')
  455. })
  456. this.areaPlane && (this.areaPlane.material = planeMats.default)
  457. this.setEdgesDisplay(false, hoverObject=="screenshot")
  458. //this.areaLabel && this.areaLabel.elem.removeClass('highLight')
  459. //this.closed || this.edgeLabels.forEach(e=>e.elem.removeClass('highLight') )
  460. this.areaLabel && this.setLabelHightState(this.areaLabel, false)
  461. this.closed || this.edgeLabels.forEach(e=>this.setLabelHightState(e, false) )
  462. }
  463. this.selected = absoluteState
  464. if(hoverObject != 'byList'){
  465. //this.bus && this.bus.emit('highlight', this.selected)
  466. this.dispatchEvent({type:'highlight',state:this.selected})//列表高亮
  467. }
  468. viewer.dispatchEvent('content_changed')
  469. viewer.mapViewer && viewer.mapViewer.dispatchEvent('content_changed')
  470. }
  471. setLabelHightState(label, state){
  472. if(state){
  473. let color = new THREE.Color(Potree.config.measure.highlight.color)
  474. //label.sprite.material.opacity = config.measure.highlight.opacity
  475. //label.setBackgroundColor({r:255*color.r, g:255*color.g, b:255*color.b, a:config.measure.highlight.opacity})
  476. label.sprite.material.useDepth = false;
  477. //label.textColor = {r: this.color.r*255, g: this.color.g*255, b: this.color.b*255, a: 1}
  478. }else{
  479. //label.setBackgroundColor({r: this.color.r*255, g: this.color.g*255, b: this.color.b*255, a:config.measure.default.opacity})
  480. label.sprite.material.useDepth = true
  481. //label.sprite.material.opacity = 0.98
  482. //label.textColor = {r: 255, g: 255, b: 255, a: 1}
  483. }
  484. label.updateTexture()
  485. }
  486. removeMarker(index ){
  487. super.removeMarker(index)
  488. this.points_datasets.splice(index, 1);
  489. this.dataset_points && this.dataset_points.splice(index, 1)
  490. this.coordinateLabels.splice(index, 1);
  491. let edgeIndex = index//(index === 0) ? 0 : (index - 1);
  492. if(this.edgeLabels[edgeIndex]){
  493. this.edgeLabels[edgeIndex].dispose()
  494. this.edgeLabels.splice(edgeIndex, 1);
  495. }
  496. this.update();
  497. this.dispatchEvent({type: 'marker_removed', measurement: this});
  498. }
  499. setPosition(index, position) {
  500. super.setPosition(index, position)
  501. //相连的点的箭头也要更新方向
  502. this.markers[(index + this.points.length - 1) % this.points.length].waitUpdate()
  503. this.markers[(index + this.points.length + 1) % this.points.length].waitUpdate()
  504. let event = {
  505. type: 'marker_moved',
  506. measure: this,
  507. index: index,
  508. position: position.clone()
  509. };
  510. this.dispatchEvent(event);
  511. }
  512. dispose(){//add
  513. var labels = this.edgeLabels.concat(this.coordinateLabels)
  514. this.areaLabel && labels.push(this.areaLabel)
  515. labels.forEach(e=>e.dispatchEvent({type:'dispose'}))
  516. super.dispose()
  517. }
  518. getTotalDistance () {
  519. if (this.points.length === 0) {
  520. return 0;
  521. }
  522. let distance = 0;
  523. for (let i = 1; i < this.points.length; i++) {
  524. let prev = this.points[i - 1];
  525. let curr = this.points[i];
  526. let d = prev.distanceTo(curr);
  527. distance += d;
  528. }
  529. if (this.closed && this.points.length > 1) {
  530. let first = this.points[0];
  531. let last = this.points[this.points.length - 1];
  532. let d = last.distanceTo(first);
  533. distance += d;
  534. }
  535. return distance;
  536. }
  537. getAngleBetweenLines (cornerPoint, point1, point2) {
  538. let v1 = new THREE.Vector3().subVectors(point1, cornerPoint);
  539. let v2 = new THREE.Vector3().subVectors(point2, cornerPoint);
  540. // avoid the error printed by threejs if denominator is 0
  541. const denominator = Math.sqrt( v1.lengthSq() * v2.lengthSq() );
  542. if(denominator === 0){
  543. return 0;
  544. }else{
  545. return v1.angleTo(v2);
  546. }
  547. };
  548. getAngle (index) {
  549. if (this.points.length < 3 || index >= this.points.length) {
  550. return 0;
  551. }
  552. let previous = (index === 0) ? this.points[this.points.length - 1] : this.points[index - 1];
  553. let point = this.points[index];
  554. let next = this.points[(index + 1) % (this.points.length)];
  555. return this.getAngleBetweenLines(point, previous, next);
  556. }
  557. getCenter(/* update */){
  558. if(this.closed){
  559. return this.center.clone()
  560. }else{
  561. let center = this.points.reduce(function(total, currentValue ){
  562. return total.add(currentValue)
  563. }, new THREE.Vector3 )
  564. center.multiplyScalar(1/this.points.length)
  565. return center //求不出重心呜呜
  566. }
  567. }
  568. // updateAzimuth(){
  569. // // if(this.points.length !== 2){
  570. // // return;
  571. // // }
  572. // // const azimuth = this.azimuth;
  573. // // const [p0, p1] = this.points;
  574. // // const r = p0.distanceTo(p1);
  575. // }
  576. createGuideLine(){//add 辅助线
  577. var guideLine = LineDraw.createFatLine([ ],{material:this.getLineMat('guide')} )
  578. guideLine.visible = false
  579. this.guideLine = guideLine
  580. this.add(guideLine);
  581. }
  582. createHorVerGuideLine(){//创建水平与垂直辅助线,仅距离测量有。
  583. var verGuideEdge = LineDraw.createFatLine([ ],{material:this.getLineMat('guide')} )
  584. verGuideEdge.visible = false
  585. this.verGuideEdge = verGuideEdge
  586. verGuideEdge.name = 'verGuideEdge'
  587. var horGuideEdge = LineDraw.createFatLine([ ],{material:this.getLineMat('guide')} )
  588. horGuideEdge.visible = false
  589. horGuideEdge.name = 'horGuideEdge'
  590. this.horGuideEdge = horGuideEdge
  591. this.add(this.verGuideEdge);
  592. this.add(this.horGuideEdge);
  593. //label:
  594. this.verEdgeLabel = this.createEdgeLabel('verGuideEdge')
  595. this.horEdgeLabel = this.createEdgeLabel('horGuideEdge')
  596. }
  597. createGuideLines(){//add 固定点垂线的辅助线 可以多段
  598. var guideLine = LineDraw.createFatLine(this.guideLinePoints ,{material:this.getLineMat('guide2'), renderOrderShift:-1, uncontinuous:true} )
  599. this.guideLine = guideLine //暂时也叫这个名字
  600. this.add(guideLine);
  601. }
  602. updateGuideLines(){
  603. LineDraw.updateLine(this.guideLine, this.guideLinePoints)
  604. }
  605. focus({dontMoveCamera=false, dontEmit}={}){
  606. if(Potree.settings.displayMode == 'showPanos')dontMoveCamera = true //2023.10.24 新需求:点击后不移动,否则经常跳到别的点。且在app上会反应一秒才选中。
  607. if(!dontMoveCamera){
  608. let dontChangeCamDir = viewer.mainViewport.camera.type == 'OrthographicCamera' /* && math.closeTo( viewer.mainViewport.view.pitch , -1.57079632) */ // 不改角度
  609. viewer.focusOnObject(this, 'measure', null, {dontChangeCamDir})
  610. }
  611. if(this.clickSelected)return
  612. this.setSelected(true, 'focus')
  613. this.clickSelected = true
  614. dontEmit || this.dispatchEvent({type:'selected', state:true})
  615. if(this.measureType == 'MulDistance_shape'){
  616. this.markers.forEach(e=>e.visible = true)
  617. }
  618. //viewer.dispatchEvent({type:'selectMeasure', measure:this})
  619. let cancelSelect = ()=>{
  620. if(this.isNew)return;//添加过程中保持选中 主要for多路径
  621. this.clickSelected = false
  622. if(this.measureType == 'MulDistance_shape'){
  623. this.markers.forEach(e=>e.visible = false)
  624. }
  625. this.removeEventListener('cancelSelect', cancelSelect)
  626. this.setSelected(false, 'focus')
  627. dontEmit || this.dispatchEvent({type:'selected', state:false})
  628. }
  629. setTimeout(()=>{
  630. this.addEventListener('cancelSelect', cancelSelect)
  631. },10)
  632. }
  633. createEdgeLabel(name, hasHoverEvent){
  634. //mainLabelProp.backgroundColor = {r: this.color.r*255, g: this.color.g*255, b: this.color.b*255, a:config.measure.default.opacity}
  635. const edgeLabel = new TextSprite(
  636. $.extend(hasHoverEvent ? mainLabelProp : subLabelProp,{
  637. sizeInfo: labelSizeInfo, name:name||'edgeLabel',
  638. })
  639. )
  640. if(hasHoverEvent){
  641. edgeLabel.addEventListener('mouseover',()=>{
  642. this.setSelected(true, 'edgeLabel')
  643. })
  644. edgeLabel.addEventListener('mouseleave',()=>{
  645. this.setSelected(false, 'edgeLabel')
  646. })
  647. edgeLabel.addEventListener('click',()=>{
  648. if(!this.isNew) this.focus()
  649. })
  650. //edgeLabel.sprite.material.opacity = config.measure.default.opacity
  651. }
  652. edgeLabel.visible = false
  653. edgeLabel.sprite.material.depthTestWhenPick = true
  654. Potree.Utils.setObjectLayers(edgeLabel, 'measure' )
  655. this.add(edgeLabel)
  656. return edgeLabel
  657. }
  658. createAreaLabel(){
  659. /* const areaLabel = new Label({
  660. className:'measure_area',
  661. })
  662. areaLabel.elem.on('mouseover',()=>{
  663. this.setSelected(true, 'areaLabel')
  664. })
  665. areaLabel.elem.on('mouseout',()=>{
  666. this.setSelected(false, 'areaLabel')
  667. }) */
  668. const areaLabel = new TextSprite(
  669. $.extend({}, mainLabelProp,{sizeInfo: labelSizeInfo, name:'areaLabel', fontsize:16*textSizeRatio} )
  670. )
  671. areaLabel.addEventListener('mouseover',()=>{
  672. this.setSelected(true, 'areaLabel')
  673. })
  674. areaLabel.addEventListener('mouseleave',()=>{
  675. this.setSelected(false, 'areaLabel')
  676. })
  677. areaLabel.addEventListener('click',()=>{
  678. if(!this.isNew) this.focus()
  679. })
  680. Potree.Utils.setObjectLayers(areaLabel, 'measure' )
  681. areaLabel.setVisible(false)
  682. return areaLabel;
  683. }
  684. getMarkerMaterial(type){
  685. let color = this.color.getHexString()
  686. let name
  687. if(this.measureType == 'MulDistance_shape'){//多线段路径
  688. name = type + '_circle_' + color
  689. }else{
  690. name = type + '_arrow_' + color
  691. }
  692. if(!markerMats[name]){
  693. markerMats['default_circle_' + color] = new DepthBasicMaterial($.extend({},lineDepthInfo,{
  694. transparent: !0,
  695. opacity: 1,
  696. map: texLoader.load(Potree.resourcePath+'/textures/pic_point_s32.png' ),
  697. useDepth:true,
  698. replaceColor:new THREE.Color(Potree.config.measure.highlight.color),
  699. beReplacedRed: 0.184, //0.18431372
  700. mapColorReplace:true,
  701. mapScale:0.7
  702. })),
  703. markerMats['select_circle_' + color] = new DepthBasicMaterial($.extend({},lineDepthInfo,{
  704. transparent: !0,
  705. opacity: 1,
  706. map: texLoader.load(Potree.resourcePath+'/textures/pic_point32.png' ),
  707. //useDepth:true ,
  708. replaceColor: new THREE.Color(Potree.config.measure.highlight.color) ,
  709. beReplacedRed: 0.184, //0.18431372
  710. mapColorReplace:true,
  711. mapScale:0.7
  712. }))
  713. markerMats['default_arrow_' + color] = new DepthBasicMaterial($.extend({},lineDepthInfo,{
  714. transparent: !0,
  715. opacity: 1,
  716. map: texLoader.load(Potree.resourcePath+'/textures/arrows_l_32.png' ),
  717. useDepth:true,
  718. replaceColor:this.color,
  719. beReplacedRed: 0.184, //0.18431372
  720. mapColorReplace:true,
  721. })),
  722. markerMats['select_arrow_' + color] = new DepthBasicMaterial($.extend({},lineDepthInfo,{
  723. transparent: !0,
  724. opacity: 1,
  725. map: texLoader.load(Potree.resourcePath+'/textures/arrows_l_32.png' ),
  726. //useDepth:true ,
  727. replaceColor: new THREE.Color(Potree.config.measure.highlight.color) ,
  728. beReplacedRed: 0.184, //0.18431372
  729. mapColorReplace:true
  730. }))
  731. }
  732. return markerMats[name]
  733. }
  734. getLineMat(type) {
  735. if(!lineMats) Measure.lineMats = lineMats = {
  736. guide: LineDraw.createFatLineMat({
  737. color:config.measure.guide.color,
  738. dashSize: 0.1,
  739. gapSize: 0.02,
  740. dashed: true,
  741. lineWidth: 2
  742. }),
  743. guide2: LineDraw.createFatLineMat(Object.assign({}, lineDepthInfo,{
  744. color:config.measure.guide.color,
  745. dashSize: 0.1,
  746. gapSize: 0.02,
  747. dashed: true,
  748. lineWidth: 2,
  749. useDepth :true,
  750. }))
  751. }
  752. let color = this.color.getHexString()
  753. if(!lineMats['edgeDefault'+color]){
  754. lineMats['edgeDefault'+color] = LineDraw.createFatLineMat(Object.assign({}, lineDepthInfo, {
  755. color: this.color,
  756. lineWidth: config.measure.lineWidth,
  757. useDepth :true,
  758. dashWithDepth :true, // 只在被遮住的部分显示虚线,因为实线容易挡住label
  759. dashed :true,
  760. dashSize : 0.04,
  761. gapSize: 0.04,
  762. transparent: true,
  763. opacity: config.measure.default.opacity,
  764. depthTestWhenPick:true,
  765. }))
  766. lineMats['edgeSelect'+color] = LineDraw.createFatLineMat(Object.assign({}, lineDepthInfo,{
  767. color: Potree.config.measure.highlight.color ,
  768. dashSize: 0.5,
  769. gapSize: 0.2,
  770. lineWidth: config.measure.lineWidth ,
  771. transparent: true,
  772. opacity: config.measure.highlight.opacity
  773. }))
  774. }
  775. if(!type.includes('guide')){
  776. return Measure.lineMats[type+color]
  777. }else return Measure.lineMats[type]
  778. }
  779. createAreaPlane(){
  780. planeMats || (planeMats = {
  781. default: new DepthBasicMaterial( $.extend({},planeDepthInfo,{
  782. color:color,
  783. side:THREE.DoubleSide,
  784. opacity:0.2,
  785. transparent:true,
  786. useDepth:true
  787. })),
  788. selected: new THREE.MeshBasicMaterial({
  789. color: color ,
  790. side:THREE.DoubleSide,
  791. opacity:0.3,
  792. transparent:true,
  793. })
  794. },Measure.planeMats = planeMats)
  795. return super.createAreaPlane(planeMats.default)
  796. }
  797. raycast (raycaster, intersects) {
  798. for (let i = 0; i < this.points.length; i++) {
  799. let marker = this.markers[i];
  800. marker.raycast(raycaster, intersects);
  801. }
  802. // recalculate distances because they are not necessarely correct
  803. // for scaled objects.
  804. // see https://github.com/mrdoob/three.js/issues/5827
  805. // TODO: remove this once the bug has been fixed
  806. for (let i = 0; i < intersects.length; i++) {
  807. let I = intersects[i];
  808. I.distance = raycaster.ray.origin.distanceTo(I.point);
  809. }
  810. intersects.sort(function (a, b) { return a.distance - b.distance; });
  811. };
  812. getPointsPos2d(viewport, update){//获取屏幕上的二维坐标
  813. let ps = this.pointsPos2d.get(viewport)
  814. if(update || !ps){
  815. let points = this.points.slice()
  816. if(this.measureType == 'MulDistance_shape'){
  817. points.push(this.getCenter()) //中心点吸附
  818. }
  819. points = points.map(e=>{
  820. let p = Potree.Utils.getPos2d(e, viewport, viewer.renderArea )
  821. p.pos3d = e.clone(), p.object = this
  822. return p
  823. });
  824. this.pointsPos2d.set(viewport, points)
  825. //console.log('updatePointsPos2d',this.uuid,viewport.name)
  826. }
  827. return this.pointsPos2d.get(viewport)
  828. }
  829. transformData(prop){
  830. if(prop.measureType == 'Point'){
  831. prop.showCoordinates = true,
  832. prop.closed = true,
  833. prop.maxMarkers = 1,
  834. prop.minMarkers = 1
  835. }else if(prop.measureType == 'Distance'){
  836. prop.showDistances = true,
  837. prop.showEdges = true,
  838. prop.maxMarkers = 2,
  839. prop.minMarkers = 2
  840. }else if(prop.measureType == 'MulDistance' ){//new
  841. prop.showDistances = true,
  842. prop.showEdges = true,
  843. prop.minMarkers = 2
  844. }else if(prop.measureType == 'MulDistance_shape' ){//new
  845. prop.showEdges = true,
  846. prop.minMarkers = 2
  847. }else if(prop.measureType == 'Ver MulDistance'){
  848. prop.showDistances = true,
  849. prop.atPlane = true,
  850. prop.showEdges = true,
  851. prop.minMarkers = 2
  852. prop.faceDirection = "vertical"
  853. prop.unableDragAtMap = true
  854. }else if(prop.measureType == 'Hor MulDistance'){
  855. prop.showDistances = true,
  856. prop.atPlane = true,
  857. prop.showEdges = true,
  858. prop.minMarkers = 2
  859. prop.faceDirection = "horizontal"
  860. }else if(prop.measureType == 'Ver Distance'){
  861. prop.showDistances = true,
  862. prop.showEdges = true,
  863. prop.maxMarkers = 2,
  864. prop.minMarkers = 2,
  865. prop.faceDirection = "vertical"
  866. prop.unableDragAtMap = true
  867. }else if(prop.measureType == 'Hor Distance'){
  868. prop.showDistances = true,
  869. prop.showEdges = true,
  870. prop.maxMarkers = 2,
  871. prop.minMarkers = 2,
  872. prop.faceDirection = "horizontal"
  873. }else if(prop.measureType == "Hor LINE with Text"){ //add
  874. prop.showEdges = true,
  875. prop.maxMarkers = 2,
  876. prop.minMarkers = 2,
  877. prop.faceDirection = "horizontal"
  878. }else if(prop.measureType == 'Area'){
  879. prop.showDistances = true,
  880. prop.atPlane = true,
  881. prop.showEdges = true,
  882. prop.closed = true,
  883. prop.minMarkers = 3
  884. }else if(prop.measureType == 'Hor Area'){
  885. prop.showDistances = true,
  886. prop.atPlane = true,
  887. prop.showEdges = true,
  888. prop.closed = true,
  889. prop.minMarkers = 3
  890. prop.faceDirection = "horizontal"
  891. }else if(prop.measureType == 'Ver Area'){
  892. prop.showDistances = true,
  893. prop.atPlane = true,
  894. prop.showEdges = true,
  895. prop.closed = true,
  896. prop.minMarkers = 3
  897. prop.faceDirection = "vertical"
  898. prop.unableDragAtMap = true
  899. }else if(prop.measureType == 'Rect Area'){
  900. prop.showDistances = true,
  901. prop.atPlane = true,
  902. prop.showEdges = true,
  903. prop.closed = true,
  904. prop.minMarkers = 4
  905. prop.maxMarkers = 4
  906. }else if(prop.measureType == 'Hor Rect Area'){
  907. prop.showDistances = true,
  908. prop.atPlane = true,
  909. prop.showEdges = true,
  910. prop.closed = true,
  911. prop.minMarkers = 4
  912. prop.maxMarkers = 4
  913. prop.isRect = true
  914. prop.faceDirection = "horizontal"
  915. }else if(prop.measureType == 'Ver Rect Area'){
  916. prop.showDistances = true,
  917. prop.atPlane = true,
  918. prop.showEdges = true,
  919. prop.closed = true,
  920. prop.minMarkers = 4
  921. prop.maxMarkers = 4
  922. prop.isRect = true
  923. prop.faceDirection = "vertical"
  924. prop.unableDragAtMap = true
  925. }
  926. if(prop.atPlane && prop.closed){ //atPlane在同一平面上
  927. prop.showArea = true
  928. }
  929. super.transformData(prop)
  930. }
  931. setUnitSystem(unitSystem){
  932. //console.log(this.name +':' +this.unitSystem)
  933. if(unitSystem != this.unitSystem){
  934. if(unitSystem == "metric"){
  935. }else if(unitSystem == 'imperial'){
  936. }
  937. this.unitSystem = unitSystem
  938. this.update()
  939. }
  940. }
  941. reDraw(restMarkerCount=0){//重新开始画
  942. super.reDraw(restMarkerCount)
  943. if(this.measureType == 'Distance'){
  944. this.shouldShowHorVerGuide = false
  945. this.setEdgesDisplay(false)
  946. }
  947. if(this.showArea){
  948. this.area = {value:0};
  949. this.areaLabel && this.areaLabel.setVisible(false)
  950. }
  951. viewer.inputHandler.dispatchEvent( {type:'measuring', v:true, cause:'reDraw',object:this, situation:'dragging'} )
  952. }
  953. /* get showCoordinates () {
  954. return this._showCoordinates;
  955. }
  956. set showCoordinates (value) {
  957. this._showCoordinates = value;
  958. this.update();
  959. }
  960. get showAngles () {
  961. return this._showAngles;
  962. }
  963. set showAngles (value) {
  964. this._showAngles = value;
  965. this.update();
  966. }
  967. get showCircle () {
  968. return this._showCircle;
  969. }
  970. set showCircle (value) {
  971. this._showCircle = value;
  972. this.update();
  973. }
  974. get showAzimuth(){
  975. return this._showAzimuth;
  976. }
  977. set showAzimuth(value){
  978. this._showAzimuth = value;
  979. this.update();
  980. }
  981. get showEdges () {
  982. return this._showEdges;
  983. }
  984. set showEdges (value) {
  985. this._showEdges = value;
  986. this.update();
  987. }
  988. get showHeight () {
  989. return this._showHeight;
  990. }
  991. set showHeight (value) {
  992. this._showHeight = value;
  993. this.update();
  994. }
  995. get showArea () {
  996. return this._showArea;
  997. }
  998. set showArea (value) {
  999. this._showArea = value;
  1000. this.update();
  1001. }
  1002. get closed () {
  1003. return this._closed;
  1004. }
  1005. set closed (value) {
  1006. this._closed = value;
  1007. this.update();
  1008. }
  1009. get showDistances () {
  1010. return this._showDistances;
  1011. }
  1012. set showDistances (value) {
  1013. this._showDistances = value;
  1014. this.update();
  1015. } */
  1016. }
  1017. function createCircleRadiusLabel(){
  1018. const circleRadiusLabel = new TextSprite("");
  1019. circleRadiusLabel.setTextColor({r: 140, g: 250, b: 140, a: 1.0});
  1020. circleRadiusLabel.setBorderColor({r: 0, g: 0, b: 0, a: 1.0});
  1021. circleRadiusLabel.setBackgroundColor({r: 0, g: 0, b: 0, a: 1.0});
  1022. circleRadiusLabel.fontsize = 16;
  1023. circleRadiusLabel.material.depthTest = false;
  1024. circleRadiusLabel.material.opacity = 1;
  1025. circleRadiusLabel.visible = false;
  1026. return circleRadiusLabel;
  1027. }
  1028. function createCircleRadiusLine(){
  1029. /* const lineGeometry = new LineGeometry();
  1030. lineGeometry.setPositions([
  1031. 0, 0, 0,
  1032. 0, 0, 0,
  1033. ]);
  1034. const lineMaterial = new LineMaterial({
  1035. color: 0xff0000,
  1036. lineWidth: 2,
  1037. resolution: new THREE.Vector2(1000, 1000),
  1038. gapSize: 1,
  1039. dashed: true,
  1040. });
  1041. lineMaterial.depthTest = false;
  1042. const circleRadiusLine = new Line2(lineGeometry, lineMaterial);*/
  1043. var circleRadiusLine = LineDraw.createFatLine([ ],{
  1044. color:0xff0000,
  1045. dashSize: 0.5,
  1046. gapSize: 0.2,
  1047. lineWidth: config.measure.lineWidth
  1048. })
  1049. circleRadiusLine.visible = false;
  1050. return circleRadiusLine;
  1051. }
  1052. function createCircleLine(){
  1053. const coordinates = [];
  1054. let n = 128;
  1055. for(let i = 0; i <= n; i++){
  1056. let u0 = 2 * Math.PI * (i / n);
  1057. let u1 = 2 * Math.PI * (i + 1) / n;
  1058. let p0 = new THREE.Vector3(
  1059. Math.cos(u0),
  1060. Math.sin(u0),
  1061. 0
  1062. );
  1063. let p1 = new THREE.Vector3(
  1064. Math.cos(u1),
  1065. Math.sin(u1),
  1066. 0
  1067. );
  1068. coordinates.push(
  1069. p0,
  1070. p1
  1071. );
  1072. }
  1073. /* const geometry = new LineGeometry();
  1074. geometry.setPositions(coordinates);
  1075. const material = new LineMaterial({
  1076. color: 0xff0000,
  1077. dashSize: 5,
  1078. gapSize: 2,
  1079. lineWidth: 2,
  1080. resolution: new THREE.Vector2(1000, 1000),
  1081. });
  1082. material.depthTest = false;
  1083. const circleLine = new Line2(geometry, material);
  1084. circleLine.visible = false;
  1085. circleLine.computeLineDistances();*/
  1086. var circleLine = LineDraw.createFatLine(coordinates,{
  1087. color: 0xff0000,
  1088. dashSize: 0.5,
  1089. gapSize: 0.2,
  1090. lineWidth: config.measure.lineWidth
  1091. })
  1092. return circleLine;
  1093. }
  1094. /* function createCircleCenter(){
  1095. const sg = new THREE.markerGeometry(1, 32, 32);
  1096. const sm = new THREE.MeshNormalMaterial();
  1097. const circleCenter = new THREE.Mesh(sg, sm);
  1098. circleCenter.visible = false;
  1099. return circleCenter;
  1100. } */
  1101. function createLine(){
  1102. const line = LineDraw.createFatLine([ ],{
  1103. color: 0xff0000,
  1104. dashSize: 0.5,
  1105. gapSize: 0.2,
  1106. lineWidth: config.measure.lineWidth
  1107. })
  1108. return line;
  1109. }
  1110. function createCircle(){
  1111. const coordinates = [];
  1112. let n = 128;
  1113. for(let i = 0; i <= n; i++){
  1114. let u0 = 2 * Math.PI * (i / n);
  1115. let u1 = 2 * Math.PI * (i + 1) / n;
  1116. let p0 = new THREE.Vector3(
  1117. Math.cos(u0),
  1118. Math.sin(u0),
  1119. 0
  1120. );
  1121. let p1 = new THREE.Vector3(
  1122. Math.cos(u1),
  1123. Math.sin(u1),
  1124. 0
  1125. );
  1126. coordinates.push(
  1127. p0,
  1128. p1
  1129. );
  1130. }
  1131. var line = LineDraw.createFatLine(coordinates,{
  1132. color: 0xff0000,
  1133. dashSize: 0.5,
  1134. gapSize: 0.2,
  1135. lineWidth: config.measure.lineWidth
  1136. })
  1137. return line;
  1138. }
  1139. Measure.markerMats = markerMats;
  1140. /* function createAzimuth(){
  1141. const azimuth = {
  1142. label: null,
  1143. center: null,
  1144. target: null,
  1145. north: null,
  1146. centerToNorth: null,
  1147. centerToTarget: null,
  1148. centerToTargetground: null,
  1149. targetgroundToTarget: null,
  1150. circle: null,
  1151. node: null,
  1152. };
  1153. const sg = new THREE.markerGeometry(1, 32, 32);
  1154. const sm = new THREE.MeshNormalMaterial();
  1155. {
  1156. const label = new TextSprite("");
  1157. label.setTextColor({r: 140, g: 250, b: 140, a: 1.0});
  1158. label.setBorderColor({r: 0, g: 0, b: 0, a: 1.0});
  1159. label.setBackgroundColor({r: 0, g: 0, b: 0, a: 1.0});
  1160. label.fontsize = 16;
  1161. label.material.depthTest = false;
  1162. label.material.opacity = 1;
  1163. azimuth.label = label;
  1164. }
  1165. azimuth.center = new THREE.Mesh(sg, sm);
  1166. azimuth.target = new THREE.Mesh(sg, sm);
  1167. azimuth.north = new THREE.Mesh(sg, sm);
  1168. azimuth.centerToNorth = createLine();
  1169. azimuth.centerToTarget = createLine();
  1170. azimuth.centerToTargetground = createLine();
  1171. azimuth.targetgroundToTarget = createLine();
  1172. azimuth.circle = createCircle();
  1173. azimuth.node = new THREE.Object3D();
  1174. azimuth.node.add(
  1175. azimuth.centerToNorth,
  1176. azimuth.centerToTarget,
  1177. azimuth.centerToTargetground,
  1178. azimuth.targetgroundToTarget,
  1179. azimuth.circle,
  1180. azimuth.label,
  1181. azimuth.center,
  1182. azimuth.target,
  1183. azimuth.north,
  1184. );
  1185. return azimuth;
  1186. } */
  1187. /*
  1188. */