Example #1
0
 /// <summary>
 /// Called when a tool property has changed
 /// </summary>
 /// <param name="sender">Changed tool</param>
 /// <param name="e">Information about the changed property</param>
 private static void ExtruderPropertyChanged(object sender, PropertyChangedEventArgs e)
 {
     if (e.PropertyName == nameof(Extruder.Filament))
     {
         Extruder extruder = (Extruder)sender;
         using (_lock.Lock(Program.CancellationToken))
         {
             int extruderIndex = Provider.Get.Move.Extruders.IndexOf(extruder);
             if (!_filamentMapping.TryGetValue(extruderIndex, out string filament) || filament != extruder.Filament)
             {
                 if (!string.IsNullOrEmpty(filament) && Macro.RunningConfig)
                 {
                     // Booting RRF, tell it about the loaded filament
                     _logger.Debug("Assigning filament {0} to extruder drive {1}", filament, extruderIndex);
                     SPI.Interface.AssignFilament(extruderIndex, filament);
                 }
                 else
                 {
                     // Filament changed
                     _logger.Debug("Filament {0} has been assigned to extruder drive {1}", extruder.Filament, extruderIndex);
                     _filamentMapping[extruderIndex] = extruder.Filament;
                     SaveMapping();
                 }
             }
         }
     }
 }
Example #2
0
        public void cmd_Tn(Dictionary <string, object> parameters)
        {
            // Select Tool
            var extruders = Extruder.get_printer_extruders(this.printer);
            var index     = this.get_int("T", parameters, minval: 0, maxval: extruders.Count - 1);
            var e         = extruders[index];

            if (object.ReferenceEquals(this.extruder, e))
            {
                return;
            }
            this.run_script_from_command(this.extruder.get_activate_gcode(false));
            try
            {
                this.toolhead.set_extruder(e);
            }
            catch (Exception ex)
            {
                throw new GCodeException(e.ToString(), ex);
            }
            this.extruder = e;
            this.reset_last_position();
            this.extrude_factor  = 1.0;
            this.base_position.W = this.last_position.W;
            this.run_script_from_command(this.extruder.get_activate_gcode(true));
        }
    public override void prepare(TrackSegment4 trackSegment, GameObject putMeshOnGO)
    {
        base.prepare(trackSegment, putMeshOnGO);

        liftExtruder1 = null;

        if (trackSegment.isLifthill && (trackSegment is ChangeHeight4 || trackSegment.getStartpoint().y != trackSegment.getEndpoint().y || (UnityEngine.Object)frictionWheelsGO == (UnityEngine.Object)null))
        {
            liftExtruder1 = instantiateLiftExtruder(trackSegment);
        }

        putMeshOnGO.GetComponent <Renderer>().sharedMaterial = base.material;
        centerTubeExtruder = new TubeExtruder(centerTubeRadius, centerTubeVertCount);
        centerTubeExtruder.setUV(14, 15);
        centerTubeExtruder.closeEnds = true;
        centerBoxExtruder            = new BoxExtruder(centerTubeRadius * 2f, centerTubeRadius * 2f);
        centerBoxExtruder.setUV(14, 15);
        centerBoxExtruder.closeEnds = true;
        leftTubeExtruder            = new TubeExtruder(sideTubesRadius, sideTubesVertCount);
        leftTubeExtruder.setUV(15, 14);
        rightTubeExtruder = new TubeExtruder(sideTubesRadius, sideTubesVertCount);
        rightTubeExtruder.setUV(15, 14);
        centerCrossTubeExtruder = new ResizableTubeExtruder(1f, centerTubeVertCount);
        centerCrossTubeExtruder.setUV(14, 15);
        centerCrossTubeExtruder.closeEnds = true;
        sideCrossTubeExtruder             = new ResizableTubeExtruder(1f, centerTubeVertCount);
        sideCrossTubeExtruder.setUV(15, 14);
        crossBoxExtruder = new BoxExtruder(sideTubesRadius * 2f, sideTubesRadius * 1.8f);
        crossBoxExtruder.setUV(14, 14);
        collisionMeshExtruder                  = new BoxExtruder(base.trackWidth, 0.02665f);
        base.buildVolumeMeshExtruder           = new BoxExtruder(base.trackWidth, 0.8f);
        base.buildVolumeMeshExtruder.closeEnds = true;
        base.setModelExtruders(centerTubeExtruder, leftTubeExtruder, rightTubeExtruder);
    }
        static void Main(string[] args)
        {
            Console.WriteLine("Manually Test converting a DomainObject to a DomainDto");
            Console.Write("Enter FirstName Value: ");
            var firstName = Console.ReadLine();

            Console.Write("Enter LastName Value: ");
            var lastName = Console.ReadLine();

            Console.Write("Enter Age Value: ");
            var age = Console.ReadLine();

            var domain = new DomainObject()
            {
                FirstName = firstName, LastName = lastName, Age = int.Parse(age)
            };
            var extruder = new Extruder <DomainObject, DomainDto>(domain);
            var output   = extruder.Generate();

            Console.WriteLine($"FirstName: {output.FirstName}");
            Console.WriteLine($"LastName: {output.LastName}");
            Console.WriteLine($"Age: {output.Age}");
            Console.WriteLine("Press Any Key to Exit");
            Console.ReadKey();
        }
Example #5
0
    // Use this for initialization
    void Start()
    {
        Mesh mesh = gameObject.GetComponent <MeshFilter> ().mesh;
        int [] triangles = mesh.triangles;

        //get the positive x face of the cube
        List <int> trianglesList = new List <int> ();
        for (int i = 0; i < triangles.Length; i += 3) {
            int vertsGreaterThanZero = 0;
            for (int j = i; j < i + 3; j++)
                if (mesh.vertices [triangles [j]].y > amt) vertsGreaterThanZero++;

            if (vertsGreaterThanZero == 3)
                for (int j = i; j < i + 3; j++) trianglesList.Add (triangles [j]);
        }
        currentFaces = trianglesList.ToArray ();

        //Vector3 [] vals = new Vector3 [] {mov};
        //Vector3 [] vals2 = new Vector3 [] {-1 * mov};
        //Vector3 [] resizeVals = new Vector3 [] {mov, new Vector3 (1.5f, 1.5f, 1.5f)};
        Vector3 [] spikeVals = new Vector3 [] {mov, new Vector3 (.2f, 0, 0),new Vector3(factors,0,0)};
        //Extruder.Extrude (mesh, currentFaces, false, Extruder.ExtrudeWeirdClean, resizeVals);
        Extruder.Extrude (mesh, currentFaces, false, Extruder.ExtrudeSpike, spikeVals);
        //Extruder.Extrude (mesh, currentFaces, true, Extruder.ExtrudeOffset, vals2);
        //TestDrag (mesh, currentFaces);
        //Debug.Log (GetUniquePoints (currentFaces));
        //TestSplitCylinder (mesh, new List <int> (triangles));
    }
    /// <summary>
    /// Create a <see cref="MapsService"/> to load buildings, then add borders around their bases and
    /// around the edges of roads.
    /// </summary>
    private void Start()
    {
        // Verify a Building Base Material has been given.
        if (BuildingAndRoadBorder == null)
        {
            Debug.LogError(ExampleErrors.MissingParameter(this, BuildingAndRoadBorder,
                                                          "Building And Road Border", "to apply around the bases of buildings"));
            return;
        }

        // Verify a Roads Material has been given.
        if (Roads == null)
        {
            Debug.LogError(ExampleErrors.MissingParameter(this, Roads, "Roads", "to apply to roads"));
            return;
        }

        // Get the required Dynamic Maps Service on this GameObject.
        DynamicMapsService dynamicMapsService = GetComponent <DynamicMapsService>();

        // Create a roads style that defines a material for roads and for borders of roads. The specific
        // border material used is chosen to look just a little darker than the material of the ground
        // plane (helping the roads to visually blend into the surrounding ground).
        SegmentStyle roadsStyle = new SegmentStyle.Builder {
            Material       = Roads,
            BorderMaterial = BuildingAndRoadBorder,
            Width          = 7.0f,
            BorderWidth    = 1.0f
        }.Build();

        // Get default style options.
        GameObjectOptions renderingStyles = ExampleDefaults.DefaultGameObjectOptions;

        // Replace default roads style with new, just created roads style.
        renderingStyles.SegmentStyle = roadsStyle;

        // Get required BuildingTexturer component on this GameObject.
        BuildingTexturer buildingTexturer = GetComponent <BuildingTexturer>();

        // Sign up to event called after each new building is loaded, so can assign Materials to this
        // new building, and add an extruded base around the building to fake an Ambient Occlusion
        // contact shadow. Note that:
        // - DynamicMapsService.MapsService is auto-found on first access (so will not be null).
        // - This event must be set now during Awake, so that when Dynamic Maps Service starts loading
        //   the map during Start, this event will be triggered for all Extruded Structures.
        dynamicMapsService.MapsService.Events.ExtrudedStructureEvents.DidCreate.AddListener(args => {
            // Apply nine sliced wall and roof materials to this building.
            //  buildingTexturer.AssignNineSlicedMaterials(args.GameObject);

            // Add a border around base to building using Building Border Builder class, coloring it using
            // the given border Material.
            Extruder.AddBuildingBorder(args.GameObject, args.MapFeature.Shape, BuildingAndRoadBorder);
        });
    }
Example #7
0
    private static int leniencyAdjustmentCount; //can't figure out why things will continue getting bigger, so I'm doing this roundabout fix

    void Start()
    {
        mf = this.gameObject.AddComponent <MeshFilter>();

        mr        = this.gameObject.AddComponent <MeshRenderer>();
        mat       = mr.material;
        mat.color = Color.white;

        spriteExtruder          = gameObject.AddComponent <Extruder>();
        leniencyAdjustmentCount = 0;
    }
        public void ExtrudeTest()
        {
            Action action = () => Extruder.Extrude();

            action.Should().NotThrow();

            var biscuit = Extruder.Extrude();

            biscuit.IsExtruded.Should().BeTrue();
            biscuit.IsStamped.Should().BeFalse();
            biscuit.IsDone.Should().BeFalse();
        }
Example #9
0
        public void motor_off()
        {
            this.dwell(STALL_TIME);
            var last_move_time = this.get_last_move_time();

            this.kin.motor_off(last_move_time);
            foreach (var ext in Extruder.get_printer_extruders(this.printer))
            {
                ext.motor_off(last_move_time);
            }
            this.dwell(STALL_TIME);
            logging.Debug("; Max time of {0}", last_move_time);
        }
    void OnSceneGUI()
    {
        extruder = (Extruder)target;
        Event e = Event.current;

        if (e.type == EventType.MouseDown)
        {
            Undo.RegisterCompleteObjectUndo(extruder, "change extruded shape");
        }


        FormShape();
        extruder.Generate();
    }
Example #11
0
    private void StartExtruder()
    {
        mf = GetComponent <MeshFilter>();
        if (mf != null && mf.sharedMesh == null)
        {
            mf.sharedMesh = new Mesh();
        }

        extruder         = GetComponent <Extruder>();
        extruder.shape2d = new Shape2D
        {
            Vertices = CommonHelperForNow.GetDefaultShapeVertices()
        };
    }
