open StdLabels module Path = Script_path type 'a selection = | Path of 'a | Point of ('a * Path.Point.t) type t = int selection let find_selection : int selection -> Outline.t list -> Outline.t selection option = fun selection paths -> match selection with | Path id -> Option.map (fun p -> Path p) (Outline.find paths id) | Point (id, pt) -> Option.map (fun p -> Point (p, pt)) (Outline.find paths id) let threshold = 20. let get_from_paths : float * float -> Outline.t list -> float * (Gg.v2 * Outline.t * Path.Point.t * Path.Point.t) option = fun position outlines -> let point = Gg.V2.of_tuple position in (* If the user click on a curve, select it *) List.fold_left outlines ~init:(threshold, None) ~f:(fun (dist, selection) outline -> match Path.Fixed.distance point outline.Outline.path with | Some { closest_point; distance; p0; p1; ratio } when distance < dist -> (ratio, Some (closest_point, outline, p0, p1)) | _ -> (dist, selection) ) let select_path : Outline.t -> t = fun outline -> Path outline.Outline.id let select_point : Outline.t -> Gg.v2 -> t = fun outline v2_point -> let point' = ref None in let dist = ref threshold in Path.Fixed.iter outline.Outline.path ~f:(fun p -> let open Gg.V2 in let new_dist = norm (Path.Point.get_coord p - v2_point) in match new_dist < !dist with | false -> () | true -> dist := new_dist; point' := Some p ); match !point' with | Some point -> Point (outline.Outline.id, point) | None -> Path outline.Outline.id (* (* If the point does not exists, find the exact point on the curve *) let coord = Gg.V2.to_tuple v2_point in begin match get_from_paths coord [path] with | _, None -> Path (Path.Fixed.id path) | f, Some (point, path, p0, p1) -> let point' = Path.Point.mix f point p0 p1 in Point (Path.Fixed.id path, point') end *)