use super::doc::{SketchDiagnostics, SketchDoc};
use brep_kernel::{solve_sketch, SolveSketchRequest};
#[derive(Clone, Debug, PartialEq)]
pub struct SketchSolverSettings {
pub tolerance: Option<f64>,
pub iterations: Option<u32>,
pub distance_slide_threshold_ratio: Option<f64>,
pub distance_slide_step_ratio: Option<f64>,
pub distance_slide_min_step: Option<f64>,
}
impl Default for SketchSolverSettings {
fn default() -> Self {
Self {
tolerance: None,
iterations: Some(1000),
distance_slide_threshold_ratio: None,
distance_slide_step_ratio: None,
distance_slide_min_step: None,
}
}
}
pub fn solve(doc: &SketchDoc) -> Result<(SketchDoc, SketchDiagnostics), String> {
solve_with(doc, &SketchSolverSettings::default())
}
pub fn solve_with(
doc: &SketchDoc,
settings: &SketchSolverSettings,
) -> Result<(SketchDoc, SketchDiagnostics), String> {
let sketch = serde_json::to_value(doc).map_err(|e| format!("sketch serialize: {e}"))?;
let request = SolveSketchRequest {
sketch,
iterations: settings.iterations,
remove_implied_duplicates: false,
tolerance: settings.tolerance,
distance_slide_threshold_ratio: settings.distance_slide_threshold_ratio,
distance_slide_step_ratio: settings.distance_slide_step_ratio,
distance_slide_min_step: settings.distance_slide_min_step,
polish: None,
};
let response = solve_sketch(&request)?;
let solved = response
.get("sketch")
.cloned()
.ok_or_else(|| "solve_sketch: response missing `sketch`".to_string())?;
let diagnostics = match solved.get("diagnostics").cloned() {
Some(value) => {
serde_json::from_value(value).map_err(|e| format!("diagnostics parse: {e}"))?
}
None => SketchDiagnostics::default(),
};
let solved_doc: SketchDoc =
serde_json::from_value(solved).map_err(|e| format!("solved sketch parse: {e}"))?;
Ok((solved_doc, diagnostics))
}