Example #12
0
        void MakeMesh()
        {
            ControlPoint cpA = new ControlPoint(transformA.position, transformA.forward * transformA.localScale.z);
            ControlPoint cpB = new ControlPoint(transformB.position, transformB.forward * transformB.localScale.z);

            Curve          curve  = CubicBezier.Evaluate(cpA, cpB, pointCount);
            ExtruderResult result = Extruder.Extrude(curve, crossSection, LineTextureMode.Tile);

            Mesh mesh = result.GenerateMesh();

            mesh.RecalculateNormals();
            mesh.RecalculateTangents();
            mesh.RecalculateBounds();
            meshFilter.sharedMesh = mesh;
        }
    /// <summary>
    /// Configures the map.
    /// </summary>
    private void Start()
    {
        MapsService mapsService = GetComponent <MapsService>();

        mapsService.InitFloatingOrigin(LoadingCenter);

        Material adminAreaMaterial = BaseMapMaterialUtils.CreateUniformColoredMaterial(AdminAreaColor);

        // Configure the map to only show prefectures and texture them with a solid color.
        mapsService.Events.RegionEvents.WillCreate.AddListener(args => {
            if (args.MapFeature.Metadata.Usage == RegionMetadata.UsageType.AdministrativeArea1)
            {
                RegionStyle.Builder style = args.Style.AsBuilder();
                style.FillMaterial        = adminAreaMaterial;
                args.Style = style.Build();
            }
            else
            {
                args.Cancel = true;
            }
        });

        // When a prefecture GameObject is created, create an extruded outline for it.
        Material borderMaterial = null;

        mapsService.Events.RegionEvents.DidCreate.AddListener(args => {
            if (borderMaterial == null)
            {
                // Set up the border material based on the prefecture material, but change the render queue
                // so that it renders on top.
                borderMaterial       = new Material(args.GameObject.GetComponent <Renderer>().material);
                borderMaterial.color = BorderColor;
                borderMaterial.renderQueue++;
            }
            Extruder.AddAreaExternalOutline(args.GameObject, borderMaterial, args.MapFeature.Shape,
                                            BorderWidth);
        });

        // Don't display water.
        mapsService.Events.AreaWaterEvents.WillCreate.AddListener(args => {
            args.Cancel = true;
        });

        // Load the map around Japan.
        mapsService.MakeMapLoadRegion()
        .AddCircle(mapsService.Coords.FromLatLngToVector3(LoadingCenter), 2000000) // 2,000 km.
        .Load(ExampleDefaults.DefaultGameObjectOptions, 5);                        // Zoom level 5.
    }
        public void HandleMotorPulseTest()
        {
            BiscuitMakerManager.TurnOn(this.Maker);

            Action action = () => Extruder.HandleMotorPulse(
                null,
                new OnMotorPulseEventArgs {
                Maker = this.Maker
            }
                );

            action.Should().NotThrow();

            var biscuit = this.Maker.FirstConveyor.Belt.ElementAt(0);

            biscuit.Should().NotBeNull();
            biscuit.IsExtruded.Should().BeTrue();
            biscuit.IsStamped.Should().BeFalse();
            biscuit.IsDone.Should().BeFalse();
        }
    //grows the branch

    /*public void Grow () {
     *      Vector3 [] parameters = new Vector3 [] {new Vector3 (0, segmentLength [0], 0),
     *              new Vector3 (widthLossFactor, 0, 0)};
     *      float currRadius = radius [0] - widthLossFactor;
     *
     *      for (int i = 0; i < segments [0] - 1; i++) {
     *              //rotate by a random amount
     *              bool a = false;
     *
     *              if ( i == segments[0] - 2)
     *                      a = true;
     *
     *              StartCoroutine(growHelp(parameters, currRadius,i, a));
     *              /*
     *              Vector3 rotVector = RandomNormalCurveVector (maxTurn [0]);
     *              Quaternion rotation = Quaternion.Euler (rotVector);
     *              parameters [0] = rotation * parameters [0];
     *
     *              //rotate upward
     *              Vector3 localY = gameObject.transform.InverseTransformVector (Vector3.up);
     *              float rad = Random.Range (0, upCurve [0]) * Mathf.PI / 180;
     *              parameters [0] = Vector3.RotateTowards (parameters [0], localY, rad, 0);
     *
     *              Extruder.Extrude (mesh, faces, false, Extruder.ExtrudeRotate, parameters, false);
     *
     *              currRadius -= widthLossFactor;
     *
     *              float willBranch = Random.Range (0f, 1f);
     *              if (willBranch < branchChance [0] && i != segments [0] - 2 && segments [0] > 2) {;
     *                      MakeNewBranch (gameObject.transform.TransformPoint (mesh.vertices [center]),
     *                                     parameters [0], .9f * currRadius, i + 1);
     *              }
     */
    /*	}
     *      SharpenPoint (parameters [0]);
     *
     *      mesh.RecalculateNormals ();
     *      mesh.RecalculateBounds ();
     * }*/

    public IEnumerator Grow()
    {
        Vector3 [] parameters = new Vector3 [] { new Vector3(0, segmentLength [0], 0),
                                                 new Vector3(widthLossFactor, 0, 0) };
        float currRadius = radius [0] - widthLossFactor;

        for (int i = 0; i < segments [0] - 1; i++)
        {
            //rotate by a random amount

            Vector3    rotVector = RandomNormalCurveVector(maxTurn [0]);
            Quaternion rotation  = Quaternion.Euler(rotVector);
            parameters [0] = rotation * parameters [0];

            //rotate upward
            Vector3 localY = gameObject.transform.InverseTransformVector(Vector3.up);
            float   rad    = Random.Range(0, upCurve [0]) * Mathf.PI / 180;
            parameters [0] = Vector3.RotateTowards(parameters [0], localY, rad, 0);

            Extruder.Extrude(mesh, faces, false, Extruder.ExtrudeRotate, parameters, false);

            currRadius -= widthLossFactor;

            float willBranch = Random.Range(0f, 1f);
            if (willBranch < branchChance [0] && i != segments [0] - 2 && segments [0] > 2)
            {
                ;
                MakeNewBranch(gameObject.transform.TransformPoint(mesh.vertices [center]),
                              parameters [0], .9f * currRadius, i + 1);
            }

            yield return(new WaitForSeconds(0.1f));
        }
        SharpenPoint(parameters [0]);
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        yield return(null);
    }
Example #16
0
    /// <summary>
    /// Create a <see cref="MapsService"/> to load buildings, then add parapets to them.
    /// </summary>
    private void Start()
    {
        // Get the required Dynamic Maps Service on this GameObject.
        DynamicMapsService dynamicMapsService = GetComponent <DynamicMapsService>();

        // Get required BuildingTexturer component on this GameObject.
        BuildingTexturer buildingTexturer = GetComponent <BuildingTexturer>();

        // Sign up to event called after each new building is loaded, so can assign Materials to this
        // new building, and add an lofted parapet around the top of each building. Note that:
        // - DynamicMapsService.MapsService is auto-found on first access (so will not be null).
        // - This event must be set now during Awake, so that when Dynamic Maps Service starts loading
        //   the map during Start, this event will be triggered for all Extruded Structures.
        dynamicMapsService.MapsService.Events.ExtrudedStructureEvents.DidCreate.AddListener(args => {
            // Apply nine sliced wall and roof materials to this building.
            buildingTexturer.AssignNineSlicedMaterials(args.GameObject);

            // Add a parapet to this building, making sure it shares the building's roof Material. This
            // should have just been added as the building's second SharedMaterial.
            Material roofMaterial = args.GameObject.GetComponent <MeshRenderer>().sharedMaterials[1];
            Extruder.AddRandomBuildingParapet(args.GameObject, args.MapFeature.Shape, roofMaterial);
        });
    }
Example #17
0
        public void Clone()
        {
            MachineModel original = new MachineModel();

            Axis axis = new Axis
            {
                Homed           = true,
                Letter          = 'X',
                MachinePosition = 123,
                Min             = -789,
                MinEndstop      = 1,
                MinProbed       = true,
                Max             = 456,
                MaxEndstop      = 2,
                MaxProbed       = true
            };

            axis.Drives.Add(1);
            axis.Drives.Add(2);
            original.Move.Axes.Add(axis);
            original.Move.BabystepZ    = 0.34F;
            original.Move.Compensation = "Compensation";
            original.Move.CurrentMove.RequestedSpeed = 45;
            original.Move.CurrentMove.TopSpeed       = 30;

            Drive drive = new Drive
            {
                Acceleration = 12,
                Current      = 1200,
                MinSpeed     = 10,
                MaxSpeed     = 400,
                Position     = 56
            };

            drive.Microstepping.Interpolated = false;
            drive.Microstepping.Value        = 256;
            original.Move.Drives.Add(drive);

            Extruder extruder = new Extruder
            {
                Factor = 1.23F
            };

            extruder.Nonlinear.A           = 1;
            extruder.Nonlinear.B           = 2;
            extruder.Nonlinear.Temperature = 56;
            extruder.Nonlinear.UpperLimit  = 78;
            original.Move.Extruders.Add(extruder);

            original.Move.Geometry.Type = GeometryType.Delta;
            original.Move.Idle.Factor   = 0.8F;
            original.Move.Idle.Timeout  = 50;
            original.Move.SpeedFactor   = 1.45F;

            MachineModel clone = (MachineModel)original.Clone();

            Assert.AreEqual(1, clone.Move.Axes.Count);
            Assert.AreEqual(original.Move.Axes[0].Drives, clone.Move.Axes[0].Drives);
            Assert.AreEqual(original.Move.Axes[0].Homed, clone.Move.Axes[0].Homed);
            Assert.AreEqual(original.Move.Axes[0].Letter, clone.Move.Axes[0].Letter);
            Assert.AreEqual(original.Move.Axes[0].MachinePosition, clone.Move.Axes[0].MachinePosition);
            Assert.AreEqual(original.Move.Axes[0].Min, clone.Move.Axes[0].Min);
            Assert.AreEqual(original.Move.Axes[0].MinEndstop, clone.Move.Axes[0].MinEndstop);
            Assert.AreEqual(original.Move.Axes[0].MinProbed, clone.Move.Axes[0].MinProbed);
            Assert.AreEqual(original.Move.Axes[0].Max, clone.Move.Axes[0].Max);
            Assert.AreEqual(original.Move.Axes[0].MaxEndstop, clone.Move.Axes[0].MaxEndstop);
            Assert.AreEqual(original.Move.Axes[0].MaxProbed, clone.Move.Axes[0].MaxProbed);

            Assert.AreEqual(original.Move.BabystepZ, clone.Move.BabystepZ);
            Assert.AreEqual(original.Move.Compensation, clone.Move.Compensation);
            Assert.AreEqual(original.Move.CurrentMove.RequestedSpeed, clone.Move.CurrentMove.RequestedSpeed);
            Assert.AreEqual(original.Move.CurrentMove.TopSpeed, clone.Move.CurrentMove.TopSpeed);

            Assert.AreEqual(1, clone.Move.Drives.Count);
            Assert.AreEqual(original.Move.Drives[0].Acceleration, clone.Move.Drives[0].Acceleration);
            Assert.AreEqual(original.Move.Drives[0].Current, clone.Move.Drives[0].Current);
            Assert.AreEqual(original.Move.Drives[0].MaxSpeed, clone.Move.Drives[0].MaxSpeed);
            Assert.AreEqual(original.Move.Drives[0].Microstepping.Interpolated, clone.Move.Drives[0].Microstepping.Interpolated);
            Assert.AreEqual(original.Move.Drives[0].Microstepping.Value, clone.Move.Drives[0].Microstepping.Value);
            Assert.AreEqual(original.Move.Drives[0].MinSpeed, clone.Move.Drives[0].MinSpeed);
            Assert.AreEqual(original.Move.Drives[0].Position, clone.Move.Drives[0].Position);

            Assert.AreEqual(1, clone.Move.Extruders.Count);
            Assert.AreEqual(original.Move.Extruders[0].Factor, clone.Move.Extruders[0].Factor);
            Assert.AreEqual(original.Move.Extruders[0].Nonlinear.A, clone.Move.Extruders[0].Nonlinear.A);
            Assert.AreEqual(original.Move.Extruders[0].Nonlinear.B, clone.Move.Extruders[0].Nonlinear.B);
            Assert.AreEqual(original.Move.Extruders[0].Nonlinear.Temperature, clone.Move.Extruders[0].Nonlinear.Temperature);
            Assert.AreEqual(original.Move.Extruders[0].Nonlinear.UpperLimit, clone.Move.Extruders[0].Nonlinear.UpperLimit);

            Assert.AreEqual(original.Move.Geometry.Type, clone.Move.Geometry.Type);
            Assert.AreEqual(original.Move.Idle.Factor, clone.Move.Idle.Factor);
            Assert.AreEqual(original.Move.Idle.Timeout, clone.Move.Idle.Timeout);
            Assert.AreEqual(original.Move.SpeedFactor, clone.Move.SpeedFactor);
        }
Example #18
0
 public bool Initialized()
 {
     SplineMono = GetComponent <SplineMono>();
     extruder   = GetComponent <Extruder>();
     return(SplineMono.Initialized() && extruder.Initialized());
 }
Example #19
0
        protected override DX11VertexGeometry GetGeom(DX11RenderContext device, int slice)
        {
            if (d2dFactory == null)
            {
                d2dFactory = new D2DFactory();
                dwFactory  = new DWriteFactory(SharpDX.DirectWrite.FactoryType.Shared);
            }

            TextFormat fmt = new TextFormat(dwFactory, this.FFontInput[slice].Name, FFontSize[slice]);
            TextLayout tl  = new TextLayout(dwFactory, FText[slice], fmt, 0.0f, 32.0f);

            tl.WordWrapping       = WordWrapping.NoWrap;
            tl.TextAlignment      = FHAlignment[slice];
            tl.ParagraphAlignment = FVAlignment[slice];

            OutlineRenderer renderer = new OutlineRenderer(d2dFactory);
            Extruder        ex       = new Extruder(d2dFactory);


            tl.Draw(renderer, 0.0f, 0.0f);

            var outlinedGeometry = renderer.GetGeometry();

            ex.GetVertices(outlinedGeometry, vertexList, this.FExtrude[slice]);
            outlinedGeometry.Dispose();

            Vector3 min = new Vector3(float.MaxValue);
            Vector3 max = new Vector3(float.MinValue);

            for (int i = 0; i < vertexList.Count; i++)
            {
                Pos3Norm3VertexSDX pn = vertexList[i];

                min.X = pn.Position.X < min.X ? pn.Position.X : min.X;
                min.Y = pn.Position.Y < min.Y ? pn.Position.Y : min.Y;
                min.Z = pn.Position.Z < min.Z ? pn.Position.Z : min.Z;

                max.X = pn.Position.X > max.X ? pn.Position.X : max.X;
                max.Y = pn.Position.Y > max.Y ? pn.Position.Y : max.Y;
                max.Z = pn.Position.Z > max.Z ? pn.Position.Z : max.Z;
            }

            SlimDX.DataStream ds = new SlimDX.DataStream(vertexList.Count * Pos3Norm3VertexSDX.VertexSize, true, true);
            ds.Position = 0;

            for (int i = 0; i < vertexList.Count; i++)
            {
                ds.Write(vertexList[i]);
            }

            ds.Position = 0;

            var vbuffer = new SlimDX.Direct3D11.Buffer(device.Device, ds, new SlimDX.Direct3D11.BufferDescription()
            {
                BindFlags      = SlimDX.Direct3D11.BindFlags.VertexBuffer,
                CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None,
                OptionFlags    = SlimDX.Direct3D11.ResourceOptionFlags.None,
                SizeInBytes    = (int)ds.Length,
                Usage          = SlimDX.Direct3D11.ResourceUsage.Default
            });

            ds.Dispose();

            DX11VertexGeometry vg = new DX11VertexGeometry(device);

            vg.InputLayout    = Pos3Norm3VertexSDX.Layout;
            vg.Topology       = SlimDX.Direct3D11.PrimitiveTopology.TriangleList;
            vg.VertexBuffer   = vbuffer;
            vg.VertexSize     = Pos3Norm3VertexSDX.VertexSize;
            vg.VerticesCount  = vertexList.Count;
            vg.HasBoundingBox = true;
            vg.BoundingBox    = new SlimDX.BoundingBox(new SlimDX.Vector3(min.X, min.Y, min.Z), new SlimDX.Vector3(max.X, max.Y, max.Z));

            renderer.Dispose();
            fmt.Dispose();
            tl.Dispose();

            return(vg);
        }
