예제 #1
0
        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);
        }
예제 #2
0
        /// <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 <Plane>   planes  = new List <Plane>();
            List <Surface> spheres = new List <Surface>();
            List <Box>     boxes   = new List <Box>();
            List <Mesh>    meshes  = new List <Mesh>();
            List <Mesh>    cmeshes = new List <Mesh>();

            FlexCollisionGeometry geom = new FlexCollisionGeometry();

            DA.GetDataList(0, planes);
            DA.GetDataList(1, spheres);
            DA.GetDataList(2, boxes);
            DA.GetDataList(3, meshes);
            DA.GetDataList(4, cmeshes);

            foreach (Plane p in planes)
            {
                double[] pe = p.GetPlaneEquation();
                geom.AddPlane((float)pe[0], (float)pe[1], (float)pe[2], (float)pe[3]);
            }

            foreach (Surface s in spheres)
            {
                Sphere sph;
                if (!s.TryGetSphere(out sph))
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "At least one sphere is not a sphere");
                }
                else
                {
                    geom.AddSphere(new float[] { (float)sph.Center.X,
                                                 (float)sph.Center.Y,
                                                 (float)sph.Center.Z },
                                   (float)sph.Radius);
                }
            }

            foreach (Box b in boxes)
            {
                if (!b.IsValid)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid box!");
                }
                else
                {
                    Plane p = Plane.WorldXY;
                    p.Origin = b.Center;
                    Quaternion q = Quaternion.Rotation(Plane.WorldXY, b.Plane);


                    geom.AddBox(new float[] { (float)(b.X.Length * 0.5), (float)(b.Y.Length * 0.5), (float)(b.Z.Length * 0.5) },
                                new float[] { (float)b.Center.X, (float)b.Center.Y, (float)b.Center.Z },
                                new float[] { (float)q.Vector.X, (float)q.Vector.Y, (float)q.Vector.Z, (float)q.Scalar });
                }
            }

            foreach (Mesh m in meshes)
            {
                if (!m.IsValid)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid mesh!");
                }
                else
                {
                    //Flex wants face normals to be pointing inward
                    m.Flip(false, false, true);

                    float[] vertices = new float[m.Vertices.Count * 3];
                    int[]   faces    = new int[m.Faces.Count * 3];
                    for (int i = 0; i < vertices.Length / 3; i++)
                    {
                        vertices[i * 3]     = m.Vertices[i].X;
                        vertices[i * 3 + 1] = m.Vertices[i].Y;
                        vertices[i * 3 + 2] = m.Vertices[i].Z;
                    }
                    for (int i = 0; i < faces.Length / 3; i++)
                    {
                        faces[i * 3]     = m.Faces[i].A;
                        faces[i * 3 + 1] = m.Faces[i].B;
                        faces[i * 3 + 2] = m.Faces[i].C;
                    }

                    //add mesh
                    geom.AddMesh(vertices, faces);

                    if (!m.IsClosed)
                    {
                        Mesh mm = m.DuplicateMesh();
                        mm.Flip(true, true, true);
                        vertices = new float[mm.Vertices.Count * 3];
                        faces    = new int[mm.Faces.Count * 3];
                        for (int i = 0; i < vertices.Length / 3; i++)
                        {
                            vertices[i * 3]     = mm.Vertices[i].X;
                            vertices[i * 3 + 1] = mm.Vertices[i].Y;
                            vertices[i * 3 + 2] = mm.Vertices[i].Z;
                        }
                        for (int i = 0; i < faces.Length / 3; i++)
                        {
                            faces[i * 3]     = mm.Faces[i].A;
                            faces[i * 3 + 1] = mm.Faces[i].B;
                            faces[i * 3 + 2] = mm.Faces[i].C;
                        }

                        //add mesh
                        geom.AddMesh(vertices, faces);
                    }
                }
            }

            foreach (Mesh m in cmeshes)
            {
                if (!m.IsClosed || !m.IsValid)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid mesh!");
                }
                else
                {
                    int planeCount = m.Faces.Count;

                    m.FaceNormals.ComputeFaceNormals();

                    float[] cPlanes    = new float[planeCount * 4];
                    float[] upperLimit = new float[3] {
                        (float)m.Vertices[0].X, (float)m.Vertices[0].Y, (float)m.Vertices[0].Z
                    };
                    float[] lowerLimit = new float[3] {
                        (float)m.Vertices[0].X, (float)m.Vertices[0].Y, (float)m.Vertices[0].Z
                    };

                    foreach (Point3d v in m.Vertices)
                    {
                        if (v.X > upperLimit[0])
                        {
                            upperLimit[0] = (float)v.X;
                        }
                        if (v.Y > upperLimit[1])
                        {
                            upperLimit[1] = (float)v.Y;
                        }
                        if (v.Z > upperLimit[2])
                        {
                            upperLimit[2] = (float)v.Z;
                        }
                        if (v.X < lowerLimit[0])
                        {
                            lowerLimit[0] = (float)v.X;
                        }
                        if (v.Y < lowerLimit[1])
                        {
                            lowerLimit[1] = (float)v.Y;
                        }
                        if (v.Z < lowerLimit[2])
                        {
                            lowerLimit[2] = (float)v.Z;
                        }
                    }

                    for (int i = 0; i < planeCount; i++)
                    {
                        Point3d faceCenter = new Point3d((m.Vertices[m.Faces[i].A].X + m.Vertices[m.Faces[i].B].X + m.Vertices[m.Faces[i].C].X) / 3.0,
                                                         (m.Vertices[m.Faces[i].A].Y + m.Vertices[m.Faces[i].B].Y + m.Vertices[m.Faces[i].C].Y) / 3.0,
                                                         (m.Vertices[m.Faces[i].A].Z + m.Vertices[m.Faces[i].B].Z + m.Vertices[m.Faces[i].C].Z) / 3.0);
                        Plane p = new Plane(faceCenter, m.FaceNormals[i] * -1);

                        double[] ABCD = p.GetPlaneEquation();

                        cPlanes[i * 4]     = (float)ABCD[0];
                        cPlanes[i * 4 + 1] = (float)ABCD[1];
                        cPlanes[i * 4 + 2] = (float)ABCD[2];
                        cPlanes[i * 4 + 3] = (float)ABCD[3];
                    }

                    //add convex mesh
                    geom.AddConvexShape(cPlanes, upperLimit, lowerLimit);
                }
            }

            DA.SetData(0, geom);
        }