private void DoUpdate() { if (optimizationTask != null) { shouldOptimizeAgain = true; return; } oldSnappedPrimitive = snappedPrimitive; snappedPrimitive = snappersManager.Create(newPrimitive); snappedPrimitive.UpdateFeatureCurves(); var emptyCurvesToAnnotations = new Dictionary <FeatureCurve, ISet <Annotation> >(); var objectivesAndConstraints = snappersManager.Reconstruct(snappedPrimitive, emptyCurvesToAnnotations); var objective = objectivesAndConstraints.Item1; var constraints = objectivesAndConstraints.Item2; var primitivesWriter = primitivesReaderWriterFactory.CreateWriter(); primitivesWriter.Write(snappedPrimitive); var vars = primitivesWriter.GetVariables(); var vals = primitivesWriter.GetValues(); optimizationTask = Task.Factory.StartNew <double[]>( _ => optimizer.Minimize(objective, constraints, vars, vals).Last(), TaskScheduler.Default) .ContinueWith(task => { if (disposed) { return; } var optimum = task.Result; // update primitives from the optimal values primitivesReaderWriterFactory.CreateReader().Read(optimum, snappedPrimitive); snappedPrimitive.UpdateFeatureCurves(); // update the task managment fields. sessionData.SnappedPrimitives.Remove(oldSnappedPrimitive); optimizationTask = null; if (shouldOptimizeAgain) { shouldOptimizeAgain = false; DoUpdate(); } else { sessionData.SnappedPrimitives.Add(snappedPrimitive); eventAggregator.GetEvent <SnapCompleteEvent>().Publish(null); } }, TaskScheduler.FromCurrentSynchronizationContext()); }
public OptimizationProblem CreateProblem() { var curvesToAnnotations = GetCurvesToAnnotationsMapping(); // get objectives and constraints for primitives var constraints = new List <Term>(); var objectives = new List <Term>(); foreach (var snappedPrimitive in sessionData.SnappedPrimitives) { var objectiveAndConstraints = snappersManager.Reconstruct(snappedPrimitive, curvesToAnnotations); objectives.Add(objectiveAndConstraints.Item1); constraints.AddRange(objectiveAndConstraints.Item2); } // add constraints extracted from the annotations var annotationConstraints = from annotation in sessionData.Annotations from constraint in annotationConstraintsExtractor.GetConstraints(annotation) select constraint; constraints.AddRange(annotationConstraints); // perform the optimization. var primitivesWriter = primitivesReaderWriterFactory.CreateWriter(); primitivesWriter.Write(sessionData.SnappedPrimitives); var variables = primitivesWriter.GetVariables(); var values = primitivesWriter.GetValues(); var finalObjective = TermUtils.SafeSum(objectives); return(new OptimizationProblem { Objective = finalObjective, Constraints = constraints.ToArray(), Variables = variables, InitialValue = values, }); }
private void OptimizeAll() { #region Write all variables and their current values to a vector var variablesWriter = new VariableVectorsWriter(); var startVectorWriter = new VectorsWriter(); // write cylinders foreach (var snappedCylinder in sessionData.SnappedPrimitives.OfType <SnappedCylinder>()) { variablesWriter.Write(snappedCylinder); startVectorWriter.Write(snappedCylinder); } // write cones foreach (var snappedCone in sessionData.SnappedPrimitives.OfType <SnappedCone>()) { variablesWriter.Write(snappedCone); startVectorWriter.Write(snappedCone); } #endregion // all objective functions. Will be summed eventually to form one big objective. var objectives = new List <Term>(); // all equality constraints. var constraints = new List <Term>(); var curvesToAnnotations = new Dictionary <FeatureCurve, ISet <Annotation> >(); #region Get mapping of curves to annotations foreach (var fc in sessionData.FeatureCurves) { curvesToAnnotations[fc] = new HashSet <Annotation>(); } foreach (var annotation in sessionData.Annotations) { IEnumerable <FeatureCurve> curves = null; annotation.MatchClass <Parallelism>(pa => curves = pa.Elements); annotation.MatchClass <Coplanarity>(ca => curves = ca.Elements); annotation.MatchClass <Cocentrality>(ca => curves = ca.Elements); Debug.Assert(curves != null); foreach (var fc in curves) { curvesToAnnotations[fc].Add(annotation); } } #endregion #region get objectives and constraints for primitives foreach (var snappedPrimitive in sessionData.SnappedPrimitives) { var objectiveAndConstraints = snappersManager.Reconstruct(snappedPrimitive, curvesToAnnotations); objectives.Add(objectiveAndConstraints.Item1); constraints.AddRange(objectiveAndConstraints.Item2); } #endregion #region get constraints for annotations foreach (var annotation in sessionData.Annotations) { var constraintTerms = GetAnnotationConstraints(annotation); constraints.AddRange(constraintTerms); } #endregion #region perform optimization var finalObjective = TermUtils.SafeSum(objectives); var vars = variablesWriter.ToArray(); var vals = startVectorWriter.ToArray(); var optimum = Optimizer.MinAugmentedLagrangian(finalObjective, constraints.ToArray(), vars, vals, mu: 10, tolerance: 1E-5); #endregion #region read data back from the optimized vector var resultReader = new VectorsReader(optimum); foreach (var snappedCylinder in sessionData.SnappedPrimitives.OfType <SnappedCylinder>()) { resultReader.Read(snappedCylinder); } foreach (var snappedCone in sessionData.SnappedPrimitives.OfType <SnappedCone>()) { resultReader.Read(snappedCone); } #endregion #region Update feature curves foreach (var snappedPrimitive in sessionData.SnappedPrimitives) { snappedPrimitive.UpdateFeatureCurves(); } #endregion }