Example #20
0
    //! Called by unity engine for rendering and handling GUI events.
    public void OnGUI()
    {
        // STYLE
        GUI.skin = GetComponent <PlayerGUI>().thisGUIskin;

        // ASPECT RATIO
        float ScreenHeight = Screen.height;
        float ScreenWidth  = Screen.width;

        if (ScreenWidth / ScreenHeight < 1.7f)
        {
            ScreenHeight = (ScreenHeight * 0.75f);
        }
        if (ScreenHeight < 700)
        {
            GUI.skin.label.fontSize = 10;
        }

        if (!playerController.stateManager.Busy() && GetComponent <MainMenu>().finishedLoading == true)
        {
            // MACHINE CONTROL GUI
            if (playerController.inventoryOpen == false && playerController.machineGUIopen == true && playerController.objectInSight != null)
            {
                GameObject obj = playerController.objectInSight;

                if (obj.GetComponent <PowerConduit>() != null)
                {
                    bool         netFlag      = false;
                    PowerConduit powerConduit = obj.GetComponent <PowerConduit>();
                    if (powerConduit.connectionFailed == false)
                    {
                        GUI.DrawTexture(guiCoordinates.FourButtonSpeedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        GUI.Label(guiCoordinates.outputLabelRect, "Range");
                        powerConduit.range = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, powerConduit.range, 6, 120);
                        if (GUI.Button(guiCoordinates.outputControlButton3Rect, "Dual Output: " + powerConduit.dualOutput))
                        {
                            if (powerConduit.dualOutput == true)
                            {
                                powerConduit.dualOutput = false;
                            }
                            else
                            {
                                powerConduit.dualOutput = true;
                            }
                            playerController.PlayButtonSound();
                        }
                        if (GUI.Button(guiCoordinates.outputControlButton4Rect, "Close"))
                        {
                            playerController.machineGUIopen = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    else
                    {
                        GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            powerConduit.connectionAttempts = 0;
                            powerConduit.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        bool rangeDeSync  = powerConduit.range != playerController.networkedConduitRange;
                        bool outputDeSync = powerConduit.dualOutput != playerController.networkedDualPower;
                        if (rangeDeSync || outputDeSync || netFlag)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = powerConduit.gameObject.transform.position;
                            updateNetworkConduitCoroutine          = StartCoroutine(net.SendPowerData(location, powerConduit.range, powerConduit.dualOutput));
                            playerController.networkedConduitRange = powerConduit.range;
                            playerController.networkedDualPower    = powerConduit.dualOutput;
                        }
                    }
                }

                if (obj.GetComponent <RailCartHub>() != null)
                {
                    bool        netFlag = false;
                    RailCartHub hub     = obj.GetComponent <RailCartHub>();
                    if (hub.connectionFailed == false)
                    {
                        if (hubStopWindowOpen == false)
                        {
                            GUI.DrawTexture(guiCoordinates.FiveButtonSpeedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                            GUI.Label(guiCoordinates.railCartHubCircuitLabelRect, "Circuit");
                            int    circuit       = hub.circuit;
                            string circuitString = GUI.TextField(guiCoordinates.railCartHubCircuitRect, circuit.ToString(), 3);
                            try
                            {
                                hub.circuit = int.Parse(circuitString);
                            }
                            catch
                            {
                                // NOOP
                            }
                            GUI.Label(guiCoordinates.outputLabelRect, "Range");
                            hub.range = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, hub.range, 6, 120);
                            if (GUI.Button(guiCoordinates.outputControlButton3Rect, "Stop Settings"))
                            {
                                hubStopWindowOpen = true;
                                playerController.PlayButtonSound();
                            }
                            if (GUI.Button(guiCoordinates.outputControlButton4Rect, "Close"))
                            {
                                playerController.machineGUIopen = false;
                                hubStopWindowOpen = false;
                                playerController.PlayButtonSound();
                            }
                        }
                        else
                        {
                            GUI.DrawTexture(guiCoordinates.FiveButtonSpeedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                            GUI.Label(guiCoordinates.longOutputLabelRect, "Stop Time");
                            if (GUI.Button(guiCoordinates.outputControlButton0Rect, "Stop: " + hub.stop))
                            {
                                if (hub.stop == true)
                                {
                                    hub.stop = false;
                                }
                                else
                                {
                                    hub.stop = true;
                                }
                                playerController.PlayButtonSound();
                            }
                            hub.stopTime = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, hub.stopTime, 0, 600);
                            if (GUI.Button(guiCoordinates.outputControlButton3Rect, "Range Settings"))
                            {
                                hubStopWindowOpen = false;
                                playerController.PlayButtonSound();
                            }
                            if (GUI.Button(guiCoordinates.outputControlButton4Rect, "Close"))
                            {
                                playerController.machineGUIopen = false;
                                hubStopWindowOpen = false;
                                playerController.PlayButtonSound();
                            }
                        }
                    }
                    else
                    {
                        GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            hub.connectionAttempts = 0;
                            hub.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        bool circuitDeSync = hub.circuit != playerController.networkedHubCircuit;
                        bool rangeDeSync   = hub.range != playerController.networkedHubRange;
                        bool stopDeSync    = hub.stop != playerController.networkedHubStop;
                        bool timeDeSync    = (int)hub.stopTime != (int)playerController.networkedHubStopTime;
                        if (circuitDeSync || rangeDeSync || stopDeSync || timeDeSync || netFlag)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = hub.gameObject.transform.position;
                            updateNetworkConduitCoroutine         = StartCoroutine(net.SendHubData(location, hub.circuit, hub.range, hub.stop, hub.stopTime));
                            playerController.networkedHubCircuit  = hub.circuit;
                            playerController.networkedHubRange    = hub.range;
                            playerController.networkedHubStop     = hub.stop;
                            playerController.networkedHubStopTime = hub.stopTime;
                        }
                    }
                }

                if (obj.GetComponent <Retriever>() != null)
                {
                    bool      netFlag   = false;
                    Retriever retriever = obj.GetComponent <Retriever>();
                    if (retriever.connectionFailed == false)
                    {
                        GUI.DrawTexture(guiCoordinates.FourButtonSpeedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        if (retriever.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            retriever.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, retriever.speed, 0, retriever.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                        if (GUI.Button(guiCoordinates.outputControlButton3Rect, "Choose Items"))
                        {
                            if (obj.GetComponent <InventoryManager>().initialized == true)
                            {
                                playerController.inventoryOpen  = true;
                                playerController.storageGUIopen = true;
                                playerController.machineGUIopen = false;
                                playerController.PlayButtonSound();
                            }
                        }
                        if (GUI.Button(guiCoordinates.outputControlButton4Rect, "Close"))
                        {
                            playerController.machineGUIopen = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    else
                    {
                        GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            retriever.connectionAttempts = 0;
                            retriever.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (retriever.speed != playerController.networkedConduitRange || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = retriever.gameObject.transform.position;
                            updateNetworkConduitCoroutine          = StartCoroutine(net.SendConduitData(location, retriever.speed));
                            playerController.networkedConduitRange = retriever.speed;
                        }
                    }
                }

                if (obj.GetComponent <AutoCrafter>() != null)
                {
                    bool        netFlag     = false;
                    AutoCrafter autoCrafter = obj.GetComponent <AutoCrafter>();
                    if (autoCrafter.connectionFailed == false)
                    {
                        GUI.DrawTexture(guiCoordinates.FourButtonSpeedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        if (autoCrafter.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            autoCrafter.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, autoCrafter.speed, 0, autoCrafter.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                        if (GUI.Button(guiCoordinates.outputControlButton3Rect, "Choose Item"))
                        {
                            if (obj.GetComponent <InventoryManager>().initialized == true)
                            {
                                playerController.inventoryOpen  = true;
                                playerController.storageGUIopen = true;
                                playerController.machineGUIopen = false;
                                playerController.PlayButtonSound();
                            }
                        }
                        if (GUI.Button(guiCoordinates.outputControlButton4Rect, "Close"))
                        {
                            playerController.machineGUIopen = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    else
                    {
                        GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            autoCrafter.connectionAttempts = 0;
                            autoCrafter.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (autoCrafter.speed != playerController.networkedConduitRange || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = autoCrafter.gameObject.transform.position;
                            updateNetworkConduitCoroutine          = StartCoroutine(net.SendConduitData(location, autoCrafter.speed));
                            playerController.networkedConduitRange = autoCrafter.speed;
                        }
                    }
                }

                if (obj.GetComponent <UniversalConduit>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    UniversalConduit conduit = obj.GetComponent <UniversalConduit>();
                    if (conduit.connectionFailed == false)
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Range");
                        conduit.range = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, conduit.range, 6, 120);
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            conduit.connectionAttempts = 0;
                            conduit.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (conduit.range != playerController.networkedConduitRange || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = conduit.gameObject.transform.position;
                            updateNetworkConduitCoroutine          = StartCoroutine(net.SendConduitData(location, conduit.range));
                            playerController.networkedConduitRange = conduit.range;
                        }
                    }
                }

                if (obj.GetComponent <DarkMatterConduit>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    DarkMatterConduit conduit = obj.GetComponent <DarkMatterConduit>();
                    if (conduit.connectionFailed == false)
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Range");
                        conduit.range = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, conduit.range, 6, 120);
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            conduit.connectionAttempts = 0;
                            conduit.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (conduit.range != playerController.networkedConduitRange || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = conduit.gameObject.transform.position;
                            updateNetworkConduitCoroutine          = StartCoroutine(net.SendConduitData(location, conduit.range));
                            playerController.networkedConduitRange = conduit.range;
                        }
                    }
                }

                if (obj.GetComponent <HeatExchanger>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    HeatExchanger hx = obj.GetComponent <HeatExchanger>();
                    if (hx.inputObject != null)
                    {
                        if (hx.inputObject.GetComponent <UniversalConduit>() != null)
                        {
                            if (hx.connectionFailed == false)
                            {
                                GUI.Label(guiCoordinates.outputLabelRect, "Output");
                                hx.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, hx.speed, 0, playerController.hxAmount);
                            }
                            else
                            {
                                GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                                if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                                {
                                    netFlag = true;
                                    hx.connectionAttempts = 0;
                                    hx.connectionFailed   = false;
                                    playerController.PlayButtonSound();
                                }
                            }
                            if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                            {
                                if (hx.speed != playerController.networkedMachineSpeed || netFlag == true)
                                {
                                    NetworkSend net      = playerController.networkController.networkSend;
                                    Vector3     location = hx.gameObject.transform.position;
                                    updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, hx.speed));
                                    playerController.networkedMachineSpeed = hx.speed;
                                }
                            }
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Input");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "No Input");
                    }
                }

                if (obj.GetComponent <PowerSource>() != null)
                {
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    PowerSource powerSource = obj.GetComponent <PowerSource>();
                    if (powerSource.connectionFailed == true)
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            powerSource.connectionAttempts = 0;
                            powerSource.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Online");
                    }
                }

                if (obj.GetComponent <Auger>() != null)
                {
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    Auger auger = obj.GetComponent <Auger>();
                    if (auger.power > 0)
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Output");
                        auger.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, auger.speed, 0, auger.power);
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (auger.speed != playerController.networkedMachineSpeed)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = auger.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, auger.speed));
                            playerController.networkedMachineSpeed = auger.speed;
                        }
                    }
                }

                if (obj.GetComponent <UniversalExtractor>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    UniversalExtractor extractor = obj.GetComponent <UniversalExtractor>();
                    if (extractor.connectionFailed == false)
                    {
                        if (extractor.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            extractor.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, extractor.speed, 0, extractor.power);
                        }
                        else
                        {
                            GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            extractor.connectionAttempts = 0;
                            extractor.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (extractor.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = extractor.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, extractor.speed));
                            playerController.networkedMachineSpeed = extractor.speed;
                        }
                    }
                }
                if (obj.GetComponent <DarkMatterCollector>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    DarkMatterCollector collector = obj.GetComponent <DarkMatterCollector>();
                    if (collector.connectionFailed == false)
                    {
                        if (collector.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            collector.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, collector.speed, 0, collector.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            collector.connectionAttempts = 0;
                            collector.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (collector.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = collector.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, collector.speed));
                            playerController.networkedMachineSpeed = collector.speed;
                        }
                    }
                }

                if (obj.GetComponent <Smelter>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    Smelter smelter = obj.GetComponent <Smelter>();
                    if (smelter.connectionFailed == false)
                    {
                        if (smelter.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            smelter.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, smelter.speed, 0, smelter.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            smelter.connectionAttempts = 0;
                            smelter.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (smelter.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = smelter.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, smelter.speed));
                            playerController.networkedMachineSpeed = smelter.speed;
                        }
                    }
                }

                if (obj.GetComponent <AlloySmelter>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    AlloySmelter alloySmelter = obj.GetComponent <AlloySmelter>();
                    if (alloySmelter.connectionFailed == false)
                    {
                        if (alloySmelter.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            alloySmelter.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, alloySmelter.speed, 0, alloySmelter.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            alloySmelter.connectionAttempts = 0;
                            alloySmelter.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (alloySmelter.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = alloySmelter.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, alloySmelter.speed));
                            playerController.networkedMachineSpeed = alloySmelter.speed;
                        }
                    }
                }

                if (obj.GetComponent <Press>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    Press press = obj.GetComponent <Press>();
                    if (press.connectionFailed == false)
                    {
                        if (press.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            press.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, press.speed, 0, press.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            press.connectionAttempts = 0;
                            press.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (press.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = press.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, press.speed));
                            playerController.networkedMachineSpeed = press.speed;
                        }
                    }
                }

                if (obj.GetComponent <Extruder>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    Extruder extruder = obj.GetComponent <Extruder>();
                    if (extruder.connectionFailed == false)
                    {
                        if (extruder.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            extruder.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, extruder.speed, 0, extruder.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            extruder.connectionAttempts = 0;
                            extruder.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (extruder.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = extruder.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, extruder.speed));
                            playerController.networkedMachineSpeed = extruder.speed;
                        }
                    }
                }

                if (obj.GetComponent <ModMachine>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    ModMachine modMachine = obj.GetComponent <ModMachine>();
                    if (modMachine.connectionFailed == false)
                    {
                        if (modMachine.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            modMachine.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, modMachine.speed, 0, modMachine.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            modMachine.connectionAttempts = 0;
                            modMachine.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (modMachine.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = modMachine.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, modMachine.speed));
                            playerController.networkedMachineSpeed = modMachine.speed;
                        }
                    }
                }

                if (obj.GetComponent <Turret>() != null)
                {
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    Turret turret = obj.GetComponent <Turret>();
                    if (turret.power > 0)
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Output");
                        if (turret.power < 30)
                        {
                            turret.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, turret.speed, 0, turret.power);
                        }
                        else
                        {
                            turret.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, turret.speed, 0, 30);
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (turret.speed != playerController.networkedMachineSpeed)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = turret.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, turret.speed));
                            playerController.networkedMachineSpeed = turret.speed;
                        }
                    }
                }

                if (obj.GetComponent <MissileTurret>() != null)
                {
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    MissileTurret turret = obj.GetComponent <MissileTurret>();
                    if (turret.power > 0)
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Output");
                        if (turret.power < 30)
                        {
                            turret.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, turret.speed, 0, turret.power);
                        }
                        else
                        {
                            turret.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, turret.speed, 0, 30);
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (turret.speed != playerController.networkedMachineSpeed)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = turret.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, turret.speed));
                            playerController.networkedMachineSpeed = turret.speed;
                        }
                    }
                }

                if (obj.GetComponent <GearCutter>() != null)
                {
                    bool netFlag = false;
                    GUI.DrawTexture(guiCoordinates.speedControlBGRect, textureDictionary.dictionary["Interface Background"]);
                    GearCutter gearCutter = obj.GetComponent <GearCutter>();
                    if (gearCutter.connectionFailed == false)
                    {
                        if (gearCutter.power > 0)
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "Output");
                            gearCutter.speed = (int)GUI.HorizontalSlider(guiCoordinates.outputControlButton2Rect, gearCutter.speed, 0, gearCutter.power);
                        }
                        else
                        {
                            GUI.Label(guiCoordinates.outputLabelRect, "No Power");
                        }
                    }
                    else
                    {
                        GUI.Label(guiCoordinates.outputLabelRect, "Offline");
                        if (GUI.Button(guiCoordinates.outputControlButton2Rect, "Reboot"))
                        {
                            netFlag = true;
                            gearCutter.connectionAttempts = 0;
                            gearCutter.connectionFailed   = false;
                            playerController.PlayButtonSound();
                        }
                    }
                    if (PlayerPrefsX.GetPersistentBool("multiplayer") == true)
                    {
                        if (gearCutter.speed != playerController.networkedMachineSpeed || netFlag == true)
                        {
                            NetworkSend net      = playerController.networkController.networkSend;
                            Vector3     location = gearCutter.gameObject.transform.position;
                            updateNetworkMachineCoroutine          = StartCoroutine(net.SendMachineData(location, gearCutter.speed));
                            playerController.networkedMachineSpeed = gearCutter.speed;
                        }
                    }
                }
            }
            else
            {
                hubStopWindowOpen = false;
                gameObject.GetComponent <MSCameraController>().enabled = true;
            }
        }
    }
        /// <summary>
        /// Process an advanced status reponse (type 2)
        /// </summary>
        /// <param name="json">JSON response in UTF-8 format</param>
        /// <returns>Asynchronous task</returns>
        private static async Task ProcessAdvancedResponse(ReadOnlyMemory <byte> json)
        {
            AdvancedStatusResponse response = (AdvancedStatusResponse)JsonSerializer.Deserialize(json.Span, typeof(AdvancedStatusResponse), JsonHelper.DefaultJsonOptions);

            List <Tool> addedTools = new List <Tool>();

            using (await Provider.AccessReadWriteAsync())
            {
                // - Electronics -
                Provider.Get.Electronics.McuTemp.Current = response.mcutemp.cur;
                Provider.Get.Electronics.McuTemp.Min     = response.mcutemp.min;
                Provider.Get.Electronics.McuTemp.Max     = response.mcutemp.max;
                Provider.Get.Electronics.VIn.Current     = response.vin.cur;
                Provider.Get.Electronics.VIn.Min         = response.vin.min;
                Provider.Get.Electronics.VIn.Max         = response.vin.max;

                // - Fans -
                for (int fan = 0; fan < [email protected]; fan++)
                {
                    Fan fanObj;
                    if (fan >= Provider.Get.Fans.Count)
                    {
                        fanObj = new Fan();
                        Provider.Get.Fans.Add(fanObj);
                    }
                    else
                    {
                        fanObj = Provider.Get.Fans[fan];
                    }

                    fanObj.Name  = [email protected][fan];
                    fanObj.Rpm   = (response.sensors.fanRPM.Count > fan && response.sensors.fanRPM[fan] > 0) ? (int?)response.sensors.fanRPM[fan] : null;
                    fanObj.Value = [email protected][fan] / 100F;
                    fanObj.Thermostatic.Control = (response.controllableFans & (1 << fan)) == 0;
                }
                for (int fan = Provider.Get.Fans.Count; fan > [email protected]; fan--)
                {
                    Provider.Get.Fans.RemoveAt(fan - 1);
                }

                // - Move -
                Provider.Get.Move.Compensation = response.compensation;
                Provider.Get.Move.CurrentMove.RequestedSpeed = response.speeds.requested;
                Provider.Get.Move.CurrentMove.TopSpeed       = response.speeds.top;
                Provider.Get.Move.SpeedFactor      = [email protected] / 100;
                Provider.Get.Move.BabystepZ        = [email protected];
                Provider.Get.Move.CurrentWorkplace = response.coords.wpl;

                // Update drives and endstops
                for (int drive = 0; drive < Provider.Get.Move.Drives.Count; drive++)
                {
                    Drive driveObj = Provider.Get.Move.Drives[drive];

                    if (drive < response.axes)
                    {
                        driveObj.Position = response.coords.xyz[drive];
                    }
                    else if (drive < response.axes + response.coords.extr.Count)
                    {
                        driveObj.Position = response.coords.extr[drive - response.axes];
                    }
                    else
                    {
                        driveObj.Position = null;
                    }

                    Endstop endstopObj;
                    if (drive >= Provider.Get.Sensors.Endstops.Count)
                    {
                        endstopObj = new Endstop();
                        Provider.Get.Sensors.Endstops.Add(endstopObj);
                    }
                    else
                    {
                        endstopObj = Provider.Get.Sensors.Endstops[drive];
                    }
                    endstopObj.Triggered = (response.endstops & (1 << drive)) != 0;
                }

                // Update axes
                int axis;
                for (axis = 0; axis < response.totalAxes; axis++)
                {
                    Axis axisObj;
                    if (axis >= Provider.Get.Move.Axes.Count)
                    {
                        axisObj = new Axis();
                        Provider.Get.Move.Axes.Add(axisObj);

                        axisObj.Drives.Add(axis);
                    }
                    else
                    {
                        axisObj = Provider.Get.Move.Axes[axis];

                        if (axisObj.Drives[0] != axis)
                        {
                            axisObj.Drives[0] = axis;
                        }
                    }

                    axisObj.Letter = response.axisNames[axis];
                    if (axis < response.coords.xyz.Count)
                    {
                        axisObj.Homed           = response.coords.axesHomed[axis] != 0;
                        axisObj.MachinePosition = response.coords.machine[axis];
                        axisObj.Visible         = true;
                    }
                    else
                    {
                        axisObj.Homed           = true;
                        axisObj.MachinePosition = null;
                        axisObj.Visible         = false;
                    }
                    axisObj.MinEndstop = axis;
                    axisObj.MaxEndstop = axis;
                }
                for (axis = Provider.Get.Move.Axes.Count; axis > response.totalAxes; axis--)
                {
                    Provider.Get.Move.Axes.RemoveAt(axis - 1);
                }

                // Update extruder drives
                int extruder;
                for (extruder = 0; extruder < response.coords.extr.Count; extruder++)
                {
                    Extruder extruderObj;
                    if (extruder >= Provider.Get.Move.Extruders.Count)
                    {
                        extruderObj = new Extruder();
                        Provider.Get.Move.Extruders.Add(extruderObj);
                    }
                    else
                    {
                        extruderObj = Provider.Get.Move.Extruders[extruder];
                    }

                    extruderObj.Factor = [email protected][extruder] / 100F;
                    if (extruderObj.Drives.Count == 1)
                    {
                        int drive = response.coords.xyz.Count + extruder;
                        if (extruderObj.Drives[0] != drive)
                        {
                            extruderObj.Drives[0] = drive;
                        }
                    }
                    else
                    {
                        extruderObj.Drives.Add(response.coords.xyz.Count + extruder);
                    }
                }
                for (extruder = Provider.Get.Move.Extruders.Count; extruder > response.coords.extr.Count; extruder--)
                {
                    Provider.Get.Move.Extruders.RemoveAt(extruder - 1);
                }

                // - Heat -
                Provider.Get.Heat.ColdExtrudeTemperature = response.coldExtrudeTemp;
                Provider.Get.Heat.ColdRetractTemperature = response.coldRetractTemp;

                // Update heaters
                int heater;
                for (heater = 0; heater < response.temps.current.Count; heater++)
                {
                    Heater heaterObj;
                    if (heater >= Provider.Get.Heat.Heaters.Count)
                    {
                        heaterObj = new Heater();
                        Provider.Get.Heat.Heaters.Add(heaterObj);
                    }
                    else
                    {
                        heaterObj = Provider.Get.Heat.Heaters[heater];
                    }

                    heaterObj.Current = response.temps.current[heater];
                    heaterObj.Max     = response.tempLimit;
                    heaterObj.Name    = response.temps.names[heater];
                    heaterObj.Sensor  = heater;
                    heaterObj.State   = (HeaterState)response.temps.state[heater];
                }
                for (heater = Provider.Get.Heat.Heaters.Count; heater > response.temps.current.Count; heater--)
                {
                    Provider.Get.Heat.Heaters.RemoveAt(heater - 1);
                }

                // Update beds
                if (response.temps.bed != null)
                {
                    BedOrChamber bedObj;
                    if (Provider.Get.Heat.Beds.Count == 0)
                    {
                        bedObj = new BedOrChamber();
                        Provider.Get.Heat.Beds.Add(bedObj);
                    }
                    else
                    {
                        bedObj = Provider.Get.Heat.Beds[0];
                    }

                    if (bedObj.Heaters.Count == 0)
                    {
                        bedObj.Active.Add(response.temps.bed.active);
                        bedObj.Standby.Add(response.temps.bed.standby);
                        bedObj.Heaters.Add(response.temps.bed.heater);
                    }
                    else
                    {
                        if (bedObj.Active[0] != response.temps.bed.active)
                        {
                            bedObj.Active[0] = response.temps.bed.active;
                        }
                        if (bedObj.Standby[0] != response.temps.bed.standby)
                        {
                            bedObj.Standby[0] = response.temps.bed.standby;
                        }
                        if (bedObj.Heaters[0] != response.temps.bed.heater)
                        {
                            bedObj.Heaters[0] = response.temps.bed.heater;
                        }
                    }
                }
                else if (Provider.Get.Heat.Beds.Count > 0)
                {
                    Provider.Get.Heat.Beds.Clear();
                }

                // Update chambers
                if (response.temps.chamber != null)
                {
                    BedOrChamber chamberObj;
                    if (Provider.Get.Heat.Chambers.Count == 0)
                    {
                        chamberObj = new BedOrChamber();
                        Provider.Get.Heat.Chambers.Add(chamberObj);
                    }
                    else
                    {
                        chamberObj = Provider.Get.Heat.Chambers[0];
                    }

                    if (chamberObj.Heaters.Count == 0)
                    {
                        chamberObj.Active.Add(response.temps.chamber.active);
                        chamberObj.Standby.Add(response.temps.chamber.standby);
                        chamberObj.Heaters.Add(response.temps.chamber.heater);
                    }
                    else
                    {
                        if (chamberObj.Active[0] != response.temps.chamber.active)
                        {
                            chamberObj.Active[0] = response.temps.chamber.active;
                        }
                        if (chamberObj.Standby[0] != response.temps.chamber.standby)
                        {
                            chamberObj.Standby[0] = response.temps.chamber.standby;
                        }
                        if (chamberObj.Heaters[0] != response.temps.chamber.heater)
                        {
                            chamberObj.Heaters[0] = response.temps.chamber.heater;
                        }
                    }
                }
                else if (Provider.Get.Heat.Chambers.Count > 0)
                {
                    Provider.Get.Heat.Chambers.Clear();
                }

                // Update extra heaters
                int extra;
                for (extra = 0; extra < response.temps.extra.Count; extra++)
                {
                    ExtraHeater extraObj;
                    if (extra >= Provider.Get.Heat.Extra.Count)
                    {
                        extraObj = new ExtraHeater();
                        Provider.Get.Heat.Extra.Add(extraObj);
                    }
                    else
                    {
                        extraObj = Provider.Get.Heat.Extra[extra];
                    }

                    extraObj.Current = response.temps.extra[extra].temp;
                    extraObj.Name    = response.temps.extra[extra].name;
                }
                for (extra = Provider.Get.Heat.Extra.Count; extra > response.temps.extra.Count; extra--)
                {
                    Provider.Get.Heat.Extra.RemoveAt(extra - 1);
                }

                // - Sensors -
                if (response.probe.type != 0)
                {
                    Probe probeObj;
                    if (Provider.Get.Sensors.Probes.Count == 0)
                    {
                        probeObj = new Probe();
                        Provider.Get.Sensors.Probes.Add(probeObj);
                    }
                    else
                    {
                        probeObj = Provider.Get.Sensors.Probes[0];
                    }

                    probeObj.Type          = (ProbeType)response.probe.type;
                    probeObj.Value         = response.sensors.probeValue;
                    probeObj.Threshold     = response.probe.threshold;
                    probeObj.TriggerHeight = response.probe.height;
                    if (response.sensors.probeSecondary != null)
                    {
                        ListHelpers.SetList(probeObj.SecondaryValues, response.sensors.probeSecondary);
                    }
                    else if (probeObj.SecondaryValues.Count > 0)
                    {
                        probeObj.SecondaryValues.Clear();
                    }
                }
                else if (Provider.Get.Sensors.Probes.Count != 0)
                {
                    Provider.Get.Sensors.Probes.Clear();
                }

                // - Output -
                int            beepDuration = 0, beepFrequency = 0;
                MessageBoxMode?messageBoxMode = null;
                string         displayMessage = string.Empty;
                if (response.output != null)
                {
                    if (response.output.beepFrequency != 0 && response.output.beepDuration != 0)
                    {
                        beepDuration  = response.output.beepDuration;
                        beepFrequency = response.output.beepFrequency;
                    }
                    displayMessage = response.output.message;
                    if (response.output.msgBox != null)
                    {
                        messageBoxMode = (MessageBoxMode)response.output.msgBox.mode;
                        Provider.Get.MessageBox.Title   = response.output.msgBox.title;
                        Provider.Get.MessageBox.Message = response.output.msgBox.msg;
                        for (int i = 0; i < 9; i++)
                        {
                            if ((response.output.msgBox.controls & (1 << i)) != 0)
                            {
                                if (!Provider.Get.MessageBox.AxisControls.Contains(i))
                                {
                                    Provider.Get.MessageBox.AxisControls.Add(i);
                                }
                            }
                            else if (Provider.Get.MessageBox.AxisControls.Contains(i))
                            {
                                Provider.Get.MessageBox.AxisControls.Remove(i);
                            }
                        }
                        Provider.Get.MessageBox.Seq = response.output.msgBox.seq;
                    }
                }
                Provider.Get.State.Beep.Duration  = beepDuration;
                Provider.Get.State.Beep.Frequency = beepFrequency;
                Provider.Get.State.DisplayMessage = displayMessage;
                Provider.Get.MessageBox.Mode      = messageBoxMode;

                // - State -
                MachineStatus oldStatus = Provider.Get.State.Status, newStatus = GetStatus(response.status);
                if ((newStatus == MachineStatus.Idle || newStatus == MachineStatus.Off) &&
                    (oldStatus == MachineStatus.Paused || oldStatus == MachineStatus.Pausing || oldStatus == MachineStatus.Processing ||
                     oldStatus == MachineStatus.Resuming || oldStatus == MachineStatus.Simulating))
                {
                    // No longer processing a file...
                    Provider.Get.Job.File.Assign(new DuetAPI.ParsedFileInfo());
                    Provider.Get.Job.FilePosition = null;
                    Provider.Get.Job.TimesLeft.Assign(new DuetAPI.Machine.TimesLeft());
                }
                Provider.Get.State.AtxPower    = ([email protected] == -1) ? null : (bool?)([email protected] != 0);
                Provider.Get.State.CurrentTool = response.currentTool;
                Provider.Get.State.Status      = newStatus;
                Provider.Get.State.Mode        = (MachineMode)Enum.Parse(typeof(MachineMode), response.mode, true);
                Provider.Get.Network.Name      = response.name;

                // - Tools -
                int tool;
                for (tool = 0; tool < response.tools.Count; tool++)
                {
                    Tool toolObj;
                    if (tool >= Provider.Get.Tools.Count)
                    {
                        toolObj = new Tool();
                        Provider.Get.Tools.Add(toolObj);
                        addedTools.Add(toolObj);
                    }
                    else
                    {
                        toolObj = Provider.Get.Tools[tool];
                    }

                    // FIXME: The filament drive is not part of the status response / OM yet
                    toolObj.FilamentExtruder = (response.tools[tool].drives.Count > 0) ? response.tools[tool].drives[0] : -1;
                    toolObj.Filament         = string.IsNullOrEmpty(response.tools[tool].filament) ? null : response.tools[tool].filament;
                    toolObj.Name             = string.IsNullOrEmpty(response.tools[tool].name) ? null : response.tools[tool].name;
                    toolObj.Number           = response.tools[tool].number;
                    ListHelpers.SetList(toolObj.Heaters, response.tools[tool].heaters);
                    ListHelpers.SetList(toolObj.Extruders, response.tools[tool].drives);
                    ListHelpers.SetList(toolObj.Active, response.temps.tools.active[tool]);
                    ListHelpers.SetList(toolObj.Standby, response.temps.tools.standby[tool]);

                    List <int> fanIndices = new List <int>();
                    for (int i = 0; i < [email protected]; i++)
                    {
                        if ((response.tools[tool].fans & (1 << i)) != 0)
                        {
                            fanIndices.Add(i);
                        }
                    }
                    ListHelpers.SetList(toolObj.Fans, fanIndices);
                    ListHelpers.SetList(toolObj.Offsets, response.tools[tool].offsets);
                }
                for (tool = Provider.Get.Tools.Count; tool > response.tools.Count; tool--)
                {
                    Utility.FilamentManager.ToolRemoved(Provider.Get.Tools[tool - 1]);
                    Provider.Get.Tools.RemoveAt(tool - 1);
                }
            }

            // Notify FilamentManager about added tools. Deal with them here to avoid deadlocks
            foreach (Tool toolObj in addedTools)
            {
                await Utility.FilamentManager.ToolAdded(toolObj);
            }
        }
