import 'package:fis_jsonrpc/rpc.dart'; import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/interfaces/enums/items.dart'; import 'package:fis_measure/interfaces/process/items/item.dart'; import 'package:fis_measure/interfaces/process/items/item_metas.dart'; import 'package:fis_measure/interfaces/process/workspace/point_info.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_den_measure.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_den_vel_measure.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_density.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_fractal_dim.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_hist.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_perfusion.dart'; import 'package:fis_measure/process/calcuators/urm_calcuators/urm_trace_vel_measure.dart'; import 'package:fis_measure/process/primitives/area_abstract.dart'; import 'package:fis_measure/process/primitives/trace.dart'; import 'package:fis_measure/process/primitives/utils/urm_sharp_copy.dart'; import 'package:fis_measure/utils/prompt_box.dart'; import 'package:flutter/material.dart'; import 'dart:ui' as ui; import 'package:flutter/services.dart'; class URMTraceMeasure extends Trace { URMTraceMeasure(super.meta, super.parent); static bool needPerfusion = false; static URMTraceMeasure createURMTraceDensity(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTraceDensity = URMTraceMeasure(meta, parent); measureTraceDensity.calculator = URMTraceDensityCal( measureTraceDensity, ); return measureTraceDensity; } static URMTraceMeasure createURMTraceFractalDim(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTraceFractalDim = URMTraceMeasure(meta, parent); measureTraceFractalDim.calculator = URMTraceFractalDimCal( measureTraceFractalDim, ); return measureTraceFractalDim; } static URMTraceMeasure createURMTraceDenMeasure(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTraceDen = URMTraceMeasure(meta, parent); measureTraceDen.calculator = URMTraceDenMeasureCal( measureTraceDen, ); return measureTraceDen; } static URMTraceMeasure createURMTraceVelMeasure(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTraceVel = URMTraceMeasure(meta, parent); measureTraceVel.calculator = URMTraceVelMeasureCal( measureTraceVel, ); return measureTraceVel; } static URMTraceMeasure createURMTracePerfusion(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTracePerfusion = URMTraceMeasure(meta, parent); measureTracePerfusion.calculator = URMTracePerfusionCal( measureTracePerfusion, ); needPerfusion = true; return measureTracePerfusion; } static URMTraceMeasure createURMTraceHist(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTraceHist = URMTraceMeasure(meta, parent); measureTraceHist.calculator = URMTraceHistCal( measureTraceHist, ); return measureTraceHist; } static URMTraceMeasure createURMTraceDenVelMeasure(ItemMeta meta, [IMeasureItem? parent]) { URMTraceMeasure measureTraceDenVel = URMTraceMeasure(meta, parent); measureTraceDenVel.calculator = URMTraceDenVelMeasureCal( measureTraceDenVel, ); return measureTraceDenVel; } @override bool onExecuteMouse(PointInfo args) { if (waitingResult) return false; if (state == ItemStates.finished) { if (args.pointType == PointInfoType.mouseDown) { state = ItemStates.waiting; } } if (state == ItemStates.waiting) { if (args.pointType == PointInfoType.mouseDown) { handleMouseDownWhileWaiting(args); } } else if (state == ItemStates.running) { if (args.pointType == PointInfoType.mouseUp) return false; feature?.adopt(args); if (args.pointType == PointInfoType.mouseDown) { handleFinish(); } else { checkAutoSnap(args); } } return true; } @override void handleMouseDownWhileWaiting(PointInfo args) { if (needPerfusion) { feature = TracePerfusionImageFeature(this); } else { super.handleMouseDownWhileWaiting(args); } state = ItemStates.running; } bool waitingResult = false; void handleFinish({bool recordSharp = true}) async { if (recordSharp) { _recordSharp(); } feature!.isActive = false; waitingResult = true; await doCalculateAsync(); doFeatureFinish(); doFeatureUpdate(); // 若不执行,子测量将无法自动切换 PromptBox.dismiss(); waitingResult = false; } void _recordSharp() { UrmSharpCopyBoard.recordSharp( UrmSharpCopyDataType.trace, feature!.innerPoints, ); } /// 自动结束检测 @override bool checkAutoSnap(PointInfo current, [bool autoFinishFeature = true]) { if (feature == null || feature!.innerPoints.length < 3) { isSmartMove = false; return _syncState(false); } // final viewport = feature!.hostVisualArea!.viewport!; if (isAutoSnap == false) return false; final pixelSize = application.displaySize; final p1 = feature!.innerPoints.first.scale2Size(pixelSize); final p2 = current.scale2Size(pixelSize); final length = (p1 - p2).length; if (length > snapThreshold * 2.0 && !isSmartMove) { isSmartMove = true; } if (length < snapThreshold && isSmartMove) { feature!.innerPoints.last = feature!.innerPoints.first.clone(); /// 此处的最后一个点,方便计算,但是绘制时要剔除 // feature!.innerPoints.removeLast(); HapticFeedback.heavyImpact(); if (autoFinishFeature) { handleFinish(); } isSmartMove = false; return _syncState(true); } else { return _syncState(false); } } bool _syncState(bool isSnap) { snapState = isSnap; return snapState; } } class TracePerfusionImageFeature extends TraceFeature { TracePerfusionImageFeature(AreaItemAbstract refItem) : super(refItem); ui.Image? perfusionImg; IntRect? perfusionPiexlRect; DPoint? leftTopPoint; DPoint? rightBottomPoint; @override void paint(Canvas canvas, Size size) { // paintPerfusion(canvas, size); super.paint(canvas, size); } /// 绘制灌注图 @override void paintPerfusion(Canvas canvas, Size size) { if (perfusionImg != null) { Paint paint = Paint(); Rect src = Rect.fromLTWH( 0, 0, perfusionImg!.width.toDouble(), perfusionImg!.height.toDouble(), ); if (leftTopPoint == null || rightBottomPoint == null) { return; } DPoint leftTop = convert2ViewPoint(size, leftTopPoint!); DPoint rightBottom = convert2ViewPoint(size, rightBottomPoint!); convert2ViewPoint(size, rightBottomPoint!); Rect dst = Rect.fromPoints( Offset(leftTop.x, leftTop.y), Offset(rightBottom.x, rightBottom.y)); canvas.drawImageRect(perfusionImg!, src, dst, paint); } } }