예제 #1
0
        private void CheckHaltingConditions(DynamicSettings settings)
        {
            var staticSettings = ConvertDynSettingsToStatic(settings);
            var toRemove       = new List <Particle>();

            for (int i = 0; i < particles.Count; i++)
            {
                var p = particles[i];

                var add      = false;
                var outBasis = new Basis(p.Current.Point, p.Current.Vector);

                if (!Algos.CheckHaltingConditions(p.Current.Point, p.Start, outBasis, p.Current.Vector.Value, out add, staticSettings) || add == false)
                {
                    toRemove.Add(p);
                }
                else
                {
                    p.Current.Point = outBasis.Point;
                }
            }

            foreach (var remove in toRemove)
            {
                particles.Remove(remove);
            }
        }
예제 #2
0
        private void UpdateWithDynamics(List <IDynamic> dynamics, DynamicSettings settings)
        {
            var points  = new List <GH_Point>(particles.Count);
            var vectors = new List <GH_Vector>(particles.Count);

            for (int i = 0; i < particles.Count; i++)
            {
                points.Add(particles[i].Current.Point);
                vectors.Add(new GH_Vector());
            }

            foreach (var d in dynamics)
            {
                // we need a new list of vectors each way through, which we add seperately to an end result
                // otherwise acceleration can apply across dynamics in unintended ways
                var tempVectors = new List <GH_Vector>(particles.Count);
                for (int i = 0; i < particles.Count; i++)
                {
                    tempVectors.Add(new GH_Vector());
                }

                // post processes use the cumulative vector list
                // pre processes use the temporary empty vector list
                if (d.PostProcess)
                {
                    // vectors is modified inline so we don't need to update as below
                    Algos.ProcessDynamics(d, points, vectors, settings.surface);
                }
                else
                {
                    Algos.ProcessDynamics(d, points, tempVectors, settings.surface);

                    for (int i = 0; i < particles.Count; i++)
                    {
                        vectors[i].Value += tempVectors[i].Value;
                    }
                }
            }

            Algos.RealignAccelerationVectors(dynamics, vectors);

            for (int i = 0; i < points.Count; i++)
            {
                points[i].Value += vectors[i].Value;

                // update particles from resultant p/v's above
                particles[i].Current.Point  = points[i];
                particles[i].Current.Vector = vectors[i];
            }
        }
예제 #3
0
        protected Emitter(int startLife, DynamicSettings settings)
        {
            this.startLife = startLife;

            respawn       = settings.respawn;
            emitTime      = settings.newSpawn;
            emitDeviance  = settings.rndSpawn;
            emitCountDown = new List <int>(); // parallel to startParticles

            particles      = new List <Particle>();
            startParticles = new List <Particle>();

            rnd = new Random();
        }
예제 #4
0
        private StaticSettings ConvertDynSettingsToStatic(DynamicSettings dyn)
        {
            var sta = new StaticSettings();

            // 1:1 functionality
            sta.avgRadius = dyn.avgRadius;
            sta.bounds    = dyn.bounds;
            sta.lineCont  = dyn.lineCont;
            sta.snapAngle = dyn.snapAngle;
            sta.snapTol   = dyn.snapTol;
            sta.surface   = dyn.surface;

            // not used or used differently from regular static usage
            sta.stop      = false; // never use the regular stop checks in dynamic
            sta.tolerance = double.MaxValue;

            return(sta);
        }
예제 #5
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // inputs
            var points          = new List <GH_Point>();
            var vectors         = new List <GH_Vector>();
            var startPoints     = new List <GH_Point>();
            var lifeTime        = new GH_Integer();
            var settings        = new GH_ObjectWrapper();
            var reset           = new GH_Boolean();
            var dynamicsWrapped = new List <GH_ObjectWrapper>();
            var dynamics        = new List <IDynamic>();

            if (DA.GetDataList(0, points) && points == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid points list. Operation canceled.");
                return;
            }

            if (DA.GetDataList(1, vectors) && vectors == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid vector list. Operation canceled.");
                return;
            }

            if (vectors.Count != points.Count && vectors.Count != 0)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Vector list size mismatch with points list, they must be equal in length (or empty). Operation canceled.");
                return;
            }

            if (DA.GetDataList(2, startPoints) && startPoints == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid travelling points. Operation canceled.");
                return;
            }

            if (DA.GetData(3, ref lifeTime) && lifeTime == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid lifetime input. Operation canceled.");
                return;
            }

            if (DA.GetDataList(4, dynamicsWrapped) && dynamicsWrapped == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid dynamics list. Operation canceled.");
                return;
            }
            dynamics = (from d in dynamicsWrapped select d.Value as IDynamic).ToList();
            Algos.SortDynamicsByPriority(dynamics);

            // if vectors list is empty we'll populate it with empty vectors to match each point
            if (vectors.Count == 0)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    vectors.Add(new GH_Vector());
                }
            }

            // spm parameters component is optional, we use its defaults if it is not available
            var spm_settings = new DynamicSettings();

            if (DA.GetData(5, ref settings))
            {
                // if getdata succeeded but the settings var is null we had bad input
                if (settings == null)
                {
                    this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid settings input. Operation canceled.");
                    return;
                }

                // otherwise cast from gh_objectwrapper and continue
                spm_settings = (DynamicSettings)settings.Value;
            }

            if (DA.GetData(6, ref reset) && reset == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid reset input. Operation canceled.");
                return;
            }

            if (emitter == null || reset.Value)
            {
                emitter = new Emitter(startPoints, lifeTime.Value, spm_settings);
                DA.SetDataList(0, startPoints);

                var zv = new List <GH_Vector>(startPoints.Count);
                for (int i = 0; i < startPoints.Count; i++)
                {
                    zv.Add(new GH_Vector());
                }

                Algos.ClearDynamics(dynamics);

                DA.SetDataList(1, zv);
                return;
            }

            // emitter updates dynamics
            emitter.Update(dynamics, points, vectors, spm_settings);

            DA.SetDataList(0, emitter.Points);
            DA.SetDataList(1, emitter.Vectors);
        }