Example #22
0
    void AddSegments()
    {
        float rad          = radius;
        float currHeight   = 0;
        float actualHeight = 0;

        //go through each segment, only extruding when radius changes (because extrusion is slow)
        for (int i = 0; i < segments; i++)
        {
            //decide whether to bevel it
            float newRad = rad;
            if (rad == radius)
            {
                if (Random.Range(0f, 1f) <= expandChance)
                {
                    newRad = Random.Range(maxRad [0], maxRad [1]);
                }
            }
            else
            {
                if (Random.Range(0f, 1f) <= expandChance)
                {
                    newRad = radius;
                }
            }
            bool       isWindow    = (Random.Range(0f, 1f) <= windowChance);
            List <int> windowVerts = null;

            //extrude it when it needs to be beveled
            if (newRad != rad)
            {
                if (i == 0)
                {
                    Debug.Log(i);
                }
                //catch up to the point where it bevels
                Vector3 [] diff  = new Vector3 [] { (actualHeight - currHeight) * Vector3.up };
                float      randH = Random.Range(1f, 2f);
                if (actualHeight != currHeight)
                {
                    Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeOffset, diff, false);
                }
                actualHeight += randH * segmentHeight;
                currHeight    = actualHeight;

                //bevel
                diff = new Vector3 [] { segmentHeight *randH *Vector3.up,
                                        new Vector3(newRad / rad, 0, newRad / rad) };
                windowVerts = Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeResize, diff, false);
            }
            else
            {
                actualHeight += segmentHeight;
            }

            //extrude it when it needs a window (so there is new geometry) or use beveled vertices
            if (isWindow)
            {
                if (newRad == rad)
                {
                    Vector3 [] diff = new Vector3 [] { (actualHeight - currHeight) * Vector3.up };
                    if (actualHeight != currHeight)
                    {
                        Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeOffset, diff, false);
                    }
                    actualHeight += windowHeight;
                    currHeight    = actualHeight;

                    float inset = (rad - windowInset) / rad;
                    diff = new Vector3 [] { Vector3.zero, new Vector3(inset, 0, inset) };
                    Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeResize, diff, false);

                    diff        = new Vector3 [] { windowHeight *Vector3.up };
                    windowVerts = Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeOffset, diff, false);

                    diff = new Vector3 [] { Vector3.zero, new Vector3(1 / inset, 0, 1 / inset) };
                    Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeResize, diff, false);
                }

                //change UV coordinates so mesh can be recolored
                Vector2 [] uv = mesh.uv;
                foreach (int j in windowVerts)
                {
                    uv [j] = new Vector2(1, 1);
                }
                mesh.uv = uv;
            }

            rad = newRad;
        }

        if (actualHeight != currHeight)
        {
            Vector3 [] diff = new Vector3 [] { (actualHeight - currHeight) * Vector3.up };
            Extruder.Extrude(mesh, faces, true, Extruder.ExtrudeOffset, diff, false);
        }
    }
        private void recalculate(MeshGenerator meshGenerator, TrackSegment4 segment)
        {
            foreach (Transform child in segment.gameObject.transform)
            {
                if (child.name != "BetweenTracksMouseCollider" && !child.name.Contains("StationPlatformTrackTile") && child.name != "MouseSelectionCollider")
                {
                    var mesh_filter = child.gameObject.GetComponent <MeshFilter> ();
                    if (mesh_filter != null)
                    {
                        UnityEngine.Object.Destroy(mesh_filter.mesh);
                        UnityEngine.Object.Destroy(mesh_filter.sharedMesh);
                    }
                    UnityEngine.Object.Destroy(child.gameObject);
                }
            }


            if (segment.getLength() <= 0f)
            {
                Debug.LogWarning("Can't extrude this segment! Has a length of 0.");
            }
            meshGenerator.prepare(segment, segment.gameObject);
            float num  = 0f;
            float num2 = 0f;

            meshGenerator.sampleAt(segment, 0f);
            int     num3 = 0;
            int     num4 = 0;
            Vector3 b    = segment.getStartpoint();

            do
            {
                float num5 = 1f - num2;
                if (Vector3.Angle(segment.getDirection(), segment.getPoint(num2 + num5) - segment.getPoint(num2)) > 5f)
                {
                    num5 /= 2f;
                }
                int     num6  = 0;
                Vector3 point = segment.getPoint(num2 + num5);
                float   num7  = Vector3.Angle(segment.getTangentPoint(num2), segment.getTangentPoint(num2 + num5));
                num7 = Mathf.Max(num7, Vector3.Angle(segment.getNormal(num2), segment.getNormal(num2 + num5)));
                while (num5 > 0.01f && (num7 > 10f || (num7 > 2f && (point - b).magnitude > 0.225f)))
                {
                    num4++;
                    num5 /= 2f;
                    point = segment.getPoint(num2 + num5);
                    num7  = Vector3.Angle(segment.getTangentPoint(num2), segment.getTangentPoint(num2 + num5));
                    num7  = Mathf.Max(num7, Vector3.Angle(segment.getNormal(num2), segment.getNormal(num2 + num5)));
                    num6++;
                    if (num6 > 50)
                    {
                        break;
                    }
                }
                num  += (point - b).magnitude;
                num2 += num5;
                b     = point;
                if (num2 > 1f)
                {
                    break;
                }
                meshGenerator.sampleAt(segment, num2);
                num3++;
            }while (num2 < 1f && num3 < 300);
            if (!Mathf.Approximately(num2, 1f))
            {
                meshGenerator.sampleAt(segment, 1f);
            }

            meshGenerator.afterExtrusion(segment, segment.gameObject);
            MeshFilter component = segment.gameObject.GetComponent <MeshFilter>();
            Mesh       mesh      = meshGenerator.getMesh(segment.gameObject);

            UnityEngine.Object.Destroy(component.sharedMesh);
            UnityEngine.Object.Destroy(component.mesh);

            component.sharedMesh = mesh;
            meshGenerator.afterMeshGeneration(segment, segment.gameObject);

            Extruder buildVolumeMeshExtruder = meshGenerator.getBuildVolumeMeshExtruder();

            buildVolumeMeshExtruder.transform(segment.gameObject.transform.worldToLocalMatrix);
            BoundingMesh boundingMesh = segment.gameObject.GetComponent <BoundingMesh>();

            boundingMesh.layers = BoundingVolume.Layers.Buildvolume;
            boundingMesh.setMesh(buildVolumeMeshExtruder.vertices.ToArray(), buildVolumeMeshExtruder.indizes.ToArray());

            GameObject track_mouse_collider = segment.transform.Find("BetweenTracksMouseCollider").gameObject;             // new GameObject("BetweenTracksMouseCollider");

            track_mouse_collider.transform.parent        = segment.gameObject.transform;
            track_mouse_collider.transform.localPosition = Vector3.zero;
            track_mouse_collider.transform.localRotation = Quaternion.identity;
            track_mouse_collider.layer = LayerMasks.ID_MOUSECOLLIDERS;
            MeshCollider meshCollider  = track_mouse_collider.GetComponent <MeshCollider>();
            Mesh         collisionMesh = meshGenerator.getCollisionMesh(segment.gameObject);

            UnityEngine.Object.Destroy(meshCollider.sharedMesh);
            meshCollider.sharedMesh = collisionMesh;

            MouseCollider mouseCollider = segment.gameObject.GetComponent <MouseCollider>();

            mouseCollider.colliderObject = track_mouse_collider;
        }
