Example #1
0
        void FinalizeConstruction()
        {
            if (bvs.Count == 1)
            {
                // this node is leaf
                box    = bvs[0];
                isLeaf = true;
                return;
            }

            // find bounding box for bvs
            box = new kDOP24();
            foreach (kDOP24 bv in bvs)
            {
                box.Expand(bv);
            }
            double dX, dY, dZ;

            box.Dimensions(out dX, out dY, out dZ);

            // arrays where left and right portions will be stored
            List <kDOP24> left  = new List <kDOP24>(bvs.Count);
            List <kDOP24> right = new List <kDOP24>(bvs.Count);

            // identify splitting axis and split
            if (dX >= dY && dX >= dZ)
            {
                double center = box.centerX;
                foreach (kDOP24 bv in bvs)
                {
                    if (bv.centerX < center)
                    {
                        left.Add(bv);
                    }
                    else
                    {
                        right.Add(bv);
                    }
                }
                // make sure that there is at least one element on each side
                if (left.Count == 0)
                {
                    kDOP24 selected = null;
                    double min1     = double.MaxValue;
                    foreach (kDOP24 bv in right)
                    {
                        if (min1 >= bv.centerX)
                        {
                            min1 = bv.centerX; selected = bv;
                        }
                    }
                    left.Add(selected);
                    right.Remove(selected);
                }
                else if (right.Count == 0)
                {
                    kDOP24 selected = null;
                    double min1     = double.MaxValue;
                    foreach (kDOP24 bv in left)
                    {
                        if (min1 >= bv.centerX)
                        {
                            min1 = bv.centerX; selected = bv;
                        }
                    }
                    right.Add(selected);
                    left.Remove(selected);
                }
            }
            else if (dY >= dX && dY >= dZ)
            {
                double center = box.centerY;
                foreach (kDOP24 bv in bvs)
                {
                    if (bv.centerY < center)
                    {
                        left.Add(bv);
                    }
                    else
                    {
                        right.Add(bv);
                    }
                }
                if (left.Count == 0)
                {
                    kDOP24 selected = null;
                    double min1     = double.MaxValue;
                    foreach (kDOP24 bv in right)
                    {
                        if (min1 >= bv.centerY)
                        {
                            min1 = bv.centerY; selected = bv;
                        }
                    }
                    left.Add(selected);
                    right.Remove(selected);
                }
                else if (right.Count == 0)
                {
                    kDOP24 selected = null;
                    double min1     = double.MaxValue;
                    foreach (kDOP24 bv in left)
                    {
                        if (min1 >= bv.centerY)
                        {
                            min1 = bv.centerY; selected = bv;
                        }
                    }
                    right.Add(selected);
                    left.Remove(selected);
                }
            }
            else
            {
                double center = box.centerZ;
                foreach (kDOP24 bv in bvs)
                {
                    if (bv.centerZ < center)
                    {
                        left.Add(bv);
                    }
                    else
                    {
                        right.Add(bv);
                    }
                }
                if (left.Count == 0)
                {
                    kDOP24 selected = null;
                    double min1     = double.MaxValue;
                    foreach (kDOP24 bv in right)
                    {
                        if (min1 >= bv.centerZ)
                        {
                            min1 = bv.centerZ; selected = bv;
                        }
                    }
                    left.Add(selected);
                    right.Remove(selected);
                }
                else if (right.Count == 0)
                {
                    kDOP24 selected = null;
                    double min1     = double.MaxValue;
                    foreach (kDOP24 bv in left)
                    {
                        if (min1 >= bv.centerZ)
                        {
                            min1 = bv.centerZ; selected = bv;
                        }
                    }
                    right.Add(selected);
                    left.Remove(selected);
                }
            }
            left.TrimExcess();
            right.TrimExcess();

            child1 = new BVHN(this, left, level + 1);
            child2 = new BVHN(this, right, level + 1);
        }
Example #2
0
        public void PrepareToCompute()
        {
            // this is called once before simulation starts
            mc.Prepare();

            if (cf == null)
            {
                mc.Reset();
                // initialize current frame
                cf = new FrameInfo();
                cf.TimeScaleFactor = 16;
                allFrames.Clear();
                allFrames.Add(cf);
                cf.nCZ_Initial = mc.nonFailedCZs.Length;
                SaveSimulationInitialState();
                SaveStep();
                gf.prms = prms;
                gf.SetConstants();
            }

            // identify and mark anchored nodes
            foreach (Mesh deformableMesh in mc.deformables)
            {
                foreach (SurfaceFragment sf in deformableMesh.surfaceFragments)
                {
                    if (sf.role == SurfaceFragment.SurfaceRole.Anchored)
                    {
                        foreach (int idx in sf.faces)
                        {
                            Face f = deformableMesh.faces[idx];
                            foreach (Node nd in f.vrts)
                            {
                                nd.anchored = true; nd.altId = -1;
                            }
                        }
                    }
                }
            }

            mc.activeNodes = Array.FindAll(mc.allNodes, nd => { return(nd.anchored == false); });
            for (int i = 0; i < mc.activeNodes.Length; i++)
            {
                mc.activeNodes[i].altId = i;
            }

            if (allFrames[allFrames.Count - 1] != cf)
            {
                // trim frame list
                int from = cf.StepNumber + 1;
                int qty  = allFrames.Count - cf.StepNumber - 1;
                allFrames.RemoveRange(cf.StepNumber + 1, allFrames.Count - cf.StepNumber - 1);
            }

            // find surface elements in all meshes, create leaf KDOP list
            bvh.b24.Clear();
            bvh.prms = prms;
            bvh.ForceReconstruct();
            foreach (Mesh mg in mc.mgs)
            {
                mg.IdentifySurfaceElements();
                mg.ConnectFaces();

                foreach (Element elem in mg.surfaceElements)
                {
                    kDOP24 k = new kDOP24();
                    k.elem = elem;
                    bvh.b24.Add(k);
                    elem.FindAdjFaces();
                }
            }
            mc.PrepareSurfaceElements();
            mc.UpdateStaticStructureData(linearSystem.csrd);

            gf.linearSystem = linearSystem;
            gf.prms         = prms;
            gf.mc           = mc;
            gf.ctx.SetCurrent();
            gf.cf = cf;
            gf.TransferStaticDataToDevice();

            isReady = true;
        }