예제 #6
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            var respawn  = new GH_Boolean();
            var newSpawn = new GH_Integer();
            var rndSpawn = new GH_Integer();

            var avgRadius = new GH_Number();
            var bounds    = new GH_Brep();
            var snapTol   = new GH_Number();
            var snapAngle = new GH_Number();
            var surface   = new GH_Surface();
            var lineCont  = new GH_Boolean();

            if (DA.GetData(0, ref respawn) && respawn == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid respawn value. Operation canceled.");
                return;
            }

            if (DA.GetData(1, ref newSpawn) && newSpawn == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid new spawn value. Operation canceled.");
                return;
            }

            if (DA.GetData(2, ref rndSpawn) && rndSpawn == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid new spawn randomizing value. Operation canceled.");
                return;
            }

            if (DA.GetData(3, ref avgRadius) && avgRadius == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid interpolation radius value. Operation canceled.");
                return;
            }

            if (DA.GetData(4, ref bounds) && bounds == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid bounding box. Operation canceled.");
                return;
            }

            if (DA.GetData(5, ref snapTol) && snapTol == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid snap tolerance. Operation canceled.");
                return;
            }

            if (DA.GetData(6, ref snapAngle) && snapAngle == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid snapping angle. Operation canceled.");
                return;
            }

            if (DA.GetData(7, ref surface) && surface == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid surface constraint. Operation canceled.");
                return;
            }

            if (DA.GetData(8, ref lineCont) && lineCont == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid line continuity value. Operation canceled.");
                return;
            }

            DynamicSettings settings = new DynamicSettings();

            settings.respawn   = respawn.Value;
            settings.newSpawn  = newSpawn.Value;
            settings.rndSpawn  = rndSpawn.Value;
            settings.avgRadius = avgRadius.Value;
            settings.bounds    = bounds;
            settings.snapTol   = snapTol.Value;
            settings.snapAngle = snapAngle.Value;
            settings.surface   = surface;
            settings.lineCont  = lineCont.Value;

            var output = new GH_ObjectWrapper(settings);

            DA.SetData(0, output);
        }
예제 #7
0
        private void UpdateIntegration(List <GH_Point> points, List <GH_Vector> vectors, DynamicSettings settings)
        {
            // only integrate if we have a vector field to work with
            if (points.Count > 0)
            {
                // integration
                var bases = new List <Basis>();
                for (int i = 0; i < points.Count; i++)
                {
                    bases.Add(new Basis(points[i], vectors[i]));
                }

                var ptSampling = (points.Count != 0);

                var staticSettings = ConvertDynSettingsToStatic(settings);

                for (int i = 0; i < particles.Count; i++)
                {
                    var p = particles[i];

                    var traveller  = p.Current.Point;
                    var startBasis = p.Start;
                    var vecLast    = p.Current.Vector;

                    var outBasis = new Basis();

                    if (points.Count != 0 &&
                        !Algos.SampleForNextPoint(bases, traveller.Value, startBasis, vecLast, staticSettings, out outBasis))
                    {
                        break;
                    }

                    p.Current.Point  = outBasis.Point;
                    p.Current.Vector = outBasis.Vector;
                }
            }
        }
예제 #8
0
 public void Update(List <IDynamic> dynamics, List <GH_Point> points, List <GH_Vector> vectors, DynamicSettings settings)
 {
     UpdateWithDynamics(dynamics, settings);
     UpdateLifeTimes(dynamics);
     UpdateEmitCounter();
     UpdateIntegration(points, vectors, settings);
     CheckHaltingConditions(settings);
 }
예제 #9
0
 public Emitter(List <GH_Point> points, int startLife, DynamicSettings settings)
     : this(startLife, settings)
 {
     points.ForEach(p => startParticles.Add(new Particle(p, startLife)));
     Begin();
 }
예제 #10
0
        public Emitter(List <GH_Point> points, List <GH_Vector> vectors, int startLife, DynamicSettings settings)
            : this(startLife, settings)
        {
            if (points.Count != vectors.Count)
            {
                throw new ArgumentException("Points and Vectors list must be parallel (same length)!");
            }

            for (int i = 0; i < points.Count; i++)
            {
                startParticles.Add(new Particle(points[i], vectors[i], startLife));
            }

            Begin();
        }
예제 #11
0
 public Emitter(List <Basis> bases, int startLife, DynamicSettings settings)
     : this(startLife, settings)
 {
     bases.ForEach(b => startParticles.Add(new Particle(b, startLife)));
     Begin();
 }