Example #1
0
        public static bool SampleForNextPoint(List <Basis> bases, Point3d point, Basis start,
                                              GH_Vector lastVec, StaticSettings settings,
                                              out Basis outBasis)
        {
            var tolerance = settings.tolerance;
            var radius    = settings.avgRadius;
            var lineCont  = settings.lineCont;
            var tensorDir = settings.tensorDir;

            outBasis = new Basis();

            GH_Vector ghkv = GetInterpolatedVector(bases, lastVec, lineCont, tensorDir, ref point, tolerance, radius);

            if (ghkv == null)
            {
                return(false);
            }

            var kv = ghkv.Value;

            // po = pt + kv
            outBasis.Vector = new GH_Vector(kv);
            outBasis.Point  = new GH_Point(point + kv);

            return(true);
        }
Example #2
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);
        }
Example #3
0
        public static GH_Point GetPointModifiedByDynamics(GH_Point traveller, Basis outBasis, List <IDynamic> dynamics, StaticSettings spm_settings)
        {
            var output = new GH_Point();

            foreach (var d in dynamics)
            {
                var p = new List <GH_Point>();
                p.Add(traveller);

                var v = new List <GH_Vector>();

                if (d.PostProcess)
                {
                    v.Add(outBasis.Vector);
                }
                else
                {
                    v.Add(new GH_Vector());
                }

                ProcessDynamics(d, p, v, spm_settings.surface);

                if (d.PostProcess)
                {
                    outBasis.Vector.Value = v[0].Value;
                }
                else
                {
                    outBasis.Vector.Value += v[0].Value;
                }
            }

            // realign acceleration if necessary
            var outVec = new List <GH_Vector>()
            {
                outBasis.Vector
            };

            Algos.RealignAccelerationVectors(dynamics, outVec);
            outBasis.Vector = outVec[0];

            // compute our resultant point via the traveller + resultant vectors
            var res = traveller.Value + (outBasis.Vector.Value);

            return(new GH_Point(res));
        }
Example #4
0
        public static bool CheckHaltingConditions(GH_Point traveller, Basis start, Basis outBasis, Vector3d previous, out bool add, StaticSettings settings)
        {
            var stop      = settings.stop;
            var surface   = settings.surface;
            var bounds    = settings.bounds;
            var snapTol   = settings.snapTol;
            var snapAngle = settings.snapAngle;

            add = false;

            if (stop && !previous.IsZero && CheckStopped(previous))
            {
                return(false);
            }

            if (CheckIfOffSurface(outBasis, surface))
            {
                return(false);
            }

            if (CheckInsideBounds(outBasis, traveller, bounds, ref add))
            {
                return(false);
            }

            if (CheckIfOrbitting(outBasis, start, previous, snapTol, snapAngle, ref add))
            {
                return(false);
            }

            add = true;
            return(true);
        }