Example #24
0
        /// <summary>
        /// Process status updates in the background
        /// </summary>
        /// <returns></returns>
        public static async Task ProcessUpdates()
        {
            while (await _statusUpdates.OutputAvailableAsync(Program.CancelSource.Token))
            {
                Tuple <byte, byte[]> statusUpdate = await _statusUpdates.TakeAsync(Program.CancelSource.Token);

                try
                {
                    if (statusUpdate.Item1 == 2)
                    {
                        AdvancedStatusResponse response = (AdvancedStatusResponse)JsonSerializer.Deserialize(statusUpdate.Item2, typeof(AdvancedStatusResponse), JsonHelper.DefaultJsonOptions);

                        List <Tool> addedTools = new List <Tool>();
                        using (await Provider.AccessReadWriteAsync())
                        {
                            // - Electronics -
                            Provider.Get.Electronics.McuTemp.Current = response.mcutemp.cur;
                            Provider.Get.Electronics.McuTemp.Min     = response.mcutemp.min;
                            Provider.Get.Electronics.McuTemp.Max     = response.mcutemp.max;
                            Provider.Get.Electronics.VIn.Current     = response.vin.cur;
                            Provider.Get.Electronics.VIn.Min         = response.vin.min;
                            Provider.Get.Electronics.VIn.Max         = response.vin.max;

                            // - Fans -
                            for (int fan = 0; fan < [email protected]; fan++)
                            {
                                Fan fanObj;
                                if (fan >= Provider.Get.Fans.Count)
                                {
                                    fanObj = new Fan();
                                    Provider.Get.Fans.Add(fanObj);
                                }
                                else
                                {
                                    fanObj = Provider.Get.Fans[fan];
                                }

                                fanObj.Name  = [email protected][fan];
                                fanObj.Rpm   = (response.sensors.fanRPM.Count > fan && response.sensors.fanRPM[fan] > 0) ? (int?)response.sensors.fanRPM[fan] : null;
                                fanObj.Value = [email protected][fan] / 100F;
                                fanObj.Thermostatic.Control = (response.controllableFans & (1 << fan)) == 0;
                            }
                            for (int fan = Provider.Get.Fans.Count; fan > [email protected]; fan--)
                            {
                                Provider.Get.Fans.RemoveAt(fan - 1);
                            }

                            // - Move -
                            Provider.Get.Move.Compensation = response.compensation;
                            Provider.Get.Move.CurrentMove.RequestedSpeed = response.speeds.requested;
                            Provider.Get.Move.CurrentMove.TopSpeed       = response.speeds.top;
                            Provider.Get.Move.SpeedFactor      = [email protected] / 100;
                            Provider.Get.Move.BabystepZ        = [email protected];
                            Provider.Get.Move.CurrentWorkplace = response.coords.wpl;

                            // Update drives and endstops
                            for (int drive = 0; drive < Provider.Get.Move.Drives.Count; drive++)
                            {
                                Drive driveObj = Provider.Get.Move.Drives[drive];

                                if (drive < response.axes)
                                {
                                    driveObj.Position = response.coords.xyz[drive];
                                }
                                else if (drive < response.axes + response.coords.extr.Count)
                                {
                                    driveObj.Position = response.coords.extr[drive - response.axes];
                                }
                                else
                                {
                                    driveObj.Position = null;
                                }

                                Endstop endstopObj;
                                if (drive >= Provider.Get.Sensors.Endstops.Count)
                                {
                                    endstopObj = new Endstop();
                                    Provider.Get.Sensors.Endstops.Add(endstopObj);
                                }
                                else
                                {
                                    endstopObj = Provider.Get.Sensors.Endstops[drive];
                                }
                                endstopObj.Triggered = (response.endstops & (1 << drive)) != 0;
                            }

                            // Update axes
                            int axis;
                            for (axis = 0; axis < response.totalAxes; axis++)
                            {
                                Axis axisObj;
                                if (axis >= Provider.Get.Move.Axes.Count)
                                {
                                    axisObj = new Axis();
                                    Provider.Get.Move.Axes.Add(axisObj);
                                }
                                else
                                {
                                    axisObj = Provider.Get.Move.Axes[axis];
                                }

                                axisObj.Letter = response.axisNames[axis];
                                if (axis < response.coords.xyz.Count)
                                {
                                    axisObj.Homed           = response.coords.axesHomed[axis] != 0;
                                    axisObj.MachinePosition = response.coords.machine[axis];
                                    axisObj.Visible         = true;
                                }
                                else
                                {
                                    axisObj.Homed           = true;
                                    axisObj.MachinePosition = null;
                                    axisObj.Visible         = false;
                                }
                                axisObj.MinEndstop = axis;
                                axisObj.MaxEndstop = axis;
                            }
                            for (axis = Provider.Get.Move.Axes.Count; axis > response.totalAxes; axis--)
                            {
                                Provider.Get.Move.Axes.RemoveAt(axis - 1);
                            }

                            // Update extruder drives
                            int extruder;
                            for (extruder = 0; extruder < response.coords.extr.Count; extruder++)
                            {
                                Extruder extruderObj;
                                if (extruder >= Provider.Get.Move.Extruders.Count)
                                {
                                    extruderObj = new Extruder();
                                    Provider.Get.Move.Extruders.Add(extruderObj);
                                }
                                else
                                {
                                    extruderObj = Provider.Get.Move.Extruders[extruder];
                                }

                                extruderObj.Factor = [email protected][extruder] / 100F;
                                if (extruderObj.Drives.Count == 1)
                                {
                                    int drive = response.coords.xyz.Count + extruder;
                                    if (extruderObj.Drives[0] != drive)
                                    {
                                        extruderObj.Drives[0] = drive;
                                    }
                                }
                                else
                                {
                                    extruderObj.Drives.Add(response.coords.xyz.Count + extruder);
                                }
                            }
                            for (extruder = Provider.Get.Move.Extruders.Count; extruder > response.coords.extr.Count; extruder--)
                            {
                                Provider.Get.Move.Extruders.RemoveAt(extruder - 1);
                            }

                            // - Heat -
                            Provider.Get.Heat.ColdExtrudeTemperature = response.coldExtrudeTemp;
                            Provider.Get.Heat.ColdRetractTemperature = response.coldRetractTemp;

                            // Update heaters
                            int heater;
                            for (heater = 0; heater < response.temps.current.Count; heater++)
                            {
                                Heater heaterObj;
                                if (heater >= Provider.Get.Heat.Heaters.Count)
                                {
                                    heaterObj = new Heater();
                                    Provider.Get.Heat.Heaters.Add(heaterObj);
                                }
                                else
                                {
                                    heaterObj = Provider.Get.Heat.Heaters[heater];
                                }

                                heaterObj.Current = response.temps.current[heater];
                                heaterObj.Max     = response.tempLimit;
                                heaterObj.Name    = response.temps.names[heater];
                                heaterObj.Sensor  = heater;
                                heaterObj.State   = (HeaterState)response.temps.state[heater];
                            }
                            for (heater = Provider.Get.Heat.Heaters.Count; heater > response.temps.current.Count; heater--)
                            {
                                Provider.Get.Heat.Heaters.RemoveAt(heater - 1);
                            }

                            // Update beds
                            if (response.temps.bed != null)
                            {
                                BedOrChamber bedObj;
                                if (Provider.Get.Heat.Beds.Count == 0)
                                {
                                    bedObj = new BedOrChamber();
                                    Provider.Get.Heat.Beds.Add(bedObj);
                                }
                                else
                                {
                                    bedObj = Provider.Get.Heat.Beds[0];
                                }

                                if (bedObj.Heaters.Count == 0)
                                {
                                    bedObj.Active.Add(response.temps.bed.active);
                                    bedObj.Standby.Add(response.temps.bed.standby);
                                    bedObj.Heaters.Add(response.temps.bed.heater);
                                }
                                else
                                {
                                    if (bedObj.Active[0] != response.temps.bed.active)
                                    {
                                        bedObj.Active[0] = response.temps.bed.active;
                                    }
                                    if (bedObj.Standby[0] != response.temps.bed.standby)
                                    {
                                        bedObj.Standby[0] = response.temps.bed.standby;
                                    }
                                    if (bedObj.Heaters[0] != response.temps.bed.heater)
                                    {
                                        bedObj.Heaters[0] = response.temps.bed.heater;
                                    }
                                }
                            }
                            else if (Provider.Get.Heat.Beds.Count > 0)
                            {
                                Provider.Get.Heat.Beds.Clear();
                            }

                            // Update chambers
                            if (response.temps.chamber != null)
                            {
                                BedOrChamber chamberObj;
                                if (Provider.Get.Heat.Chambers.Count == 0)
                                {
                                    chamberObj = new BedOrChamber();
                                    Provider.Get.Heat.Chambers.Add(chamberObj);
                                }
                                else
                                {
                                    chamberObj = Provider.Get.Heat.Chambers[0];
                                }

                                if (chamberObj.Heaters.Count == 0)
                                {
                                    chamberObj.Active.Add(response.temps.chamber.active);
                                    chamberObj.Standby.Add(response.temps.chamber.standby);
                                    chamberObj.Heaters.Add(response.temps.chamber.heater);
                                }
                                else
                                {
                                    if (chamberObj.Active[0] != response.temps.chamber.active)
                                    {
                                        chamberObj.Active[0] = response.temps.chamber.active;
                                    }
                                    if (chamberObj.Standby[0] != response.temps.chamber.standby)
                                    {
                                        chamberObj.Standby[0] = response.temps.chamber.standby;
                                    }
                                    if (chamberObj.Heaters[0] != response.temps.chamber.heater)
                                    {
                                        chamberObj.Heaters[0] = response.temps.chamber.heater;
                                    }
                                }
                            }
                            else if (Provider.Get.Heat.Chambers.Count > 0)
                            {
                                Provider.Get.Heat.Chambers.Clear();
                            }

                            // Update extra heaters
                            int extra;
                            for (extra = 0; extra < response.temps.extra.Count; extra++)
                            {
                                ExtraHeater extraObj;
                                if (extra >= Provider.Get.Heat.Extra.Count)
                                {
                                    extraObj = new ExtraHeater();
                                    Provider.Get.Heat.Extra.Add(extraObj);
                                }
                                else
                                {
                                    extraObj = Provider.Get.Heat.Extra[extra];
                                }

                                extraObj.Current = response.temps.extra[extra].temp;
                                extraObj.Name    = response.temps.extra[extra].name;
                            }
                            for (extra = Provider.Get.Heat.Extra.Count; extra > response.temps.extra.Count; extra--)
                            {
                                Provider.Get.Heat.Extra.RemoveAt(extra - 1);
                            }

                            // - Sensors -
                            if (response.probe.type != 0)
                            {
                                Probe probeObj;
                                if (Provider.Get.Sensors.Probes.Count == 0)
                                {
                                    probeObj = new Probe();
                                    Provider.Get.Sensors.Probes.Add(probeObj);
                                }
                                else
                                {
                                    probeObj = Provider.Get.Sensors.Probes[0];
                                }

                                probeObj.Type          = (ProbeType)response.probe.type;
                                probeObj.Value         = response.sensors.probeValue;
                                probeObj.Threshold     = response.probe.threshold;
                                probeObj.TriggerHeight = response.probe.height;
                                if (response.sensors.probeSecondary != null)
                                {
                                    ListHelpers.SetList(probeObj.SecondaryValues, response.sensors.probeSecondary);
                                }
                            }
                            else if (Provider.Get.Sensors.Probes.Count != 0)
                            {
                                Provider.Get.Sensors.Probes.Clear();
                            }

                            // - Output -
                            int            beepDuration = 0, beepFrequency = 0;
                            MessageBoxMode?messageBoxMode = null;
                            string         displayMessage = string.Empty;
                            if (response.output != null)
                            {
                                if (response.output.beepFrequency != 0 && response.output.beepDuration != 0)
                                {
                                    beepDuration  = response.output.beepFrequency;
                                    beepFrequency = response.output.beepDuration;
                                }
                                displayMessage = response.output.message;
                                if (response.output.msgBox != null)
                                {
                                    messageBoxMode = (MessageBoxMode)response.output.msgBox.mode;
                                    Provider.Get.MessageBox.Title   = response.output.msgBox.title;
                                    Provider.Get.MessageBox.Message = response.output.msgBox.msg;
                                    for (int i = 0; i < 9; i++)
                                    {
                                        if ((response.output.msgBox.controls & (1 << i)) != 0)
                                        {
                                            if (!Provider.Get.MessageBox.AxisControls.Contains(i))
                                            {
                                                Provider.Get.MessageBox.AxisControls.Add(i);
                                            }
                                        }
                                        else if (Provider.Get.MessageBox.AxisControls.Contains(i))
                                        {
                                            Provider.Get.MessageBox.AxisControls.Remove(i);
                                        }
                                    }
                                    Provider.Get.MessageBox.Seq = response.output.msgBox.seq;
                                }
                            }
                            Provider.Get.State.Beep.Duration  = beepDuration;
                            Provider.Get.State.Beep.Frequency = beepFrequency;
                            Provider.Get.State.DisplayMessage = displayMessage;
                            Provider.Get.MessageBox.Mode      = messageBoxMode;

                            // - State -
                            Provider.Get.State.AtxPower    = ([email protected] == -1) ? null : (bool?)([email protected] != 0);
                            Provider.Get.State.CurrentTool = response.currentTool;
                            Provider.Get.State.Status      = GetStatus(response.status);
                            Provider.Get.State.Mode        = (MachineMode)Enum.Parse(typeof(MachineMode), response.mode, true);
                            Provider.Get.Network.Name      = response.name;

                            // - Tools -
                            int tool;
                            for (tool = 0; tool < response.tools.Count; tool++)
                            {
                                Tool toolObj;
                                if (tool >= Provider.Get.Tools.Count)
                                {
                                    toolObj = new Tool();
                                    Provider.Get.Tools.Add(toolObj);
                                    addedTools.Add(toolObj);
                                }
                                else
                                {
                                    toolObj = Provider.Get.Tools[tool];
                                }

                                // FIXME: The filament drive is not part of the status response / OM yet
                                toolObj.FilamentExtruder = (response.tools[tool].drives.Count > 0) ? response.tools[tool].drives[0] : -1;
                                toolObj.Filament         = string.IsNullOrEmpty(response.tools[tool].filament) ? null : response.tools[tool].filament;
                                toolObj.Name             = string.IsNullOrEmpty(response.tools[tool].name) ? null : response.tools[tool].name;
                                toolObj.Number           = response.tools[tool].number;
                                ListHelpers.SetList(toolObj.Heaters, response.tools[tool].heaters);
                                ListHelpers.SetList(toolObj.Extruders, response.tools[tool].drives);
                                ListHelpers.SetList(toolObj.Active, response.temps.tools.active[tool]);
                                ListHelpers.SetList(toolObj.Standby, response.temps.tools.standby[tool]);

                                List <int> fanIndices = new List <int>();
                                for (int i = 0; i < [email protected]; i++)
                                {
                                    if ((response.tools[tool].fans & (1 << i)) != 0)
                                    {
                                        fanIndices.Add(i);
                                    }
                                }
                                ListHelpers.SetList(toolObj.Fans, fanIndices);
                                ListHelpers.SetList(toolObj.Offsets, response.tools[tool].offsets);
                            }
                            for (tool = Provider.Get.Tools.Count; tool > response.tools.Count; tool--)
                            {
                                Utility.FilamentManager.ToolRemoved(Provider.Get.Tools[tool - 1]);
                                Provider.Get.Tools.RemoveAt(tool - 1);
                            }
                        }

                        // Notify FilamentManager about added tools. Deal with them here to avoid deadlocks
                        foreach (Tool toolObj in addedTools)
                        {
                            await Utility.FilamentManager.ToolAdded(toolObj);
                        }
                    }
                    else if (statusUpdate.Item1 == 3)
                    {
                        // Deserialize print status response
                        PrintStatusResponse printResponse = (PrintStatusResponse)JsonSerializer.Deserialize(statusUpdate.Item2, typeof(PrintStatusResponse), JsonHelper.DefaultJsonOptions);

                        using (await Provider.AccessReadWriteAsync())
                        {
                            if (printResponse.currentLayer > Provider.Get.Job.Layers.Count + 1)
                            {
                                // Layer complete
                                Layer lastLayer = (Provider.Get.Job.Layers.Count > 0)
                                    ? Provider.Get.Job.Layers[Provider.Get.Job.Layers.Count - 1]
                                        : new Layer()
                                {
                                    Filament = new List <float>(printResponse.extrRaw.Count)
                                };

                                float   lastHeight = 0F, lastDuration = 0F, lastProgress = 0F;
                                float[] lastFilamentUsage = new float[printResponse.extrRaw.Count];
                                foreach (Layer l in Provider.Get.Job.Layers)
                                {
                                    lastHeight   += l.Height;
                                    lastDuration += l.Duration;
                                    lastProgress += l.FractionPrinted;
                                    for (int i = 0; i < Math.Min(lastFilamentUsage.Length, l.Filament.Count); i++)
                                    {
                                        lastFilamentUsage[i] += l.Filament[i];
                                    }
                                }

                                float[] filamentUsage = new float[printResponse.extrRaw.Count];
                                for (int i = 0; i < filamentUsage.Length; i++)
                                {
                                    filamentUsage[i] = printResponse.extrRaw[i] - lastFilamentUsage[i];
                                }

                                float printDuration = printResponse.printDuration - printResponse.warmUpDuration;
                                Layer layer         = new Layer
                                {
                                    Duration        = printDuration - lastDuration,
                                    Filament        = new List <float>(filamentUsage),
                                    FractionPrinted = (printResponse.fractionPrinted / 100F) - lastProgress,
                                    Height          = (printResponse.currentLayer > 2) ? _currentHeight - lastHeight : printResponse.firstLayerHeight
                                };
                                Provider.Get.Job.Layers.Add(layer);

                                // FIXME: In case Z isn't mapped to the 3rd axis...
                                _currentHeight = printResponse.coords.xyz[2];
                            }
                            else if (printResponse.currentLayer < Provider.Get.Job.Layers.Count && GetStatus(printResponse.status) == MachineStatus.Processing)
                            {
                                // Starting a new print job
                                Provider.Get.Job.Layers.Clear();
                                _currentHeight = 0F;
                            }

                            Provider.Get.Job.Layer        = printResponse.currentLayer;
                            Provider.Get.Job.LayerTime    = (printResponse.currentLayer == 1) ? printResponse.firstLayerDuration : printResponse.currentLayerTime;
                            Provider.Get.Job.FilePosition = printResponse.filePosition;
                            ListHelpers.SetList(Provider.Get.Job.ExtrudedRaw, printResponse.extrRaw);
                            Provider.Get.Job.Duration           = printResponse.printDuration;
                            Provider.Get.Job.WarmUpDuration     = printResponse.warmUpDuration;
                            Provider.Get.Job.TimesLeft.File     = (printResponse.timesLeft.file > 0F) ? (float?)printResponse.timesLeft.file : null;
                            Provider.Get.Job.TimesLeft.Filament = (printResponse.timesLeft.filament > 0F) ? (float?)printResponse.timesLeft.filament : null;
                            Provider.Get.Job.TimesLeft.Layer    = (printResponse.timesLeft.layer > 0F) ? (float?)printResponse.timesLeft.layer : null;
                        }

                        // Notify waiting threads about the model update
                        _updateEvent.Set();
                        _updateEvent.Reset();
                    }
                    else if (statusUpdate.Item1 == 5)
                    {
                        // Deserialize config response
                        ConfigResponse configResponse = (ConfigResponse)JsonSerializer.Deserialize(statusUpdate.Item2, typeof(ConfigResponse), JsonHelper.DefaultJsonOptions);

                        if (configResponse.axisMins == null)
                        {
                            Console.WriteLine("[warn] Config response unsupported. Update your firmware!");
                            return;
                        }

                        using (await Provider.AccessReadWriteAsync())
                        {
                            // - Axes -
                            for (int axis = 0; axis < Math.Min(Provider.Get.Move.Axes.Count, configResponse.axisMins.Count); axis++)
                            {
                                Provider.Get.Move.Axes[axis].Min = configResponse.axisMins[axis];
                                Provider.Get.Move.Axes[axis].Max = configResponse.axisMaxes[axis];
                            }

                            // - Drives -
                            int drive;
                            for (drive = 0; drive < configResponse.accelerations.Count; drive++)
                            {
                                Drive driveObj;
                                if (drive >= Provider.Get.Move.Drives.Count)
                                {
                                    driveObj = new Drive();
                                    Provider.Get.Move.Drives.Add(driveObj);
                                }
                                else
                                {
                                    driveObj = Provider.Get.Move.Drives[drive];
                                }

                                driveObj.Acceleration = configResponse.accelerations[drive];
                                driveObj.Current      = configResponse.currents[drive];
                                driveObj.MinSpeed     = configResponse.minFeedrates[drive];
                                driveObj.MaxSpeed     = configResponse.maxFeedrates[drive];
                            }
                            for (drive = Provider.Get.Move.Drives.Count; drive > configResponse.accelerations.Count; drive--)
                            {
                                Provider.Get.Move.Drives.RemoveAt(drive - 1);
                                Provider.Get.Sensors.Endstops.RemoveAt(drive - 1);
                            }

                            // - Electronics -
                            Provider.Get.Electronics.Name      = configResponse.firmwareElectronics;
                            Provider.Get.Electronics.ShortName = configResponse.boardName;
                            switch (Provider.Get.Electronics.ShortName)
                            {
                            case "MBP05":
                                Provider.Get.Electronics.Revision = "0.5";
                                break;

                            case "MB6HC":
                                Provider.Get.Electronics.Revision = "0.6";
                                break;
                            }
                            Provider.Get.Electronics.Firmware.Name    = configResponse.firmwareName;
                            Provider.Get.Electronics.Firmware.Version = configResponse.firmwareVersion;
                            Provider.Get.Electronics.Firmware.Date    = configResponse.firmwareDate;

                            // - Move -
                            Provider.Get.Move.Idle.Factor  = configResponse.idleCurrentFactor / 100F;
                            Provider.Get.Move.Idle.Timeout = configResponse.idleTimeout;
                        }

                        // Check if the firmware is supposed to be updated only. When this finishes, DCS is terminated.
                        if (configResponse.boardName != null && Program.UpdateOnly && !_updatingFirmware)
                        {
                            _updatingFirmware = true;

                            Code updateCode = new Code
                            {
                                Type        = DuetAPI.Commands.CodeType.MCode,
                                MajorNumber = 997,
                                Flags       = DuetAPI.Commands.CodeFlags.IsPrioritized
                            };
                            _ = updateCode.Execute();
                        }
                    }
                }
                catch (JsonException e)
                {
                    Console.WriteLine($"[err] Failed to merge JSON: {e}");
                }
            }
        }
 private void OnEnable()
 {
     extruder = (Extruder)target;
 }
