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); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { FlexScene scene = new FlexScene(); List <FlexParticle> parts = new List <FlexParticle>(); //List<Fluid> fluids = new List<Fluid>(); List <RigidBody> rigids = new List <RigidBody>(); List <SoftBody> softs = new List <SoftBody>(); List <SpringSystem> springs = new List <SpringSystem>(); List <Cloth> cloths = new List <Cloth>(); List <Inflatable> inflatables = new List <Inflatable>(); List <ConstraintSystem> constraints = new List <ConstraintSystem>(); DA.GetDataList(0, parts); //DA.GetDataList(1, fluids); DA.GetDataList(1, rigids); DA.GetDataList(2, softs); DA.GetDataList(3, springs); DA.GetDataList(4, cloths); DA.GetDataList(5, inflatables); DA.GetDataList(6, constraints); foreach (FlexParticle p in parts) { scene.RegisterParticles(new float[3] { p.PositionX, p.PositionY, p.PositionZ }, new float[3] { p.VelocityX, p.VelocityY, p.VelocityZ }, new float[1] { p.InverseMass }, p.IsFluid, p.SelfCollision, p.GroupIndex); } //foreach (Fluid f in fluids) //scene.RegisterFluid(f.Positions, f.Velocities, f.InvMasses, f.GroupIndex); foreach (RigidBody r in rigids) { scene.RegisterRigidBody(r.Vertices, r.VertexNormals, r.Velocity, r.InvMasses, r.Stiffness, r.GroupIndex); } foreach (SoftBody s in softs) { if (s.Asset != 0) { scene.RegisterAsset(s.Asset, s.Velocity, s.InvMass, s.GroupIndex, true); } } foreach (SpringSystem s in springs) { s.SpringOffset = scene.RegisterSpringSystem(s.Positions, s.Velocities, s.InvMasses, s.SpringPairIndices, s.Stiffnesses, s.TargetLengths, s.SelfCollision, s.AnchorIndices, s.GroupIndex); } foreach (Cloth c in cloths) { scene.RegisterCloth(c.Positions, c.Velocities, c.InvMasses, c.Triangles, c.TriangleNormals, c.StretchStiffness, c.BendingStiffness, c.PreTensionFactor, c.AnchorIndices, c.SelfCollision, c.GroupIndex); } foreach (Inflatable inf in inflatables) { scene.RegisterInflatable(inf.Positions, inf.Velocities, inf.InvMasses, inf.Triangles, inf.TriangleNormals, inf.StretchStiffness, inf.BendingStiffness, inf.PreTensionFactor, inf.RestVolume, inf.OverPressure, inf.ConstraintScale, inf.AnchorIndices, inf.SelfCollision, inf.GroupIndex); } foreach (ConstraintSystem c in constraints) { scene.RegisterCustomConstraints(c.AnchorIndices, c.ShapeMatchingIndices, c.ShapeStiffness, c.SpringPairIndices, c.SpringStiffnesses, c.SpringTargetLengths, c.TriangleIndices, c.TriangleNormals); } DA.SetData(0, scene); }
public SoftBody(float[] vertices, float[] velocity, float invMass, int[] triangles, float[] softParams, int groupIndex, ref GH_Structure <GH_Point> particleTree, ref GH_Structure <GH_Integer> spiTree, ref GH_Structure <GH_Integer> smcTree, ref GH_Structure <GH_Line> lineTree, ref GH_Structure <GH_Box> boxTree) { Vertices = vertices; Triangles = triangles; Velocity = velocity; InvMass = invMass; SoftParams = softParams; GroupIndex = groupIndex; Asset = 0; InitialParticles = new List <GH_Point>(); SpringIndices = new GH_Structure <GH_Integer>(); ShapeIndices = new GH_Structure <GH_Integer>(); NewMeshFaces = new List <MeshFace>(); unsafe { void *asset = null; FlexScene.InitSoftBodyFromMesh(ref asset, vertices, triangles, softParams[0], softParams[1], softParams[2], softParams[3], softParams[4], softParams[5], softParams[6], softParams[7], softParams[8]); Asset = (ulong)asset; float[] initParticles = new float[0]; int[] springIndices = new int[0]; int[][] shapeIndices = new int[0][]; FlexScene.UnwrapSoftBody(asset, ref initParticles, ref springIndices, ref shapeIndices); int gPathIndex = particleTree.Branches.Count; GH_Path globalPath = new GH_Path(gPathIndex); for (int i = 0; i < initParticles.Length; i += 3) { GH_Point pt = new GH_Point(new Point3d((double)initParticles[i], (double)initParticles[i + 1], (double)initParticles[i + 2])); InitialParticles.Add(pt); particleTree.Append(pt, new GH_Path(gPathIndex)); } for (int i = 0; i < springIndices.Length; i += 2) { //add to this very object GH_Path p = new GH_Path(i / 2); SpringIndices.Append(new GH_Integer(springIndices[i]), p); SpringIndices.Append(new GH_Integer(springIndices[i + 1]), p); //add to global tree for display GH_Path gp = new GH_Path(gPathIndex, i / 2); spiTree.Append(new GH_Integer(springIndices[i]), gp); spiTree.Append(new GH_Integer(springIndices[i + 1]), gp); lineTree.Append( new GH_Line(new Line(InitialParticles[springIndices[i]].Value, InitialParticles[springIndices[i + 1]].Value)), globalPath); } for (int i = 0; i < shapeIndices.Length; i++) { //add to this very object GH_Path p = new GH_Path(i); GH_Path gp = new GH_Path(gPathIndex, i); List <Point3d> smcPoints = new List <Point3d>(); for (int j = 0; j < shapeIndices[i].Length; j++) { ShapeIndices.Append(new GH_Integer(shapeIndices[i][j]), p); smcTree.Append(new GH_Integer(shapeIndices[i][j]), gp); smcPoints.Add(InitialParticles[shapeIndices[i][j]].Value); } boxTree.Append(new GH_Box(new BoundingBox(smcPoints)), globalPath); } } }