protected override void SolveInstance(IGH_DataAccess DA) { //CONTINUE HERE!!!! UpdateTask = new Task <int>(() => Update()); FlexParams param = new FlexParams(); FlexCollisionGeometry geom = new FlexCollisionGeometry(); List <FlexForceField> forceFields = new List <FlexForceField>(); List <FlexScene> scenes = new List <FlexScene>(); List <ConstraintSystem> constraints = new List <ConstraintSystem>(); FlexSolverOptions options = new FlexSolverOptions(); bool reset = false; bool go = false; DA.GetData(6, ref reset); DA.GetData(7, ref go); if (reset) { //reset everything related to time tracking counter = 0; totalTimeMs = 0; totalUpdateTimeMs = 0; sw.Stop(); sw.Reset(); outInfo = new List <string>(); //retrieve relevant data DA.GetData(0, ref param); DA.GetData(1, ref geom); DA.GetDataList(2, forceFields); DA.GetDataList(3, scenes); DA.GetDataList(4, constraints); DA.GetData(5, ref options); sceneTimeStamps = new List <int>(); forceFieldTimeStamps = new List <int>(); //destroy old Flex instance if (flex != null) { flex.Destroy(); } //Create new instance and assign everything flex = new Flex(); flex.SetParams(param); flex.SetCollisionGeometry(geom); flex.SetForceFields(forceFields); foreach (FlexForceField f in forceFields) { forceFieldTimeStamps.Add(f.TimeStamp); } FlexScene scene = new FlexScene(); foreach (FlexScene s in scenes) { scene.AppendScene(s); sceneTimeStamps.Add(s.TimeStamp); } foreach (ConstraintSystem c in constraints) { scene.RegisterCustomConstraints(c.AnchorIndices, c.ShapeMatchingIndices, c.ShapeStiffness, c.SpringPairIndices, c.SpringStiffnesses, c.SpringTargetLengths, c.TriangleIndices, c.TriangleNormals); constraintTimeStamps.Add(c.TimeStamp); } flex.SetScene(scene); flex.SetSolverOptions(options); } else if (go && flex != null && flex.IsReady()) { DA.GetData(5, ref options); if (options.TimeStamp != optionsTimeStamp) { flex.SetSolverOptions(options); } if (options.SceneMode == 0 || options.SceneMode == 1) { //update params if timestamp expired DA.GetData(0, ref param); if (param.TimeStamp != paramsTimeStamp) { flex.SetParams(param); paramsTimeStamp = param.TimeStamp; } //update geom if timestamp expired if (DA.GetData(1, ref geom)) { if (geom.TimeStamp != geomTimeStamp) { flex.SetCollisionGeometry(geom); geomTimeStamp = geom.TimeStamp; } } else if (geom != null) { flex.SetCollisionGeometry(new FlexCollisionGeometry()); } //update forcefields where timestamp expired DA.GetDataList(2, forceFields); bool needsUpdate = false; for (int i = forceFieldTimeStamps.Count; i < forceFields.Count; i++) { forceFieldTimeStamps.Add(forceFields[i].TimeStamp); needsUpdate = true; } for (int i = 0; i < forceFields.Count; i++) { if (forceFields[i].TimeStamp != forceFieldTimeStamps[i]) { needsUpdate = true; forceFieldTimeStamps[i] = forceFields[i].TimeStamp; } } if (needsUpdate) { flex.SetForceFields(forceFields); } //update scenes where timestamp expired DA.GetDataList(3, scenes); for (int i = sceneTimeStamps.Count; i < scenes.Count; i++) { sceneTimeStamps.Add(scenes[i].TimeStamp); } for (int i = 0; i < scenes.Count; i++) { if (scenes[i].TimeStamp != sceneTimeStamps[i]) { if (options.SceneMode == 0) { flex.SetScene(flex.Scene.AlterScene(scenes[i], false)); } else { flex.SetScene(flex.Scene.AppendScene(scenes[i])); } sceneTimeStamps[i] = scenes[i].TimeStamp; } } DA.GetDataList(4, constraints); for (int i = constraintTimeStamps.Count; i < constraints.Count; i++) { constraintTimeStamps.Add(constraints[i].TimeStamp); } for (int i = 0; i < constraints.Count; i++) { ConstraintSystem c = constraints[i]; if (c.TimeStamp != constraintTimeStamps[i]) { if (!flex.Scene.RegisterCustomConstraints(c.AnchorIndices, c.ShapeMatchingIndices, c.ShapeStiffness, c.SpringPairIndices, c.SpringStiffnesses, c.SpringTargetLengths, c.TriangleIndices, c.TriangleNormals)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Custom constraint indices exceeded particle count. No constraints applied!"); } flex.SetScene(flex.Scene); constraintTimeStamps[i] = constraints[i].TimeStamp; } } } //Add timing info outInfo = new List <string>(); counter++; outInfo.Add(counter.ToString()); long currentTickTimeMs = sw.ElapsedMilliseconds; sw.Restart(); totalTimeMs += currentTickTimeMs; outInfo.Add(totalTimeMs.ToString()); outInfo.Add(currentTickTimeMs.ToString()); float avTotalTickTime = ((float)totalTimeMs / (float)counter); outInfo.Add(avTotalTickTime.ToString()); //start update UpdateTask.Start(); //Add solver timing info int tickTimeSolver = UpdateTask.Result; totalUpdateTimeMs += tickTimeSolver; float ratUpdateTime = ((float)totalUpdateTimeMs / (float)counter); outInfo.Add(tickTimeSolver.ToString()); outInfo.Add(ratUpdateTime.ToString()); } if (go && options.FixedTotalIterations < 1) { ExpireSolution(true); } else if (flex != null && UpdateTask.Status == TaskStatus.Running) { UpdateTask.Dispose(); } if (flex != null) { DA.SetData(0, flex); } DA.SetDataList(1, outInfo); }