/// <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) { List <Mesh> meshes = new List <Mesh>(); List <Vector3d> velocities = new List <Vector3d>(); List <double> masses = new List <double>() { 1.0 }; List <double> softParams = new List <double>(); List <int> groupIndices = new List <int>(); DA.GetDataList(0, meshes); DA.GetDataList(1, velocities); DA.GetDataList(2, masses); DA.GetDataList(3, softParams); DA.GetDataList(4, groupIndices); List <SoftBody> softBodies = new List <SoftBody>(); GH_Structure <GH_Point> ptTree = new GH_Structure <GH_Point>(); GH_Structure <GH_Integer> spiTree = new GH_Structure <GH_Integer>(); GH_Structure <GH_Integer> sciTree = new GH_Structure <GH_Integer>(); GH_Structure <GH_Line> lnTree = new GH_Structure <GH_Line>(); GH_Structure <GH_Box> boxTree = new GH_Structure <GH_Box>(); for (int i = 0; i < meshes.Count; i++) { Mesh mesh = new Mesh(); //make new super shallow copy, as user referenced meshes are crazy heavy smh mesh.Vertices.AddVertices(meshes[i].Vertices); mesh.Faces.AddFaces(meshes[i].Faces); mesh.UnifyNormals(); mesh.Normals.ComputeNormals(); mesh.Normals.UnitizeNormals(); float[] vertices = new float[mesh.Vertices.Count * 3]; float[] velocity = new float[3]; float invMass = 1.0f; for (int j = 0; j < mesh.Vertices.Count; j++) { //set vertices vertices[3 * j] = mesh.Vertices[j].X; vertices[3 * j + 1] = mesh.Vertices[j].Y; vertices[3 * j + 2] = mesh.Vertices[j].Z; } //set velocities if (velocities.Count == 1) { velocity[0] = (float)velocities[0].X; velocity[1] = (float)velocities[0].Y; velocity[2] = (float)velocities[0].Z; } else if (velocities.Count > i) { velocity[0] = (float)velocities[i].X; velocity[1] = (float)velocities[i].Y; velocity[2] = (float)velocities[i].Z; } //set masses if (masses.Count == 1) { invMass = 1.0f / (float)masses[0]; } else if (masses.Count > i) { invMass = 1.0f / (float)masses[i]; } int[] triangles = new int[mesh.Faces.Count * 3]; for (int j = 0; j < mesh.Faces.Count; j++) { triangles[3 * j] = mesh.Faces[j].A; triangles[3 * j + 1] = mesh.Faces[j].B; triangles[3 * j + 2] = mesh.Faces[j].C; } float[] softParameters = new float[9]; if (softParams.Count == 9) { for (int j = 0; j < 9; j++) { softParameters[j] = (float)softParams[j]; } } else if (softParams.Count == 6) { softParameters[0] = 1.0e-18f; softParameters[1] = 0; softParameters[2] = 1.0e-18f; for (int j = 0; j < 6; j++) { softParameters[j + 3] = (float)softParams[j]; } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Either supply all nine soft param values or leave out the first three."); } int groupIndex = i; if (groupIndices.Count == 1) { groupIndex += groupIndices[0]; } else if (groupIndices.Count > i) { groupIndex = groupIndices[i]; } SoftBody softBody = new SoftBody(vertices, velocity, invMass, triangles, softParameters, groupIndex, ref ptTree, ref spiTree, ref sciTree, ref lnTree, ref boxTree); softBody.Mesh = mesh; softBodies.Add(softBody); if (mesh.Vertices.Count != softBody.InitialParticles.Count && softParams.Count == 6) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Sorry, I couldn't generate valid new mesh faces. The mesh preview in GetSoftBodies will not work!"); } else if (mesh.Vertices.Count == softBody.InitialParticles.Count && softParams.Count == 6) { softBody.GenerateShuffledFaces(); } } DA.SetDataTree(0, ptTree); DA.SetDataTree(1, spiTree); DA.SetDataTree(2, sciTree); DA.SetDataTree(3, lnTree); DA.SetDataTree(4, boxTree); DA.SetDataList(5, softBodies); }