Example #26
0
    /// <summary>
    /// Connect to <see cref="FloatingOriginUpdater.OnFloatingOriginUpdate"/>, so that whenever the
    /// world's Floating Origin is moved, all controlled world space textured
    /// <see cref="WorldspaceMaterials"/> are realigned to the world's new Floating Origin.
    /// </summary>
    private void Start()
    {
        // Verify all required parameters are defined, skipping further setup if not.
        if (!VerifyParameters())
        {
            enabled = false;
            return;
        }

        // Get the required Floating Origin component on this GameObject.
        FloatingOriginUpdater floatingOriginUpdater = GetComponent <FloatingOriginUpdater>();

        // Make sure that whenever the Floating Origin is updated, Materials are updated in sync.
        floatingOriginUpdater.OnFloatingOriginUpdate.AddListener(UpdateWorldspaceMaterialOffsets);

        // Store all Materials that are to be updated. This function only stores Materials that have an
        // _Offset Vector, which will be used to offset the Material's world space coordinates to align
        // to the world's moved Floating Origin.
        TryAddMaterial(Buildings);
        TryAddMaterial(Roads);
        TryAddMaterial(Ground);
        TryAddMaterial(Water);

        // Because the Floating Origin has not yet been moved, there is no need to apply an _Offset to
        // these Materials yet. Instead we make sure these Material's _Offsets start at (0, 0, 0).
        UpdateWorldspaceMaterialOffsets(Vector3.zero);

        // Create styles to assign world space textured Materials to geometry as it is created.
        ExtrudedStructureStyle extrudedStructureStyle = new ExtrudedStructureStyle.Builder {
            WallMaterial = Buildings,
            RoofMaterial = Buildings
        }.Build();
        ModeledStructureStyle modeledStructureStyle = new ModeledStructureStyle.Builder {
            Material = Buildings
        }.Build();
        SegmentStyle roadsStyle = new SegmentStyle.Builder {
            Material       = Roads,
            BorderMaterial = Borders,
            Width          = 7.0f,
            BorderWidth    = BorderWidth
        }.Build();
        RegionStyle groundStyle = new RegionStyle.Builder {
            FillMaterial = Ground
        }.Build();
        AreaWaterStyle areaWaterStyle = new AreaWaterStyle.Builder {
            FillMaterial = Water
        }.Build();
        LineWaterStyle lineWaterStyle = new LineWaterStyle.Builder {
            Material = Water,
            Width    = 7.0f
        }.Build();

        GameObjectOptions renderingStyles = ExampleDefaults.DefaultGameObjectOptions;

        renderingStyles.ExtrudedStructureStyle = extrudedStructureStyle;
        renderingStyles.ModeledStructureStyle  = modeledStructureStyle;
        renderingStyles.SegmentStyle           = roadsStyle;
        renderingStyles.RegionStyle            = groundStyle;
        renderingStyles.AreaWaterStyle         = areaWaterStyle;
        renderingStyles.LineWaterStyle         = lineWaterStyle;

        DynamicMapsService dynamicMapsService = floatingOriginUpdater.DynamicMapsService;

        dynamicMapsService.RenderingStyles = renderingStyles;

        // Make sure that if any new Materials are cloned by the Maps Service (which can occur to
        // resolve z-fighting issues), that these new cloned materials are added to the list of managed
        // Materials.
        MapsService mapsService = dynamicMapsService.MapsService;

        mapsService.Events.RegionEvents.DidCreate.AddListener(
            args => TryAddMaterialFrom(args.GameObject));
        mapsService.Events.AreaWaterEvents.DidCreate.AddListener(
            args => TryAddMaterialFrom(args.GameObject));
        mapsService.Events.LineWaterEvents.DidCreate.AddListener(
            args => TryAddMaterialFrom(args.GameObject));
        mapsService.Events.SegmentEvents.DidCreate.AddListener(
            args => TryAddMaterialFrom(args.GameObject));
        mapsService.Events.ModeledStructureEvents.DidCreate.AddListener(
            args => TryAddMaterialFrom(args.GameObject));

        // For extruded buildings, also create borders around the edges of these buildings, to match
        // borders around roads.
        mapsService.Events.ExtrudedStructureEvents.DidCreate.AddListener(args => {
            Debug.Log(args.MapFeature.MapFeatureMetadata.PlaceId);
            TryAddMaterialFrom(args.GameObject);
            Extruder.AddBuildingBorder(args.GameObject, args.MapFeature.Shape, Borders, BorderWidth);
        });
    }
