import {Tool} from './tool' import {Graph} from '../../utils/graph' import {Styles} from '../styles' import {DEFAULT_SEARCH_BUFFER} from "../viewer2d"; export class LoopPickTool extends Tool { constructor(name, viewer) { super(name, viewer); this.loops = new Map(); this.marked = new Set(); this.pickedLoop = null; this.pointToObject = new Map(); } restart() { this.sendHint('pick a polygon'); this.reindexLoops(); this.marked.clear(); this.pointToObject.clear(); this.pickedLoop = null; } cleanup() { this.clearMarked(); } clearMarked() { this.viewer.withdrawAll('tool'); } mark(obj) { this.viewer.capture('tool', obj); } otherEnd(point) { if (point.parent.a.id === point.id) { return point.parent.b; } else { return point.parent.a; } } reindexLoops() { this.loops.clear(); const points = []; this.viewer.accept((obj) => { if (obj.TYPE === 'Point' && obj.parent && obj.parent.a && obj.parent.b && (obj.parent.a === obj || obj.parent.b === obj)) { points.push(obj); } return true; }); const graph = { connections : (p) => { const conns = [] p.visitLinked(l => conns.push(l)); conns.push(this.otherEnd(p)); return conns; }, at : function(index) { return points[index]; }, size : function() { return points.length; } }; const loopPoints = Graph.findAllLoops(graph, (p) => p.id, (a, b) => a.id === b.id); const loops = loopPoints.map(l => this.cleanLoop(l)); for (const loop of loops) { for (const point of loop.points) { this.loops.set(point, loop); } } } cleanLoop(loop) { const points = []; const edges = []; for (let i = 0; i < loop.length; i++) { const a = loop[i]; const b = loop[(i + 1) % loop.length]; if (a.parent == b.parent) { points.push(a); edges.push(b.parent); } } return {points, edges}; } mousemove(e) { this.clearMarked(); this.pickedLoop = null; const p = this.viewer.screenToModel(e); this.pickedLoop = this.pickLoop(p); if (this.pickedLoop != null) { for (const obj of this.pickedLoop.edges) { this.mark(obj); } } this.viewer.refresh(); } pickLoop(p) { const pickResult = this.viewer.search(p.x, p.y, DEFAULT_SEARCH_BUFFER, true, false, []); for (const obj of pickResult) { for (const point of [obj.a, obj.b]) { const loop = this.loops.get(point); if (loop) { return loop; } } } return null; } mousedown(e) { if (this.pickedLoop == null) { this.viewer.toolManager.releaseControl(); this.viewer.toolManager.tool.mousedown(e); } else { this.onMousedown(e); } } onMousedown(e) {} } function getEdgeFor(a, b) { if (isEdgeFor(a.parent, a, b)) { return a.parent } else if (isEdgeFor(b.parent, a, b)) { return b.parent; } else { return null; } } function isEdgeFor(obj, a, b) { return (obj.a.id == a.id && obj.b.id == b.id) || (obj.a.id == b.id && obj.b.id == b.id) }