Example #5
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // inputs
            var points = new List <GH_Point>();
            var planes = new List <GH_Plane>();

            var vectors         = new List <GH_Vector>();
            var traveller       = new GH_Point();
            var settings        = new GH_ObjectWrapper();
            var dynamicsWrapped = new List <GH_ObjectWrapper>();
            var dynamics        = new List <IDynamic>();

            // outputs
            var linePoints = new List <GH_Point>();
            var lineVecs   = new List <GH_Vector>();

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

            if (DA.GetData(2, ref traveller) && traveller == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid travelling point. Operation canceled.");
                return;
            }

            if (DA.GetDataList(3, 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);

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

            if (DA.GetData(4, 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 = (StaticSettings)settings.Value;
            }

            var bases        = new List <Basis>();
            var basesWrapper = new List <GH_ObjectWrapper>();

            // we need to get the vector field information after settings, for tensor settings
            if (spm_settings.tensor && (spm_settings.tensorDir >= 0 && spm_settings.tensorDir <= 2))
            {
                if (DA.GetDataList(1, basesWrapper) && basesWrapper == null)
                {
                    this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid tensor field. Operation canceled.");
                    return;
                }

                for (int i = 0; i < basesWrapper.Count; i++)
                {
                    Basis b = basesWrapper[i].Value as Basis;
                    bases.Add(new Basis(points[i], b.Vectors));
                    bases[i].Axes = spm_settings.tensorAxes;
                }
            }
            else
            {
                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 if you wish to integrate using just dynamics). Operation canceled.");
                    return;
                }

                // if vectors list is empty we'll populate it with empty vectors to match each point
                if (vectors.Count == 0)
                {
                    foreach (var i in Enumerable.Range(0, points.Count))
                    {
                        vectors.Add(new GH_Vector());
                    }
                }

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

            int steps = spm_settings.steps;

            if (steps == 0)
            {
                steps = MAX_ITERATIONS;
            }

            var    startBasis = new Basis(traveller);
            var    vecLast    = new GH_Vector();
            double xy         = 0;
            double yz         = 0;
            double xz         = 0;

            // add start point to output
            linePoints.Add(startBasis.Point);

            Algos.ClearDynamics(dynamics);

            // find each next point based on an averaging formula and iterate
            for (int i = 0; i < steps; i++)
            {
                bool add      = false;
                var  outBasis = new Basis();

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

                if (dynamics.Count > 0)
                {
                    traveller      = Algos.GetPointModifiedByDynamics(traveller, outBasis, dynamics, spm_settings);
                    outBasis.Point = traveller;
                }
                else
                {
                    traveller = outBasis.Point;
                }

                // this step must be done oustide of the regular halting checks as we must store the axes rotations
                if (spm_settings.windAngle != 0.0d && !vecLast.Value.IsZero &&
                    Algos.IsWoundPast(outBasis.Vector.Value, vecLast.Value, spm_settings.windAngle, ref xy, ref yz, ref xz))
                {
                    break;
                }

                var working = Algos.CheckHaltingConditions(traveller, startBasis, outBasis, vecLast.Value, out add, spm_settings);

                traveller = outBasis.Point;
                vecLast   = outBasis.Vector;

                // cache the vector between start and start+1
                if (i == 0 && working)
                {
                    startBasis.Vector.Value = traveller.Value - startBasis.Point.Value;
                }

                if (add)
                {
                    linePoints.Add(traveller);
                    lineVecs.Add(vecLast);
                }

                if (!working)
                {
                    break;
                }
            }

            DA.SetDataList(0, linePoints);
            DA.SetDataList(1, lineVecs);
        }
Example #6
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            var steps      = new GH_Integer();
            var tolerance  = new GH_Number();
            var stop       = new GH_Boolean();
            var windAngle  = new GH_Number();
            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 tensor     = new GH_Boolean();
            var tensorDir  = new GH_Integer();
            var tensorAxes = new List <GH_Integer>();
            var lineCont   = new GH_Boolean();

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

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

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

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

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

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

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

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

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

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

            if (DA.GetData(10, ref tensorDir) && tensorDir == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid tensor direction. Operation canceled.");
                return;
            }

            if (tensorDir.Value < 0 || tensorDir.Value > 2)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid tensor direction. Valid input is 0-2. Operation canceled.");
                return;
            }

            if (DA.GetDataList(11, tensorAxes) && tensorAxes == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid tensor direction. Operation canceled.");
                return;
            }

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

            StaticSettings settings = new StaticSettings();

            settings.steps     = steps.Value;
            settings.stop      = stop.Value;
            settings.windAngle = windAngle.Value;
            settings.tolerance = tolerance.Value;
            settings.avgRadius = avgRadius.Value;
            settings.bounds    = bounds;
            settings.snapTol   = snapTol.Value;
            settings.snapAngle = snapAngle.Value;
            settings.surface   = surface;
            settings.tensor    = tensor.Value;
            settings.tensorDir = tensorDir.Value;
            settings.lineCont  = lineCont.Value;

            if (tensorAxes.Count == 0)
            {
                settings.tensorAxes.Add(0);
                settings.tensorAxes.Add(1);
            }
            else
            {
                foreach (var axis in tensorAxes)
                {
                    settings.tensorAxes.Add(axis.Value);
                }
            }

            if (settings.tensor == false)
            {
                settings.tensorDir = -1;
            }

            var output = new GH_ObjectWrapper(settings);

            DA.SetData(0, output);
        }