Example #27
0
 public void AddExtruder(Extruder p_extruder)
 {
     m_extruders.Add(p_extruder);
 }
        private static async Task DoMerge(byte module, string json)
        {
            if (module == 2)
            {
                // Deserialize extended response (temporary)
                var response = new
                {
                    status = 'I',
                    coords = new
                    {
                        axesHomed = new byte[0],
                        xyz       = new float[0],
                        machine   = new float[0],
                        extr      = new float[0]
                    },
                    speeds = new
                    {
                        requested = 0.0F,
                        top       = 0.0F
                    },
                    currentTool = -1,
                    output      = new
                    {
                        beepDuration  = 0,
                        beepFrequency = 0,
                        message       = "",
                        msgBox        = new
                        {
                            msg      = "",
                            title    = "",
                            seq      = 0,
                            timeout  = 0,
                            controls = 0
                        }
                    },
                    Params = new
                    {
                        atxPower    = 0,
                        fanPercent  = new float[0],
                        fanNames    = new string[0],
                        speedFactor = 0.0F,
                        extrFactors = new float[0],
                        babystep    = 0.0F
                    },
                    sensors = new
                    {
                        probeValue     = 0,
                        probeSecondary = new int[0],
                        fanRPM         = new int[0]
                    },
                    temps = new
                    {
                        bed = new
                        {
                            active  = 0.0F,
                            standby = 0.0F,
                            state   = 0,
                            heater  = 0
                        },
                        chamber = new
                        {
                            active  = 0.0F,
                            standby = 0.0F,
                            state   = 0,
                            heater  = 0
                        },
                        current = new float[0],
                        state   = new byte[0],
                        names   = new string[0],
                        tools   = new
                        {
                            active  = new[] { new float[0] },
                            standby = new[] { new float[0] }
                        },
                        extra = new[]
                        {
                            new
                            {
                                name = "",
                                temp = 0.0F
                            }
                        }
                    },
                    coldExtrudeTemp  = 160.0F,
                    coldRetractTemp  = 90.0F,
                    compensation     = "",
                    controllableFans = 0,
                    tempLimit        = 0.0F,
                    tools            = new[]
                    {
                        new
                        {
                            number    = 0,
                            name      = "",
                            heaters   = new int[0],
                            extruders = new int[0],
                            fan       = 0,
                            filament  = "",
                            offsets   = new float[0]
                        }
                    },
                    mcutemp = new
                    {
                        min = 0.0F,
                        cur = 0.0F,
                        max = 0.0F
                    },
                    vin = new
                    {
                        min = 0.0F,
                        cur = 0.0F,
                        max = 0.0F
                    },
                    firmwareName = "",
                    mode         = "FFF"
                };
                response = JsonConvert.DeserializeAnonymousType(json, response);

                using (await Provider.AccessReadWriteAsync())
                {
                    // - Electronics -
                    Provider.Get.Electronics.Firmware.Name   = response.firmwareName;
                    Provider.Get.Electronics.McuTemp.Current = response.mcutemp.cur;
                    Provider.Get.Electronics.McuTemp.Min     = response.mcutemp.min;
                    Provider.Get.Electronics.McuTemp.Max     = response.mcutemp.max;
                    Provider.Get.Electronics.VIn.Current     = response.vin.cur;
                    Provider.Get.Electronics.VIn.Min         = response.vin.min;
                    Provider.Get.Electronics.VIn.Max         = response.vin.max;

                    // - Fans -
                    for (int fan = 0; fan < response.Params.fanPercent.Length; fan++)
                    {
                        Fan fanObj;
                        if (fan >= Provider.Get.Fans.Count)
                        {
                            fanObj = new Fan();
                            Provider.Get.Fans.Add(fanObj);
                        }
                        else
                        {
                            fanObj = Provider.Get.Fans[fan];
                        }

                        fanObj.Name  = response.Params.fanNames[fan];
                        fanObj.Rpm   = (response.sensors.fanRPM.Length > fan && response.sensors.fanRPM[fan] > 0) ? (int?)response.sensors.fanRPM[fan] : null;
                        fanObj.Value = response.Params.fanPercent[fan] / 100;
                    }
                    for (int fan = Provider.Get.Fans.Count; fan > response.Params.fanPercent.Length; fan--)
                    {
                        Provider.Get.Fans.RemoveAt(fan - 1);
                    }

                    // - Move -
                    Provider.Get.Move.Compensation = response.compensation;
                    Provider.Get.Move.CurrentMove.RequestedSpeed = response.speeds.requested;
                    Provider.Get.Move.CurrentMove.TopSpeed       = response.speeds.top;
                    Provider.Get.Move.SpeedFactor = response.Params.speedFactor / 100;
                    Provider.Get.Move.BabystepZ   = response.Params.babystep;

                    // Update drives
                    int numDrives = response.coords.xyz.Length + response.coords.extr.Length;
                    for (int drive = 0; drive < numDrives; drive++)
                    {
                        Drive driveObj;
                        if (drive >= Provider.Get.Move.Drives.Count)
                        {
                            driveObj = new Drive();
                            Provider.Get.Move.Drives.Add(driveObj);
                        }
                        else
                        {
                            driveObj = Provider.Get.Move.Drives[drive];
                        }

                        driveObj.Position = (drive < response.coords.xyz.Length) ? response.coords.xyz[drive] : response.coords.extr[drive - response.coords.xyz.Length];
                    }
                    for (int drive = Provider.Get.Move.Drives.Count; drive > numDrives; drive--)
                    {
                        Provider.Get.Move.Drives.RemoveAt(drive - 1);
                    }

                    // Update axes
                    for (int axis = 0; axis < response.coords.xyz.Length; axis++)
                    {
                        Axis axisObj;
                        if (axis >= Provider.Get.Move.Axes.Count)
                        {
                            axisObj = new Axis();
                            Provider.Get.Move.Axes.Add(axisObj);
                        }
                        else
                        {
                            axisObj = Provider.Get.Move.Axes[axis];
                        }

                        axisObj.Letter          = GetAxisLetter(axis);
                        axisObj.Homed           = response.coords.axesHomed[axis] != 0;
                        axisObj.MachinePosition = response.coords.machine[axis];
                    }
                    for (int axis = Provider.Get.Move.Axes.Count; axis > response.coords.xyz.Length; axis--)
                    {
                        Provider.Get.Move.Axes.RemoveAt(axis - 1);
                    }

                    // Update extruder drives
                    Extruder extruderObj;
                    for (int extruder = 0; extruder < response.coords.extr.Length; extruder++)
                    {
                        if (extruder >= Provider.Get.Move.Extruders.Count)
                        {
                            extruderObj = new Extruder();
                            Provider.Get.Move.Extruders.Add(extruderObj);
                        }
                        else
                        {
                            extruderObj = Provider.Get.Move.Extruders[extruder];
                        }

                        extruderObj.Factor = response.Params.extrFactors[extruder] / 100;
                        if (extruderObj.Drives.Count == 1)
                        {
                            extruderObj.Drives[0] = response.coords.xyz.Length + extruder;
                        }
                        else
                        {
                            extruderObj.Drives.Add(response.coords.xyz.Length + extruder);
                        }
                    }
                    for (int extruder = Provider.Get.Move.Extruders.Count; extruder > response.coords.extr.Length; extruder--)
                    {
                        Provider.Get.Move.Extruders.RemoveAt(extruder - 1);
                    }

                    // - Heat -
                    Provider.Get.Heat.ColdExtrudeTemperature = response.coldExtrudeTemp;
                    Provider.Get.Heat.ColdRetractTemperature = response.coldRetractTemp;

                    // Update heaters
                    for (int heater = 0; heater < response.temps.current.Length; heater++)
                    {
                        Heater heaterObj;
                        if (heater >= Provider.Get.Heat.Heaters.Count)
                        {
                            heaterObj = new Heater();
                            Provider.Get.Heat.Heaters.Add(heaterObj);
                        }
                        else
                        {
                            heaterObj = Provider.Get.Heat.Heaters[heater];
                        }

                        heaterObj.Current = response.temps.current[heater];
                        heaterObj.Max     = response.tempLimit;
                        heaterObj.Name    = response.temps.names[heater];
                        heaterObj.Sensor  = heater;
                        heaterObj.State   = (HeaterState)response.temps.state[heater];
                    }
                    for (int heater = Provider.Get.Heat.Heaters.Count; heater > response.temps.current.Length; heater--)
                    {
                        Provider.Get.Heat.Heaters.RemoveAt(heater - 1);
                    }

                    // Update beds
                    if (response.temps.bed != null)
                    {
                        BedOrChamber bedObj;
                        if (Provider.Get.Heat.Beds.Count == 0)
                        {
                            bedObj = new BedOrChamber();
                            Provider.Get.Heat.Beds.Add(bedObj);
                        }
                        else
                        {
                            bedObj = Provider.Get.Heat.Beds[0];
                        }

                        if (bedObj.Heaters.Count == 0)
                        {
                            bedObj.Active.Add(response.temps.bed.active);
                            bedObj.Standby.Add(response.temps.bed.standby);
                            bedObj.Heaters.Add(response.temps.bed.heater);
                        }
                        else
                        {
                            bedObj.Active[0]  = response.temps.bed.active;
                            bedObj.Standby[0] = response.temps.bed.standby;
                            bedObj.Heaters[0] = response.temps.bed.heater;
                        }
                    }
                    else if (Provider.Get.Heat.Beds.Count > 0)
                    {
                        Provider.Get.Heat.Beds.Clear();
                    }

                    // Update chambers
                    if (response.temps.chamber != null)
                    {
                        BedOrChamber chamberObj;
                        if (Provider.Get.Heat.Chambers.Count == 0)
                        {
                            chamberObj = new BedOrChamber();
                            Provider.Get.Heat.Chambers.Add(chamberObj);
                        }
                        else
                        {
                            chamberObj = Provider.Get.Heat.Chambers[0];
                        }

                        if (chamberObj.Heaters.Count == 0)
                        {
                            chamberObj.Active.Add(response.temps.chamber.active);
                            chamberObj.Standby.Add(response.temps.chamber.standby);
                            chamberObj.Heaters.Add(response.temps.chamber.heater);
                        }
                        else
                        {
                            chamberObj.Active[0]  = response.temps.chamber.active;
                            chamberObj.Standby[0] = response.temps.chamber.standby;
                            chamberObj.Heaters[0] = response.temps.chamber.heater;
                        }
                    }
                    else if (Provider.Get.Heat.Chambers.Count > 0)
                    {
                        Provider.Get.Heat.Chambers.Clear();
                    }

                    // Update extra heaters
                    for (int extra = 0; extra < response.temps.extra.Length; extra++)
                    {
                        ExtraHeater extraObj;
                        if (extra >= Provider.Get.Heat.Extra.Count)
                        {
                            extraObj = new ExtraHeater();
                            Provider.Get.Heat.Extra.Add(extraObj);
                        }
                        else
                        {
                            extraObj = Provider.Get.Heat.Extra[extra];
                        }

                        extraObj.Current = response.temps.extra[extra].temp;
                        extraObj.Name    = response.temps.extra[extra].name;
                    }
                    for (int extra = Provider.Get.Heat.Extra.Count; extra > response.temps.extra.Length; extra--)
                    {
                        Provider.Get.Heat.Extra.RemoveAt(extra - 1);
                    }

                    // - Sensors -
                    Probe probeObj;
                    if (Provider.Get.Sensors.Probes.Count == 0)
                    {
                        probeObj = new Probe();
                        Provider.Get.Sensors.Probes.Add(probeObj);
                    }
                    else
                    {
                        probeObj = Provider.Get.Sensors.Probes[0];
                    }

                    probeObj.Value = response.sensors.probeValue;
                    if (response.sensors.probeSecondary != null)
                    {
                        ListHelpers.SetList(probeObj.SecondaryValues, response.sensors.probeSecondary);
                    }

                    // - State -
                    Provider.Get.State.AtxPower = (response.Params.atxPower == -1) ? null : (bool?)(response.Params.atxPower != 0);
                    if (response.output != null)
                    {
                        if (response.output.beepFrequency != 0 && response.output.beepDuration != 0)
                        {
                            Provider.Get.State.Beep.Frequency = response.output.beepFrequency;
                            Provider.Get.State.Beep.Duration  = response.output.beepDuration;
                            _ = Task.Run(async() =>
                            {
                                await Task.Delay(response.output.beepDuration);
                                using (await Provider.AccessReadWriteAsync())
                                {
                                    Provider.Get.State.Beep.Duration  = 0;
                                    Provider.Get.State.Beep.Frequency = 0;
                                }
                            }, Program.CancelSource.Token);
                        }
                        Provider.Get.State.DisplayMessage = response.output.message;
                    }
                    Provider.Get.State.CurrentTool = response.currentTool;
                    Provider.Get.State.Status      = GetStatus(response.status);
                    if (Provider.Get.State.Status == MachineStatus.Idle && FileExecution.MacroFile.DoingMacroFile)
                    {
                        // RRF does not always know whether a macro file is being executed
                        Provider.Get.State.Status = MachineStatus.Busy;
                    }
                    Provider.Get.State.Mode = (MachineMode)Enum.Parse(typeof(MachineMode), response.mode, true);

                    // - Tools -
                    Tool toolObj;
                    for (int tool = 0; tool < response.tools.Length; tool++)
                    {
                        if (tool >= Provider.Get.Tools.Count)
                        {
                            toolObj = new Tool();
                            Provider.Get.Tools.Add(toolObj);
                        }
                        else
                        {
                            toolObj = Provider.Get.Tools[tool];
                        }

                        toolObj.Filament = response.tools[tool].filament;
                        toolObj.Name     = (response.tools[tool].name == "") ? null : response.tools[tool].name;
                        toolObj.Number   = response.tools[tool].number;
                        ListHelpers.SetList(toolObj.Heaters, response.tools[tool].heaters);
                        ListHelpers.SetList(toolObj.Active, response.temps.tools.active[tool]);
                        ListHelpers.SetList(toolObj.Standby, response.temps.tools.standby[tool]);
                        if (toolObj.Fans.Count == 0)
                        {
                            toolObj.Fans.Add(response.tools[tool].fan);
                        }
                        else
                        {
                            toolObj.Fans[0] = response.tools[tool].fan;
                        }
                        ListHelpers.SetList(toolObj.Offsets, response.tools[tool].offsets);
                    }
                    for (int tool = Provider.Get.Tools.Count; tool > response.tools.Length; tool--)
                    {
                        Provider.Get.Tools.RemoveAt(tool - 1);
                    }
                }
            }

            // Deserialize print status response
            else if (module == 3)
            {
                var printResponse = new
                {
                    currentLayer       = 0,
                    currentLayerTime   = 0F,
                    filePosition       = 0L,
                    firstLayerDuration = 0F,
                    extrRaw            = new float[0],
                    printDuration      = 0F,
                    warmUpDuration     = 0F,
                    timesLeft          = new
                    {
                        file     = 0F,
                        filament = 0F,
                        layer    = 0F
                    }
                };
                printResponse = JsonConvert.DeserializeAnonymousType(json, printResponse);

                using (await Provider.AccessReadWriteAsync())
                {
                    Provider.Get.Job.Layer        = printResponse.currentLayer;
                    Provider.Get.Job.LayerTime    = (printResponse.currentLayer == 1) ? printResponse.firstLayerDuration : printResponse.currentLayerTime;
                    Provider.Get.Job.FilePosition = printResponse.filePosition;
                    ListHelpers.SetList(Provider.Get.Job.ExtrudedRaw, printResponse.extrRaw);
                    Provider.Get.Job.Duration           = printResponse.printDuration;
                    Provider.Get.Job.WarmUpDuration     = printResponse.warmUpDuration;
                    Provider.Get.Job.TimesLeft.File     = (printResponse.timesLeft.file > 0F) ? (float?)printResponse.timesLeft.file : null;
                    Provider.Get.Job.TimesLeft.Filament = (printResponse.timesLeft.filament > 0F) ? (float?)printResponse.timesLeft.filament : null;
                    Provider.Get.Job.TimesLeft.Layer    = (printResponse.timesLeft.layer > 0F) ? (float?)printResponse.timesLeft.layer : null;
                }
            }

            // Reset everything if the controller is halted
            using (await Provider.AccessReadOnlyAsync())
            {
                if (Provider.Get.State.Status == MachineStatus.Halted)
                {
                    await SPI.Interface.InvalidateData("Firmware halted");
                }
            }

            // Notify subscribers
            IPC.Processors.Subscription.ModelUpdated();

            // Notify waiting threads about the last module updated
            _moduleUpdateEvents[module].Set();
            _moduleUpdateEvents[module].Reset();
            lock (_moduleUpdateEvents)
            {
                _lastUpdatedModule = module;
            }

            // Force manual garbage collection (maybe the GC cannot keep up with the speed of the update loop)
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }