├── docs ├── img │ ├── main-header.jpg │ ├── 161117-artifacts.gif │ ├── 160826-grasshopper-workflow.png │ ├── 160816-dynamo-workflow-polycurve.png │ ├── 160824-grasshopper-voxel-workflow.png │ └── 160824-contour-curves-filter-800px.gif ├── TODO.md ├── Release_Notes.md └── Acknowledgments.md ├── src ├── Voxel2GCodeCore │ ├── Properties │ │ ├── Settings.settings │ │ ├── Settings.Designer.cs │ │ └── AssemblyInfo.cs │ ├── Classes │ │ ├── Geometry │ │ │ ├── V2GLine.cs │ │ │ ├── V2GPrintable.cs │ │ │ ├── V2GCurve.cs │ │ │ ├── V2GVoxelPoint.cs │ │ │ ├── V2GPrintPolyline.cs │ │ │ ├── V2GPoint.cs │ │ │ └── V2GPrintPosition.cs │ │ ├── Instructions │ │ │ ├── V2GInstruction.cs │ │ │ ├── V2GMovement.cs │ │ │ ├── V2GPrintSegment.cs │ │ │ ├── _PrintSegmentOld.cs │ │ │ └── _PrintMovementOld.cs │ │ ├── Utilities │ │ │ ├── V2GMath.cs │ │ │ ├── V2GPrint.cs │ │ │ ├── V2GGeometry.cs │ │ │ └── V2GVoxel.cs │ │ ├── V2GSlice.cs │ │ ├── V2GPath.cs │ │ ├── V2GSettings.cs │ │ ├── V2GState.cs │ │ └── V2GModel.cs │ └── Voxel2GCodeCore.csproj ├── Voxel2GCodeDynamo │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Voxel2GCodeDynamo.csproj ├── Voxel2GCodeDesignScript │ ├── Utilities │ │ └── V2GDesignScriptGeometry.cs │ ├── V2GDesignScriptCurve.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Voxel2GCodeDesignScript.csproj ├── Voxel2GCodeGH │ ├── V2GH.cs │ ├── Voxel2GCodeLibGH.sln │ ├── Voxel2GCodeGHInfo.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── V2GH_Export.cs │ ├── V2GH_SortCurves.cs │ ├── V2GH_SlicePlanes.cs │ ├── V2GH_VoxelPoint.cs │ ├── V2GH_VoxelCurvePoints.cs │ ├── V2GH_Printer.cs │ ├── V2GH_PrintPoint.cs │ ├── V2GH_BoundingFrames.cs │ ├── V2GH_PrintPolylineData.cs │ ├── V2GH_PrintSettings.cs │ ├── Voxel2GCodeGH.csproj │ └── V2GH_PrintPolyline.cs ├── Voxel2GCodeRhinoCommon │ ├── V2GRhinoCurve.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Voxel2GCodeRhinoCommon.csproj │ └── Utilities │ │ └── V2GRhinoGeometry.cs └── Voxel2GCode.sln ├── LICENSE ├── .gitignore └── README.md /docs/img/main-header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonoesp/Voxel2GCode/HEAD/docs/img/main-header.jpg -------------------------------------------------------------------------------- /docs/img/161117-artifacts.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonoesp/Voxel2GCode/HEAD/docs/img/161117-artifacts.gif -------------------------------------------------------------------------------- /docs/img/160826-grasshopper-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonoesp/Voxel2GCode/HEAD/docs/img/160826-grasshopper-workflow.png -------------------------------------------------------------------------------- /docs/img/160816-dynamo-workflow-polycurve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonoesp/Voxel2GCode/HEAD/docs/img/160816-dynamo-workflow-polycurve.png -------------------------------------------------------------------------------- /docs/img/160824-grasshopper-voxel-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonoesp/Voxel2GCode/HEAD/docs/img/160824-grasshopper-voxel-workflow.png -------------------------------------------------------------------------------- /docs/img/160824-contour-curves-filter-800px.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonoesp/Voxel2GCode/HEAD/docs/img/160824-contour-curves-filter-800px.gif -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Voxel2GCodeDynamo/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GLine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Voxel2GCodeCore.Geometry 8 | { 9 | class V2GLine 10 | { 11 | public V2GPoint StartPoint; 12 | public V2GPoint EndPoint; 13 | 14 | public V2GLine(V2GPoint startPoint, V2GPoint endPoint) 15 | { 16 | this.StartPoint = startPoint; 17 | this.EndPoint = endPoint; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GPrintable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Voxel2GCodeCore.Geometry 7 | { 8 | public abstract class V2GPrintable 9 | { 10 | /// 11 | /// Determines wether the printable movement is relative or absolute. 12 | /// 13 | public bool IsRelative = false; 14 | public virtual void GenerateInstructions(V2GModel model) 15 | { 16 | } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Instructions/V2GInstruction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using Voxel2GCodeCore.Utilities; 8 | 9 | namespace Voxel2GCodeCore.Instructions 10 | { 11 | /// 12 | /// A parent class for printing instructions. 13 | /// 14 | public abstract class V2GInstruction 15 | { 16 | public virtual void GenerateGCode(StringBuilder s, V2GState printer) 17 | { 18 | 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Voxel2GCodeDesignScript/Utilities/V2GDesignScriptGeometry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using Autodesk.DesignScript.Geometry; 8 | 9 | namespace Voxel2GCodeDesignScript.Utilities 10 | { 11 | public class V2GDesignScriptGeometry 12 | { 13 | public static V2GPoint V2GPoint(Autodesk.DesignScript.Geometry.Point p) 14 | { 15 | return new V2GPoint(p.X, p.Y, p.Z); 16 | } 17 | public static Point Point(V2GPoint p) 18 | { 19 | return Autodesk.DesignScript.Geometry.Point.ByCoordinates(p.X, p.Y, p.Z); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using Rhino.Geometry; 8 | using Voxel2GCodeCore.Utilities; 9 | 10 | namespace Voxel2GCodeGH 11 | { 12 | class V2GH 13 | { 14 | public static Point3d Point3d(V2GPoint p) 15 | { 16 | return new Point3d(p.X, p.Y, p.Z); 17 | } 18 | 19 | public static Vector3d Vector3d(V2GPoint p) 20 | { 21 | return new Vector3d(p.X, p.Y, p.Z); 22 | } 23 | 24 | public static V2GPoint V2GPoint(Point3d p) 25 | { 26 | return new V2GPoint(p.X, p.Y, p.Z); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docs/TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | - [ ] Fix `Force Top Layer` in `Slice Planes` component. 4 | 5 | ## Slicer additions (tentative) 6 | 7 | ```csharp 8 | List V2GBoundingFrames(GeometryBase g, double angles) { 9 | List frames = new List(); 10 | // ... 11 | return frames; 12 | } 13 | ``` 14 | 15 | ```csharp 16 | /// 17 | /// Creates infill curves (weaved/stitched already?) 18 | /// 19 | /// 20 | /// 21 | /// Two possible approaches: 22 | /// a. The surface has cavities cut already. 23 | /// b. The surface is an outline, and cavities are later used to trim 24 | /// (which would need different parameters on the function) 25 | List V2GInfillCurves(GeometryBase g) 26 | { 27 | List infill = new List(); 28 | // ... 29 | return infill; 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Utilities/V2GMath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Voxel2GCodeCore.Utilities 8 | { 9 | public class V2GMath 10 | { 11 | /// 12 | /// Precision for floating-point comparisons. 13 | /// 14 | public static readonly double EPSILON = 0.0000000001; 15 | /// 16 | /// Constant to convert from degrees to radians. 17 | /// 18 | public const double DEGREES_TO_RADIANS = Math.PI / 180.0; 19 | /// 20 | /// Constant to convert from radians to degrees. 21 | /// 22 | public const double RADIANS_TO_DEGREES = 1 / DEGREES_TO_RADIANS; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/Release_Notes.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## 0.1.2 (master) 4 | 5 | This is the current version in progress. 6 | 7 | - [X] Change ZOffset default to 0.0. 8 | - [X] [Core] Removed redundant G-code. (Coordinates and speeds only appear on G1 commands when they change, which reduces file sizes.) 9 | - [X] [Core] Fixed resetting head comparison, now it checks for absolute different between Z coordinates rather than comparing them (this was returning false for a difference of 0.000000001 in coordinates). 10 | - [X] [Core] EndPoint behavior fixed to incremental positioning (G91). 11 | 12 | ## 0.1.1 13 | 14 | - [X] [Core] Reset E value at Z level change. 15 | - [X] [Core] V2G Reset E value per Z. 16 | - [X] [Core] Fixed bug were ZOffset was cumulative over points. 17 | - [X] [GH] Verbose setting transferred to printing settings component. 18 | 19 | ## 0.1.0 20 | 21 | - [X] First released version. 22 | -------------------------------------------------------------------------------- /src/Voxel2GCodeRhinoCommon/V2GRhinoCurve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using Rhino.Geometry; 8 | 9 | namespace Voxel2GCodeRhino 10 | { 11 | public class V2GRhinoCurve : V2GCurve 12 | { 13 | public Rhino.Geometry.Curve curve; 14 | 15 | public override V2GPoint StartPoint 16 | { 17 | get 18 | { 19 | return new V2GPoint(curve.PointAtStart.X, curve.PointAtStart.Y, curve.PointAtStart.Z); 20 | } 21 | } 22 | 23 | public override V2GPoint EndPoint 24 | { 25 | get 26 | { 27 | return new V2GPoint(curve.PointAtEnd.X, curve.PointAtEnd.Y, curve.PointAtEnd.Z); 28 | } 29 | } 30 | 31 | public override void Reverse() 32 | { 33 | curve.Reverse(); 34 | } 35 | 36 | public V2GRhinoCurve(Curve c) 37 | { 38 | this.curve = c; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Voxel2GCodeDesignScript/V2GDesignScriptCurve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using Autodesk.DesignScript.Geometry; 8 | 9 | namespace Voxel2GCodeDesignScript 10 | { 11 | class V2GDesignScriptCurve : V2GCurve 12 | { 13 | public Autodesk.DesignScript.Geometry.Curve curve; 14 | 15 | public override V2GPoint StartPoint 16 | { 17 | get 18 | { 19 | return new V2GPoint(curve.StartPoint.X, curve.StartPoint.Y, curve.StartPoint.Z); 20 | } 21 | } 22 | 23 | public override V2GPoint EndPoint 24 | { 25 | get 26 | { 27 | return new V2GPoint(curve.EndPoint.X, curve.EndPoint.Y, curve.EndPoint.Z); 28 | } 29 | } 30 | 31 | public override void Reverse() 32 | { 33 | curve.Reverse(); 34 | } 35 | 36 | public V2GDesignScriptCurve(Curve c) 37 | { 38 | this.curve = c; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Nono Martínez Alonso 4 | Copyright (c) 2016 Autodesk for portions developed between May and August 2016 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Voxel2GCodeCore.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/V2GSlice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Voxel2GCodeCore 8 | { 9 | /// 10 | /// A class to hold a set of paths contains in a slice. 11 | /// 12 | public class V2GSlice 13 | { 14 | /// 15 | /// A tag to identify an specific PrintSlice which displays on the G-code file if the printer is in verbose mode. 16 | /// 17 | public string tag = "Untitled"; 18 | /// 19 | /// A list of paths. 20 | /// 21 | public List Paths = new List(); 22 | /// 23 | /// Generate G-code instructions from the slice. 24 | /// 25 | /// 26 | /// 27 | public void GenerateGCode(StringBuilder s, V2GState printer) 28 | { 29 | s.Append("\n; PrintSlice"); 30 | if (this.tag != "Untitled") s.Append(" (" + this.tag + ")"); 31 | s.Append("."); 32 | foreach (V2GPath p in Paths) 33 | { 34 | p.GenerateGCode(s, printer); 35 | } 36 | } 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/Voxel2GCodeLibGH.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel2GCodeLibGH", "Voxel2GCodeLibGH.csproj", "{6F0508DE-90BE-4134-B69A-1BB68E925F36}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D758A2A2-B0C7-4D59-9D73-2944F7292DE6}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug32|Any CPU = Debug32|Any CPU 13 | Debug64|Any CPU = Debug64|Any CPU 14 | Release|Any CPU = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug32|Any CPU.ActiveCfg = Debug32|Any CPU 18 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug32|Any CPU.Build.0 = Debug32|Any CPU 19 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug64|Any CPU.ActiveCfg = Debug64|Any CPU 20 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug64|Any CPU.Build.0 = Debug64|Any CPU 21 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Release|Any CPU.Build.0 = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GCurve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Voxel2GCodeCore.Geometry 8 | { 9 | abstract public class V2GCurve 10 | { 11 | /// 12 | /// 13 | /// 14 | abstract public V2GPoint StartPoint 15 | { 16 | get; 17 | } 18 | 19 | /// 20 | /// 21 | /// 22 | abstract public V2GPoint EndPoint 23 | { 24 | get; 25 | } 26 | 27 | /// 28 | /// 29 | /// 30 | abstract public void Reverse(); 31 | 32 | /*public V2GCurve() 33 | { 34 | //this.StartPoint = startPoint; 35 | //this.EndPoint = endPoint; 36 | }*/ 37 | } 38 | 39 | /* 40 | class V2GCurveRhino: V2GCurve 41 | { 42 | Rhino.Geometry.Curve curve; 43 | 44 | virtual public V2GPoint StartPoint 45 | { 46 | get 47 | { 48 | return new V2GPoint(curve.PointAtStart.X, curve.PointAtStart.Y, curve.PointAtStart.Z); 49 | }; 50 | } 51 | 52 | virtual public V2GPoint EndPoint 53 | { 54 | get 55 | { 56 | return new V2GPoint(curve.PointAtEnd.X, curve.PointAtEnd.Y, curve.PointAtEnd.Z); 57 | }; 58 | } 59 | }*/ 60 | } 61 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Voxel2GCodeCore")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Voxel2GCodeCore")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bcb34b54-0384-47a9-98e1-e4f43f520023")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.1.*")] 36 | [assembly: AssemblyFileVersion("0.1.2.0")] 37 | -------------------------------------------------------------------------------- /src/Voxel2GCodeDynamo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Voxel2GCodeDynamo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Voxel2GCodeDynamo")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cddac5a1-7e66-42ff-b012-b5095b1b1ac2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/Voxel2GCodeGHInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using Grasshopper.Kernel; 4 | 5 | namespace Voxel2GCodeGH 6 | { 7 | public class Voxel2GCodeGHInfo : GH_AssemblyInfo 8 | { 9 | public override string Name 10 | { 11 | get 12 | { 13 | return "Voxel2GCodeGH"; 14 | } 15 | } 16 | public override Bitmap Icon 17 | { 18 | get 19 | { 20 | //Return a 24x24 pixel bitmap to represent this GHA library. 21 | return null; 22 | } 23 | } 24 | public override string Description 25 | { 26 | get 27 | { 28 | //Return a short string describing the purpose of this GHA library. 29 | return ""; 30 | } 31 | } 32 | public override Guid Id 33 | { 34 | get 35 | { 36 | return new Guid("9477c734-e22e-40e1-9c76-51afb7f8f44a"); 37 | } 38 | } 39 | 40 | public override string AuthorName 41 | { 42 | get 43 | { 44 | //Return a string identifying you or your company. 45 | return ""; 46 | } 47 | } 48 | public override string AuthorContact 49 | { 50 | get 51 | { 52 | //Return a string representing your preferred contact details. 53 | return ""; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Voxel2GCodeRhinoCommon/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Voxel2GCodeRhinoCommon")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Voxel2GCodeRhinoCommon")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3f73c724-8a83-47c7-ae44-1baf6cfd2147")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Voxel2GCodeDesignScript/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Voxel2GCodeDesignScript")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Voxel2GCodeDesignScript")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9c56fd2e-e684-45f2-a424-bf8fb5c20d8e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.1.0.0")] 36 | [assembly: AssemblyFileVersion("0.1.0.0")] 37 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Rhino.PlugIns; 5 | 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("Voxel2GCodeLibGH")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("Voxel2GCodeLibGH")] 15 | [assembly: AssemblyCopyright("Copyright © 2016")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | // The following GUID is for the ID of the typelib if this project is exposed to COM 25 | [assembly: Guid("6f0508de-90be-4134-b69a-1bb68e925f36")] // This will also be the Guid of the Rhino plug-in 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | [assembly: AssemblyVersion("1.0.0.0")] 38 | [assembly: AssemblyFileVersion("1.0.0.0")] 39 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/V2GPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Instructions; 7 | 8 | namespace Voxel2GCodeCore 9 | { 10 | /// 11 | /// A class to hold a set of printable segments. 12 | /// 13 | public class V2GPath 14 | { 15 | /// 16 | /// A tag to identify an specific PrintPath which displays on the G-code file if the printer is in verbose mode. 17 | /// 18 | public string tag = "Untitled"; 19 | 20 | /// 21 | /// A list of segments contained in the path. 22 | /// 23 | public List Segments = new List(); 24 | 25 | /// 26 | /// Generate G-code instructions for the path. 27 | /// 28 | /// 29 | /// 30 | public void GenerateGCode(StringBuilder s, V2GState printer) 31 | { 32 | if (printer.settings.IsVerbose) 33 | { 34 | s.Append("\n; PrintPath."); 35 | if (this.tag != "Untitled") s.Append(" (" + this.tag + ".)"); 36 | s.Append("(" + this.Segments.Count + " segments.)"); 37 | s.Append("\n; -----"); 38 | } 39 | int idx = 0; 40 | foreach (V2GInstruction ins in Segments) 41 | { 42 | ins.GenerateGCode(s, printer); 43 | idx++; 44 | } 45 | if (printer.settings.IsVerbose) s.Append("\n; -----"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /docs/Acknowledgments.md: -------------------------------------------------------------------------------- 1 | # Acknowledgments 2 | 3 | [Voxel2GCode](http://github.com/nonoesp/Voxel2GCode) originated in Boston as part of the *Material Gradients with Monolith* project at [Autodesk Inc](http://autodesk.com). 4 | 5 | #### Autodesk 6 | 7 | The development of Voxel2GCode was sponsored by Autodesk, under the guidance of Matt Jezyk, Panagiotis Michalatos, and all the [Generative Design Team](http://www.autodesk.com/solutions/generative-design), which played a huge role in making this project possible. They let me put my own vision into this project and provided me incredible resources. (Having a ZMorph of my own for prototyping clearly speeded up the research and development process.) Special thanks to Panagiotis Michalatos, for his invaluable insight on the overall philosophy of the project and help with code implementation. Also, I feel humbled of the chance to work with Andrew Payne, Zach Kron, Peter Boyer, Neal Burham, Racel Williams, Lilli Smith, Michael Kirschner, Tom, Anthony Hauck, Thord, Rick Rundell, Adam Allard, Tim Brinkerhoff, Joe Aronis, Bevin Lin, Nathan King and the rest of the team. 8 | 9 | My colleagues—Jose Luis Garcia del Castillo, Keith Alfaro, Omid Oliyan, and Varvara Toulkeridou—made my summer incredibly fun: 👌. You should check out the projects they’ve been working on. 10 | 11 | * [BRobot](https://github.com/garciadelcastillo/BRobot) by Jose Luis García del Castillo. An open-source library for action and state-based robot control. 12 | * [MeshToolkit](http://dynamobim.org/meshtoolkit-1-1-0-release/) development by Keith Alfaro. Mesh utilities for Dynamo. 13 | * [Fractal](https://home.fractal.live). Omid and Varvara have been working on this new tool for evaluating different design options. 14 | 15 | #### BRobot (now called [Machina.NET](http://github.com/robotexmachina/machina.net)) 16 | 17 | Voxel2GCode includes operator methods from BRobot.Point inside V2GPoint. 18 | 19 | #### Monolith 20 | 21 | Voxel2GCode uses Monolith libraries for voxel operations. 22 | 23 | *** 24 | 25 | I apologize if you think you should be here and I forgot about you. If so, please do let me know and I’ll add you! 26 | 27 | Voxel2GCode was created and is maintained by [Nono Martínez Alonso](http://nono.ma). 28 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Instructions/V2GMovement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeCore.Instructions 9 | { 10 | /// 11 | /// A printing instruction to move the tool-head without extruding material. 12 | /// 13 | public class V2GMovement : V2GInstruction 14 | { 15 | // TODO: Implement IsRelative behavior 16 | public V2GPrintPosition PrintPosition; 17 | //public double Speed = 700.0; 18 | public double MovementThreshold = 0.001; 19 | 20 | public V2GMovement(V2GPrintPosition printPosition, double speed) 21 | { 22 | this.PrintPosition = printPosition; 23 | this.PrintPosition.Speed = speed; 24 | } 25 | /// 26 | /// Generate G-code instructions for the segment. 27 | /// 28 | /// StringBuilder to store the G-code. 29 | /// Printer state. 30 | public override void GenerateGCode(StringBuilder s, V2GState printer) 31 | { 32 | double MovementLength = printer.Position.DistanceTo(printer.PrintPointOnBase(this.PrintPosition)); 33 | if (MovementLength > MovementThreshold) 34 | { 35 | if (printer.settings.IsVerbose) s.Append("\n(A. PrintMovement) (Printer has to move)"); 36 | printer.F = this.PrintPosition.Speed; 37 | printer.SetPosition(this.PrintPosition, s); 38 | 39 | // Move 40 | s.Append("\nG1"); 41 | s.Append(" X" + Math.Round(printer.Position.X, 4)); 42 | s.Append(" Y" + Math.Round(printer.Position.Y, 4)); 43 | s.Append(" Z" + Math.Round(printer.Position.Z, 4)); 44 | s.Append(" F" + Math.Round(printer.F, 4)); 45 | } 46 | else 47 | { 48 | if (printer.settings.IsVerbose) s.Append("\n (A. PrintMovement) (Printer is already here)"); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Instructions/V2GPrintSegment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeCore.Instructions 9 | { 10 | /// 11 | /// A print instruction to extrude material along a segment. 12 | /// 13 | public class V2GPrintSegment : V2GInstruction 14 | { 15 | /// 16 | /// The destination point of the segment. 17 | /// 18 | public V2GPrintPosition PrintPosition; 19 | 20 | public V2GPrintSegment(V2GPrintPosition printPosition) { 21 | this.PrintPosition = printPosition; 22 | } 23 | 24 | /// 25 | /// Generate G-code instructions for the segment. 26 | /// 27 | /// StringBuilder to store the G-code. 28 | /// Printer state. 29 | public override void GenerateGCode(StringBuilder s, V2GState printer) 30 | { 31 | V2GPrintPosition prevPrinterPosition = printer.Position; 32 | bool speedChanged = false; 33 | if(printer.F != this.PrintPosition.Speed) 34 | { 35 | printer.F = this.PrintPosition.Speed; 36 | speedChanged = true; 37 | } 38 | printer.SetPosition(this.PrintPosition, s); 39 | double length = printer.Position.DistanceTo(prevPrinterPosition); 40 | 41 | // Switch Extruder Head if Needed 42 | printer.SetHead(s, this.PrintPosition.Head); 43 | 44 | // Move to Start Point 45 | //s.Append("\nG1"); 46 | //s.Append(" Z" + Math.Round(printer.Position.Z, 4)); 47 | 48 | // Move and Extrude 49 | s.Append("\nG1"); 50 | if (prevPrinterPosition.X != printer.Position.X) s.Append(" X" + Math.Round(printer.Position.X, 4)); 51 | if (prevPrinterPosition.Y != printer.Position.Y) s.Append(" Y" + Math.Round(printer.Position.Y, 4)); 52 | if (Math.Abs(prevPrinterPosition.Z - printer.Position.Z) > 0.0001) s.Append(" Z" + Math.Round(printer.Position.Z, 4)); 53 | printer.IncreaseE(s, this.PrintPosition.MaterialAmount, length, this.PrintPosition.MixPercentage); 54 | if(speedChanged) s.Append(" F" + Math.Round(printer.F, 4)); 55 | } 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/V2GSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeCore 9 | { 10 | /// 11 | /// A class to hold 3D printing settings. 12 | /// 13 | public class V2GSettings 14 | { 15 | /// 16 | /// Layer height in mm. 17 | /// 18 | public double LayerHeight = 0.2; 19 | 20 | /// 21 | /// Default feed rate of the printer in mm/min. 22 | /// 23 | public double Speed = 700.0; 24 | 25 | /// 26 | /// Default retraction length for retraction operations of the filament(s) in mm. 27 | /// 28 | public double Retraction_Length = 0.2; 29 | 30 | /// 31 | /// Temperature of the heated bed (if your printer has one) in celsius degrees. 32 | /// 33 | public double BedTemperature = 60.0; 34 | 35 | /// 36 | /// Temperature of the primary extruder head in celsius degrees. 37 | /// 38 | public double T0Temperature = 200.0; 39 | 40 | /// 41 | /// Temperature of the secondary extruder head in celsius degrees. 42 | /// 43 | public double T1Temperature = 200.0; 44 | 45 | /// 46 | /// Diameter of the printing filament in mm. 47 | /// 48 | public double FilamentThickness = 1.75; 49 | 50 | /// 51 | /// Determine if the printer should heat up at the beginning of the print. 52 | /// 53 | public bool ShouldHeatUpOnStart = true; 54 | 55 | /// 56 | /// Determine if the printer should cool down at the end of the print. 57 | /// 58 | public bool ShouldCoolDownOnEnd = true; 59 | 60 | /// 61 | /// Offset from the bed to the extrusion in mm. 62 | /// 63 | public double ZOffset = 0.0; 64 | 65 | /// 66 | /// Printer start point. 67 | /// 68 | public V2GPrintPosition StartPoint = new V2GPrintPosition(25.0, 25.0, 0.0); 69 | 70 | /// 71 | /// Printer end point. 72 | /// 73 | public V2GPrintPosition EndPoint = new V2GPrintPosition(25.0, 25.0, 0.0); 74 | 75 | /// 76 | /// Determines wether the generated G-code should contain detailed comments or not. 77 | /// 78 | public bool IsVerbose = false; 79 | 80 | /// 81 | /// Constructor of PrintSettings. 82 | /// 83 | public V2GSettings() 84 | { 85 | /// 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GVoxelPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MalachiteNet; 7 | using MonolithLib; 8 | using CGeometrica; 9 | using CSerializer; 10 | using Voxel2GCodeCore.Utilities; 11 | 12 | namespace Voxel2GCodeCore.Geometry 13 | { 14 | /// 15 | /// 16 | /// 17 | public class V2GVoxelPoint 18 | { 19 | public V2GPoint Position; 20 | public V2GPoint ContourVector3d; 21 | public V2GPoint ContourVector; 22 | public V2GPoint GradientVector; 23 | public double FieldValue; 24 | 25 | /// 26 | /// A V2GPoint with voxel metadata. 27 | /// 28 | /// 29 | /// 30 | public V2GVoxelPoint(VoxelImage _Voxel, V2GPoint _Point) 31 | { 32 | this.Position = _Point; 33 | this.SetPropertiesWith(_Voxel); 34 | } 35 | 36 | /// 37 | /// Calculate voxel point properties. 38 | /// 39 | /// 40 | public void SetPropertiesWith(VoxelImage _Voxel) { 41 | double delta = 0.000001; 42 | 43 | VoxelImage v = _Voxel as VoxelImage; 44 | VoxelChannel vc = v.GetChannel(VoxelImageLayout.SHAPECHANNEL) as VoxelChannel; 45 | 46 | V2GPoint x0 = this.Position - V2GPoint.XAxis * delta; 47 | V2GPoint x1 = this.Position + V2GPoint.XAxis * delta; 48 | V2GPoint y0 = this.Position - V2GPoint.YAxis * delta; 49 | V2GPoint y1 = this.Position + V2GPoint.YAxis * delta; 50 | V2GPoint z0 = this.Position - V2GPoint.ZAxis * delta; 51 | V2GPoint z1 = this.Position + V2GPoint.ZAxis * delta; 52 | 53 | double x = V2GVoxel.GetVoxelFieldValue(vc, x1) - V2GVoxel.GetVoxelFieldValue(vc, x0); 54 | double y = V2GVoxel.GetVoxelFieldValue(vc, y1) - V2GVoxel.GetVoxelFieldValue(vc, y0); 55 | double z = V2GVoxel.GetVoxelFieldValue(vc, z1) - V2GVoxel.GetVoxelFieldValue(vc, z0); 56 | 57 | V2GPoint UnitVector = new V2GPoint(x, y, z); 58 | UnitVector.Normalize(); 59 | 60 | double fieldValue = V2GVoxel.GetVoxelFieldValue(vc, this.Position); 61 | V2GPoint RealVector = UnitVector * fieldValue; 62 | 63 | V2GPoint UnitVectorProjected = new V2GPoint(RealVector.X, RealVector.Y, 0); 64 | V2GPoint UnitVectorPerpendicularProjected = V2GPoint.CrossProduct(UnitVectorProjected, V2GPoint.ZAxis); 65 | UnitVectorProjected.Normalize(); 66 | UnitVectorPerpendicularProjected.Normalize(); 67 | 68 | this.ContourVector3d = UnitVector; 69 | this.ContourVector = UnitVectorPerpendicularProjected; 70 | this.GradientVector = UnitVectorProjected; 71 | this.FieldValue = fieldValue; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Instructions/_PrintSegmentOld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using Voxel2GCodeCore.Utilities; 8 | 9 | namespace Voxel2GCodeCore.Instructions 10 | { 11 | /// 12 | /// A PrintInstruction subclass to print segments. 13 | /// 14 | public class PrintSegmentOld : V2GInstruction 15 | { 16 | public V2GPrintPosition p; 17 | public double speed; 18 | public double thickness; 19 | public bool AllowsGroundOverride = true; 20 | public double HeightFactor = 1.0; 21 | 22 | //public bool IsFirst = false; 23 | 24 | public double Height() 25 | { 26 | return V2GPrint.Height(this.thickness, this.HeightFactor); 27 | } 28 | 29 | public PrintSegmentOld() 30 | { 31 | speed = 700; 32 | thickness = 0.05; 33 | } 34 | 35 | public double EUnitIncrease() 36 | { 37 | return V2GPrint.EUnitIncrease(this.thickness); 38 | } 39 | 40 | public override void GenerateGCode(StringBuilder s, V2GState printer) 41 | { 42 | V2GPrintPosition prevP = printer.Position; 43 | 44 | printer.F = this.speed; 45 | printer.SetPosition(this.p); 46 | double length = printer.Position.DistanceTo(prevP); 47 | double extrusionHeight = this.Height(); 48 | 49 | if (printer.Position.Z < 0) printer.Position.Z = 0; // todo: this safes inside the PrintState class 50 | 51 | if (printer.Position.Z < 0.7 && this.AllowsGroundOverride) 52 | { 53 | if (this.thickness < 700) this.speed = 400; 54 | extrusionHeight = 0.25; 55 | } 56 | 57 | // Locate Z in its place 58 | s.Append("\nG1"); 59 | s.Append(" Z" + Math.Round((printer.Position.Z + extrusionHeight), 4)); 60 | 61 | printer.EPerMM = this.EUnitIncrease(); 62 | 63 | // Calculate E increase 64 | double EUnitIncrease = printer.EPerMM; 65 | double EIncrease = EUnitIncrease * length; 66 | printer.E += EIncrease; 67 | 68 | // Extrude 69 | // - todo: check if coordinates are equal than previous ones 70 | s.Append("\nG1"); 71 | s.Append(" X" + Math.Round(printer.Position.X, 4)); 72 | s.Append(" Y" + Math.Round(printer.Position.Y, 4)); 73 | s.Append(" Z" + Math.Round((printer.Position.Z + extrusionHeight), 4)); 74 | s.Append(" E" + Math.Round(printer.E, 4)); 75 | s.Append(" F" + Math.Round(printer.F, 4)); 76 | if (printer.settings.IsVerbose) s.Append(" (EUnitIncrease " + EUnitIncrease + ", thickness " + this.thickness + ", height " + extrusionHeight + ")"); 77 | if (printer.settings.IsVerbose) s.Append(" (PrintSegment)"); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_Export.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | 7 | using System.IO; 8 | 9 | namespace Voxel2GCodeGH 10 | { 11 | public class V2GH_Export : GH_Component 12 | { 13 | /// 14 | /// Initializes a new instance of the V2GExport class. 15 | /// 16 | public V2GH_Export() 17 | : base("Export G-code", "Export", 18 | "Write a string of text to file", 19 | "V2G", "G-code") 20 | { 21 | } 22 | 23 | /// 24 | /// Registers all the input parameters for this component. 25 | /// 26 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 27 | { 28 | pManager.AddTextParameter("Text", "Text", "String to write to file.", GH_ParamAccess.item, "Intentionally left blank."); 29 | pManager.AddTextParameter("FilePath", "FilePath", "Path to export the file to.", GH_ParamAccess.item); 30 | pManager.AddBooleanParameter("Active", "Active", "Wether should be exporting or not.", GH_ParamAccess.item, true); 31 | } 32 | 33 | /// 34 | /// Registers all the output parameters for this component. 35 | /// 36 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 37 | { 38 | } 39 | 40 | /// 41 | /// This is the method that actually does the work. 42 | /// 43 | /// The DA object is used to retrieve from inputs and store in outputs. 44 | protected override void SolveInstance(IGH_DataAccess DA) 45 | { 46 | // Variables 47 | string Text = ""; 48 | string FilePath = ""; 49 | bool IsActive = false; 50 | 51 | // Get Data 52 | DA.GetData(0, ref Text); 53 | DA.GetData(1, ref FilePath); 54 | DA.GetData(2, ref IsActive); 55 | 56 | if (IsActive) 57 | { 58 | using (StreamWriter outputFile = new StreamWriter(FilePath)) 59 | { 60 | outputFile.Write(Text); 61 | } 62 | } 63 | } 64 | 65 | /// 66 | /// Provides an Icon for the component. 67 | /// 68 | protected override System.Drawing.Bitmap Icon 69 | { 70 | get 71 | { 72 | //You can add image files to your project resources and access them like this: 73 | // return Resources.IconForThisComponent; 74 | return null; 75 | } 76 | } 77 | 78 | /// 79 | /// Gets the unique ID for this component. Do not change this ID after release. 80 | /// 81 | public override Guid ComponentGuid 82 | { 83 | get { return new Guid("{3a1ae457-ca4b-4888-b329-fed85d306455}"); } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeDesignScript/Voxel2GCodeDesignScript.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E} 8 | Library 9 | Properties 10 | Voxel2GCodeDesignScript 11 | Voxel2GCodeDesignScript 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\..\..\..\..\..\..\Program Files\Dynamo 0.8\ProtoGeometry.dll 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {bcb34b54-0384-47a9-98e1-e4f43f520023} 54 | Voxel2GCodeCore 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_SortCurves.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore; 7 | using Voxel2GCodeCore.Utilities; 8 | using Voxel2GCodeCore.Geometry; 9 | using Voxel2GCodeRhino; 10 | 11 | namespace Voxel2GCodeGH 12 | { 13 | public class V2GH_SortCurves : GH_Component 14 | { 15 | /// 16 | /// Initializes a new instance of the V2GCurveSort class. 17 | /// 18 | public V2GH_SortCurves() 19 | : base("Sort Curves to Print", "CurveSort", 20 | "Sort curves on the best path to print.", 21 | "V2G", "Slicer") 22 | { 23 | } 24 | 25 | /// 26 | /// Registers all the input parameters for this component. 27 | /// 28 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 29 | { 30 | pManager.AddCurveParameter("Curve", "Curve", "List of curves to sort for printing.", GH_ParamAccess.list); 31 | } 32 | 33 | /// 34 | /// Registers all the output parameters for this component. 35 | /// 36 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 37 | { 38 | pManager.AddCurveParameter("Curve", "Curve", "List of sorted curves for printing.", GH_ParamAccess.list); 39 | } 40 | 41 | /// 42 | /// This is the method that actually does the work. 43 | /// 44 | /// The DA object is used to retrieve from inputs and store in outputs. 45 | protected override void SolveInstance(IGH_DataAccess DA) 46 | { 47 | List curves = new List(); 48 | List sortedCurves = new List(); 49 | if (!DA.GetDataList(0, curves)) return; 50 | 51 | List V2GRhinoCurves = new List(); 52 | foreach (Curve c in curves) 53 | { 54 | V2GRhinoCurves.Add(new V2GRhinoCurve(c)); 55 | } 56 | List vCurves = V2GGeometry.SortCurves(V2GRhinoCurves); 57 | foreach (V2GCurve c in vCurves) 58 | { 59 | sortedCurves.Add((c as V2GRhinoCurve).curve); 60 | } 61 | DA.SetDataList(0, sortedCurves); 62 | } 63 | 64 | /// 65 | /// Provides an Icon for the component. 66 | /// 67 | protected override System.Drawing.Bitmap Icon 68 | { 69 | get 70 | { 71 | //You can add image files to your project resources and access them like this: 72 | // return Resources.IconForThisComponent; 73 | return null; 74 | } 75 | } 76 | 77 | /// 78 | /// Gets the unique ID for this component. Do not change this ID after release. 79 | /// 80 | public override Guid ComponentGuid 81 | { 82 | get { return new Guid("{687c293d-f136-4672-bcb4-9b032f9f958f}"); } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeRhinoCommon/Voxel2GCodeRhinoCommon.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147} 8 | Library 9 | Properties 10 | Voxel2GCodeRhinoCommon 11 | Voxel2GCodeRhinoCommon 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | False 36 | ..\..\..\..\..\..\..\..\..\..\Program Files\Rhinoceros 5 (64-bit)\System\RhinoCommon.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {bcb34b54-0384-47a9-98e1-e4f43f520023} 55 | Voxel2GCodeCore 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GPrintPolyline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Voxel2GCodeCore.Geometry 7 | { 8 | /// 9 | /// A printable polyline with printing information. 10 | /// 11 | public class V2GPrintPolyline : V2GPrintable 12 | { 13 | /// 14 | /// Set of printable points to print along. 15 | /// 16 | public List PrintPositions = new List(); 17 | /// 18 | /// Default feed rate to move and extrude, i.e. velocity in mm/min. 19 | /// 20 | double Speed = 700.0; 21 | /// 22 | /// Default amount of material to be fed per mm. (If using a dual extruder, the material distributes among using the MixPercentage value.) 23 | /// 24 | double MaterialAmount = 0.033; 25 | /// 26 | /// Extruder-head to be used to print this. (e.g. T0 for left extruder, T1 for right extruder, T3 for dual extruder, etc.) This values vary from printer to printer. 27 | /// 28 | int Head = 1; 29 | /// 30 | /// Percentage of material to extrude with the secondary extruder. 31 | /// 32 | double MixPercentage = 0.0; 33 | 34 | public void AddPrintPosition(V2GPoint position, double speed, double materialAmount, int head, double mixPercentage) 35 | { 36 | this.Speed = speed; 37 | this.MaterialAmount = materialAmount; 38 | this.Head = head; 39 | this.MixPercentage = mixPercentage; 40 | this.PrintPositions.Add(new V2GPrintPosition(position, speed, materialAmount, head, mixPercentage)); 41 | } 42 | 43 | public void AddPrintPosition(V2GPrintPosition printPosition) 44 | { 45 | this.Speed = printPosition.Speed; 46 | this.MaterialAmount = printPosition.MaterialAmount; 47 | this.Head = printPosition.Head; 48 | this.MixPercentage = printPosition.MixPercentage; 49 | this.PrintPositions.Add(printPosition); 50 | } 51 | 52 | public void AddPrintPosition(V2GPoint position) 53 | { 54 | this.PrintPositions.Add(new V2GPrintPosition(position)); 55 | } 56 | 57 | // add variables to constructor 58 | 59 | /* 60 | // Tentative 61 | // Implement a string or string[] of segment types to apply effects to each of the segments 62 | // public string SegmentType = "PRINT_SEGMENT_2"; 63 | // public string[] SegmentTypes; // this could be to input a series of iterating types (wavy, segment2, [repeat]) 64 | 65 | // TODO: Implement a Generate instructions method inside each printable 66 | public override void GenerateInstructions(PrintModel model) 67 | { 68 | //base.GenerateInstructions(); 69 | PrintPath path = new PrintPath(); 70 | 71 | //PrintSegment segment = new PrintSegment2(); 72 | //segment.p = 73 | 74 | //path.Segments.Add(new PrintSegment2()); 75 | //model.Pahts.Add(new Path); 76 | // Append self as paths 77 | } 78 | */ 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Utilities/V2GPrint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | using System.IO; 8 | 9 | namespace Voxel2GCodeCore.Utilities 10 | { 11 | /// 12 | /// A class with 3D printing utilities and workflows. 13 | /// 14 | 15 | public class V2GPrint 16 | { 17 | public delegate double ThicknessIncrementDelegate(int index); 18 | 19 | /// 20 | /// Returns heights at which each slice should be printed for a given height 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | /// 27 | /// 28 | /// 29 | /// 30 | public static List ZHeights(double height, double StartThickness, ThicknessIncrementDelegate ThicknessDel, out List Thicknesses, double HeightFactor = 1.0, double ThicknessIncrement = 0.0) 31 | { 32 | List heights = new List(); 33 | List thicknesses = new List(); 34 | 35 | double CurrentHeight = 0.005; // todo: Figure out why 0.0 flips the offset of the section curves 36 | double CurrentThickness = StartThickness; 37 | 38 | int i = 0; 39 | while (CurrentHeight < height) 40 | { 41 | heights.Add(CurrentHeight); 42 | if (ThicknessDel == null) 43 | { 44 | CurrentThickness += ThicknessIncrement * i; 45 | } 46 | else 47 | { 48 | CurrentThickness = StartThickness + ThicknessDel(i); 49 | } 50 | thicknesses.Add(CurrentThickness); 51 | CurrentHeight += V2GPrint.Height(CurrentThickness, HeightFactor); 52 | i++; 53 | } 54 | 55 | Thicknesses = thicknesses; 56 | 57 | return heights; 58 | } 59 | 60 | // Deprecated 61 | public static double Height(double _thickness, double _factor = 1.0) 62 | { 63 | return LayerHeight(_thickness, _factor); 64 | } 65 | 66 | public static double LayerHeight(double _thickness, double _factor = 1.0) 67 | { 68 | double FilamentDiameter = 1.75; 69 | double FilamentArea = Math.PI * Math.Pow((FilamentDiameter / 2), 2); 70 | double height = Math.Sqrt(FilamentArea * V2GPrint.EUnitIncrease(_thickness)); 71 | height *= _factor; 72 | if (height < 0) return 0; 73 | return height * _factor; 74 | } 75 | 76 | public static double EUnitIncrease(double _thickness) 77 | { 78 | if (_thickness <= 0) return 0.0; 79 | return 0.033 * _thickness / 0.05; 80 | } 81 | 82 | public static void WriteStringToFilePath(string FilePath, string Text = "Intentionally left blank.") 83 | { 84 | using (StreamWriter outputFile = new StreamWriter(FilePath)) 85 | { 86 | outputFile.Write(Text); 87 | } 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_SlicePlanes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeRhino; 7 | using Voxel2GCodeRhino.Utilities; 8 | 9 | namespace Voxel2GCodeGH 10 | { 11 | public class V2GH_SlicePlanes : GH_Component 12 | { 13 | /// 14 | /// Initializes a new instance of the V2GH_SlicePlanes class. 15 | /// 16 | public V2GH_SlicePlanes() 17 | : base("Get Slice Planes", "SlicePlanes", 18 | "Get z planes to slice a given geometry.", 19 | "V2G", "Slicer") 20 | { 21 | } 22 | 23 | /// 24 | /// Registers all the input parameters for this component. 25 | /// 26 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 27 | { 28 | pManager.AddGeometryParameter("Geometry", "Geometry", "Geometry to slice.", GH_ParamAccess.item); 29 | pManager.AddNumberParameter("Layer Height", "Layer Height", "Distance between z planes.", GH_ParamAccess.item, 0.2); 30 | pManager.AddNumberParameter("Global Offset", "Global Offset", "Offset distance applied to all layers.", GH_ParamAccess.item, 0); 31 | pManager.AddNumberParameter("Bottom Layer Offset", "Bottom Layer Offset", "Bottom layer offset distance.", GH_ParamAccess.item, 0); 32 | pManager.AddNumberParameter("Top Layer Offset", "Bottom Layer Offset", "Top layer offset distance.", GH_ParamAccess.item, 0); 33 | pManager.AddBooleanParameter("Force Top Layer", "Force Top Layer", "Ensure there is a layer at the top. (0 or 1; True or False.)", GH_ParamAccess.item, false); 34 | } 35 | 36 | /// 37 | /// Registers all the output parameters for this component. 38 | /// 39 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 40 | { 41 | pManager.AddPlaneParameter("Planes", "Planes", "Z planes.", GH_ParamAccess.list); 42 | } 43 | 44 | /// 45 | /// This is the method that actually does the work. 46 | /// 47 | /// The DA object is used to retrieve from inputs and store in outputs. 48 | protected override void SolveInstance(IGH_DataAccess DA) 49 | { 50 | List SlicePlanes = new List(); 51 | 52 | GeometryBase Geometry = null; 53 | double LayerHeight = 0.2; 54 | double OffsetBottomGlobal = 0; 55 | double OffsetBottom = 0; 56 | double OffsetTop = 0; 57 | 58 | if (!DA.GetData(0, ref Geometry)) return; 59 | DA.GetData(1, ref LayerHeight); 60 | DA.GetData(2, ref OffsetBottomGlobal); 61 | DA.GetData(3, ref OffsetBottom); 62 | DA.GetData(4, ref OffsetTop); 63 | 64 | SlicePlanes = V2GRhinoGeometry.SlicePlanes(Geometry, LayerHeight, OffsetBottomGlobal, OffsetBottom, OffsetTop); 65 | 66 | DA.SetDataList(0, SlicePlanes); 67 | } 68 | 69 | /// 70 | /// Provides an Icon for the component. 71 | /// 72 | protected override System.Drawing.Bitmap Icon 73 | { 74 | get 75 | { 76 | //You can add image files to your project resources and access them like this: 77 | // return Resources.IconForThisComponent; 78 | return null; 79 | } 80 | } 81 | 82 | /// 83 | /// Gets the unique ID for this component. Do not change this ID after release. 84 | /// 85 | public override Guid ComponentGuid 86 | { 87 | get { return new Guid("{f3820b46-1ceb-4536-b1b4-5fbf4eae7bc8}"); } 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_VoxelPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore; 7 | using Voxel2GCodeCore.Geometry; 8 | using Voxel2GCodeCore.Utilities; 9 | // Monolith 10 | using MalachiteNet; 11 | using MonolithLib; 12 | using CGeometrica; 13 | using CSerializer; 14 | 15 | namespace Voxel2GCodeGH 16 | { 17 | public class V2GH_VoxelPoint : GH_Component 18 | { 19 | /// 20 | /// Initializes a new instance of the V2GVoxelPoint class. 21 | /// 22 | public V2GH_VoxelPoint() 23 | : base("Create VoxelPoint", "VoxelPoint", 24 | "VoxelPoint from a Monolith voxel field and a Point3d.", 25 | "V2G", "Voxel") 26 | { 27 | } 28 | 29 | /// 30 | /// Registers all the input parameters for this component. 31 | /// 32 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 33 | { 34 | pManager.AddGenericParameter("Voxel", "Voxel", "Monolith voxel field.", GH_ParamAccess.item); 35 | pManager.AddPointParameter("Point", "Point", "Point3d.", GH_ParamAccess.item); 36 | } 37 | 38 | /// 39 | /// Registers all the output parameters for this component. 40 | /// 41 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 42 | { 43 | pManager.AddGenericParameter("VoxelPoint", "VoxelPoint", "VoxelPoint with metadata of the Voxel field.", GH_ParamAccess.item); 44 | pManager.AddPointParameter("Position", "Position", "Position of the point.", GH_ParamAccess.item); 45 | pManager.AddNumberParameter("FieldValue", "FieldValue", "Value of the field at this point.", GH_ParamAccess.item); 46 | pManager.AddVectorParameter("ContourVector", "ContourVector", "Vector along iso-curves (projected to the z coordinate of the point).", GH_ParamAccess.item); 47 | pManager.AddVectorParameter("GradientVector", "GradientVector", "Vector along gradient curves (projected to the z coordinate of the point)s.", GH_ParamAccess.item); 48 | pManager.AddVectorParameter("ContourVector3d", "ContourVector3", "Vector3d along the gradient of the field.", GH_ParamAccess.item); 49 | } 50 | 51 | /// 52 | /// This is the method that actually does the work. 53 | /// 54 | /// The DA object is used to retrieve from inputs and store in outputs. 55 | protected override void SolveInstance(IGH_DataAccess DA) 56 | { 57 | VoxelImage VoxelImage = null; 58 | Point3d Point = new Point3d(); 59 | 60 | DA.GetData(0, ref VoxelImage); 61 | DA.GetData(1, ref Point); 62 | 63 | V2GVoxelPoint VoxelPoint = new V2GVoxelPoint(VoxelImage, V2GH.V2GPoint(Point)); 64 | 65 | DA.SetData(0, VoxelPoint); 66 | DA.SetData(1, V2GH.Point3d(VoxelPoint.Position)); 67 | DA.SetData(2, VoxelPoint.FieldValue); 68 | DA.SetData(3, V2GH.Vector3d(VoxelPoint.ContourVector)); 69 | DA.SetData(4, V2GH.Vector3d(VoxelPoint.GradientVector)); 70 | DA.SetData(5, V2GH.Vector3d(VoxelPoint.ContourVector3d)); 71 | } 72 | 73 | /// 74 | /// Provides an Icon for the component. 75 | /// 76 | protected override System.Drawing.Bitmap Icon 77 | { 78 | get 79 | { 80 | //You can add image files to your project resources and access them like this: 81 | // return Resources.IconForThisComponent; 82 | return null; 83 | } 84 | } 85 | 86 | /// 87 | /// Gets the unique ID for this component. Do not change this ID after release. 88 | /// 89 | public override Guid ComponentGuid 90 | { 91 | get { return new Guid("{9fbd4d7e-be65-427b-aecb-d97df9666184}"); } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_VoxelCurvePoints.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore; 7 | using Voxel2GCodeCore.Geometry; 8 | using Voxel2GCodeCore.Utilities; 9 | // Monolith 10 | using MalachiteNet; 11 | using MonolithLib; 12 | using CGeometrica; 13 | using CSerializer; 14 | 15 | namespace Voxel2GCodeGH 16 | { 17 | public class V2GH_VoxelCurvePoints : GH_Component 18 | { 19 | /// 20 | /// Initializes a new instance of the V2GVoxelCurvePoints class. 21 | /// 22 | public V2GH_VoxelCurvePoints() 23 | : base("Get Voxel Curve Points", "VoxelCurvePoints", 24 | "Get voxel gradient and contour curve points from a Monolith voxel field.", 25 | "V2G", "Voxel") 26 | { 27 | } 28 | 29 | /// 30 | /// Registers all the input parameters for this component. 31 | /// 32 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 33 | { 34 | pManager.AddGenericParameter("Voxel", "Voxel", "Monolith voxel field.", GH_ParamAccess.item); 35 | pManager.AddPointParameter("Point", "Point", "Point3d.", GH_ParamAccess.item, new Point3d(0,0,0)); 36 | pManager.AddIntegerParameter("Vector Type", "Vector Type", "(0) Contour vector projected to z plane (1) Gradient vector projected to z plane (2) 3D Gradient vector", GH_ParamAccess.item, 0); 37 | pManager.AddNumberParameter("Segment Length", "SegmentLength", "Length of each of the segments.", GH_ParamAccess.item, 0.0001); 38 | pManager.AddIntegerParameter("Iterations", "Iterations", "Maximum number of iterations to find an end point.", GH_ParamAccess.item, 10000); 39 | } 40 | 41 | /// 42 | /// Registers all the output parameters for this component. 43 | /// 44 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 45 | { 46 | pManager.AddCurveParameter("Polyline", "Polyline", "Field polyline.", GH_ParamAccess.item); 47 | } 48 | 49 | /// 50 | /// This is the method that actually does the work. 51 | /// 52 | /// The DA object is used to retrieve from inputs and store in outputs. 53 | protected override void SolveInstance(IGH_DataAccess DA) 54 | { 55 | VoxelImage VoxelImage = null; 56 | Point3d Point = new Point3d(); 57 | int VectorType = 0; 58 | double SegmentLength = 0.0001; 59 | int Iterations = 25000; 60 | 61 | if(!DA.GetData(0, ref VoxelImage)) return; 62 | DA.GetData(1, ref Point); 63 | DA.GetData(2, ref VectorType); 64 | DA.GetData(3, ref SegmentLength); 65 | DA.GetData(4, ref Iterations); 66 | 67 | List Points = V2GVoxel.VoxelCurvePoints(VoxelImage, V2GH.V2GPoint(Point), SegmentLength, Iterations, VectorType); 68 | List RhinoPoints = new List(); 69 | foreach(V2GPoint p in Points) 70 | { 71 | RhinoPoints.Add(new Point3d(p.X, p.Y, p.Z)); 72 | } 73 | Polyline Polyline = new Polyline(RhinoPoints); 74 | 75 | DA.SetData(0, Polyline); 76 | } 77 | 78 | /// 79 | /// Provides an Icon for the component. 80 | /// 81 | protected override System.Drawing.Bitmap Icon 82 | { 83 | get 84 | { 85 | //You can add image files to your project resources and access them like this: 86 | // return Resources.IconForThisComponent; 87 | return null; 88 | } 89 | } 90 | 91 | /// 92 | /// Gets the unique ID for this component. Do not change this ID after release. 93 | /// 94 | public override Guid ComponentGuid 95 | { 96 | get { return new Guid("{648cd942-f2e4-4085-9664-e662f83fedca}"); } 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Instructions/_PrintMovementOld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeCore.Instructions 9 | { 10 | 11 | /// 12 | /// A PrintInstruction subclass to move the tool-head without printing. 13 | /// 14 | 15 | public class PrintMovementOld : V2GInstruction 16 | { 17 | public V2GPrintPosition p; 18 | public double speed = 700.0; 19 | public double thickness; 20 | public double zDelta = 0.0; 21 | public double FilamentRetract = 0.0; // mm 22 | public double FilamentFeed = 0.0;//mm 23 | public bool IsRelative = false; 24 | public bool ForceFilamentOperations = false; 25 | 26 | public void SetRelativePoint(V2GState printer) 27 | { 28 | this.p = printer.Position + this.p; 29 | if (this.p.Z <= 0.0) this.p.Z = 0.05; 30 | } 31 | 32 | public override void GenerateGCode(StringBuilder s, V2GState printer) 33 | { 34 | double MovementLength = printer.Position.DistanceTo(printer.PrintPointOnBase(this.p)); 35 | 36 | if (MovementLength > 0.001) 37 | { 38 | if (this.IsRelative) 39 | { 40 | this.SetRelativePoint(printer); 41 | } 42 | 43 | if (printer.settings.IsVerbose) s.Append("\n(A. PrintMovement) (Printer has to move)"); 44 | 45 | printer.F = this.speed; 46 | 47 | // Filament retract 48 | if (this.FilamentRetract > 0.0 && (MovementLength > 2.0 || ForceFilamentOperations)) 49 | { 50 | printer.E += -this.FilamentRetract; 51 | s.Append("\nG1 E" + Math.Round(printer.E, 4)); 52 | } 53 | 54 | // Add zDelta 55 | if (zDelta != 0) 56 | { 57 | printer.Position.Z += zDelta; 58 | s.Append("\nG1 Z" + Math.Round(printer.Position.Z, 4)); if (printer.settings.IsVerbose) s.Append(" (B. PrintMovement) (move zDelta " + zDelta + ")"); 59 | } 60 | 61 | // Move 62 | // todo: rollback and forth 63 | printer.SetPosition(this.p + new V2GPrintPosition(0, 0, zDelta)); 64 | s.Append("\nG1"); 65 | s.Append(" X" + Math.Round(printer.Position.X, 4)); 66 | s.Append(" Y" + Math.Round(printer.Position.Y, 4)); 67 | s.Append(" Z" + Math.Round(printer.Position.Z, 4)); 68 | s.Append(" F" + Math.Round(printer.F, 4)); 69 | 70 | if (printer.settings.IsVerbose) s.Append(" (C. PrintMovement) (move towards point with zDelta " + zDelta + ")"); 71 | 72 | // Substract zDelta 73 | if (zDelta != 0) 74 | { 75 | printer.Position.Z -= zDelta; 76 | if (printer.Position.Z < 0) printer.Position.Z = 0.0; 77 | s.Append("\nG1 Z" + Math.Round(printer.Position.Z, 4)); 78 | //if (printer.IsVerbose) s.Append(" (D. PrintMovement) (move zDelta " + zDelta + ")"); 79 | } 80 | 81 | // Filament feed (while moving) 82 | 83 | if (this.FilamentFeed > 0.0 && (MovementLength > 2.0 || ForceFilamentOperations)) // todo: check if this makes PLA behavior worse (length restriction wasn't here, just testing for NinjaFlex not to go out of the extruder) 84 | { 85 | if (zDelta == 0) 86 | { 87 | s.Append("\nG1"); 88 | } 89 | printer.E += this.FilamentFeed; 90 | s.Append(" E" + Math.Round(printer.E, 4)); 91 | } 92 | } 93 | else 94 | { 95 | if (printer.settings.IsVerbose) s.Append("\n (A. PrintMovement) (Printer is already here)"); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Utilities; 7 | 8 | namespace Voxel2GCodeCore.Geometry 9 | { 10 | /// 11 | /// A generic point class. 12 | /// 13 | public struct V2GPoint 14 | { 15 | public double X, Y, Z; 16 | 17 | /// 18 | /// Create a Point from its XYZ coordinates. 19 | /// 20 | /// 21 | /// 22 | /// 23 | public V2GPoint(double x, double y, double z) 24 | { 25 | this.X = x; 26 | this.Y = y; 27 | this.Z = z; 28 | } 29 | 30 | /// 31 | /// Creates a shallow copy of the specified Point. 32 | /// 33 | /// 34 | public V2GPoint(V2GPoint p) 35 | { 36 | this.X = p.X; 37 | this.Y = p.Y; 38 | this.Z = p.Z; 39 | } 40 | 41 | /// 42 | /// Returns the distance of this PrintPoint to another. 43 | /// 44 | /// 45 | /// 46 | public double DistanceTo(V2GPoint p) 47 | { 48 | return Math.Sqrt( 49 | (this.X - p.X) * (this.X - p.X) + 50 | (this.Y - p.Y) * (this.Y - p.Y) + 51 | (this.Z - p.Z) * (this.Z - p.Z) 52 | ); 53 | } 54 | 55 | public static V2GPoint operator +(V2GPoint p1, V2GPoint p2) 56 | { 57 | return new V2GPoint(p1.X + p2.X, p1.Y + p2.Y, p1.Z + p2.Z); 58 | } 59 | 60 | public static V2GPoint operator -(V2GPoint p) 61 | { 62 | return new V2GPoint(-p.X, -p.Y, -p.Z); 63 | } 64 | 65 | public static V2GPoint operator -(V2GPoint p1, V2GPoint p2) 66 | { 67 | return new V2GPoint(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z); 68 | } 69 | 70 | public static V2GPoint operator *(Double s, V2GPoint p) 71 | { 72 | return new V2GPoint(s * p.X, s * p.Y, s * p.Z); 73 | } 74 | 75 | public static V2GPoint operator *(V2GPoint p, Double s) 76 | { 77 | return new V2GPoint(s * p.X, s * p.Y, s * p.Z); 78 | } 79 | 80 | /// 81 | /// Unit X Vector. 82 | /// 83 | public static V2GPoint XAxis = new V2GPoint(1, 0, 0); 84 | 85 | /// 86 | /// Unit Y Vector. 87 | /// 88 | public static V2GPoint YAxis = new V2GPoint(0, 1, 0); 89 | 90 | /// 91 | /// Unit Z Vector. 92 | /// 93 | public static V2GPoint ZAxis = new V2GPoint(0, 0, 1); 94 | 95 | /// 96 | /// Returns the length of this Vector. 97 | /// 98 | /// 99 | public double Length() 100 | { 101 | return Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); 102 | } 103 | 104 | /// 105 | /// Unitizes this Vector. Will return false if Vector is not unitizable 106 | /// (zero length Vector). 107 | /// 108 | /// 109 | public bool Normalize() 110 | { 111 | double len = this.Length(); 112 | if (len < V2GMath.EPSILON) return false; 113 | this.X /= len; 114 | this.Y /= len; 115 | this.Z /= len; 116 | return true; 117 | } 118 | 119 | /// 120 | /// Returns the Cross Product 121 | /// of specified Vectors (Points). 122 | /// 123 | /// 124 | /// 125 | /// 126 | public static V2GPoint CrossProduct(V2GPoint p1, V2GPoint p2) 127 | { 128 | return new V2GPoint( 129 | p1.Y * p2.Z - p1.Z * p2.Y, 130 | p1.Z * p2.X - p1.X * p2.Z, 131 | p1.X * p2.Y - p1.Y * p2.X); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Utilities/V2GGeometry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeCore.Utilities 9 | { 10 | public class V2GGeometry 11 | { 12 | public int value = 32; 13 | /// 14 | /// Sort curves on the shortest path. 15 | /// 16 | /// 17 | /// 18 | public static List SortCurves(List curvesToSort) 19 | { 20 | List sortedCurves = new List(); 21 | List curves = new List(); 22 | curves.AddRange(curvesToSort); 23 | 24 | // todo: first curve could be the furthest from the center 25 | // as of now it's the last curve of the list 26 | V2GCurve currentCurve = curves[curves.Count - 1]; 27 | curves.RemoveAt(curves.Count - 1); 28 | sortedCurves.Add(currentCurve); 29 | 30 | // find ouf next curve either startpoint or endpoint is closest to the end point of the current curve 31 | while (curves.Count != 0) 32 | { 33 | int bestI = 0; 34 | double bestDistance = double.MaxValue; 35 | V2GPoint currentPoint = currentCurve.EndPoint; 36 | for (int i = 0; i < curves.Count; ++i) 37 | { 38 | V2GCurve c = curves[i]; 39 | double d = Math.Min(currentPoint.DistanceTo(c.StartPoint), currentPoint.DistanceTo(c.EndPoint)); 40 | if (bestDistance > d) 41 | { 42 | bestI = i; 43 | bestDistance = d; 44 | } 45 | } 46 | currentCurve = curves[bestI]; 47 | curves.RemoveAt(bestI); 48 | if (currentPoint.DistanceTo(currentCurve.EndPoint) < currentPoint.DistanceTo(currentCurve.StartPoint)) 49 | { 50 | currentCurve.Reverse(); 51 | } 52 | sortedCurves.Add(currentCurve); 53 | } 54 | return sortedCurves; 55 | } 56 | 57 | /* 58 | /// 59 | /// Sort curves on the shortest path for 3D printing. 60 | /// 61 | /// 62 | /// 63 | public static List SortPrintableCurvesRhino(List _curves) 64 | { 65 | List sortedCurves = new List(); 66 | List curves = new List(); 67 | curves.AddRange(_curves); // Copying elements to curves to avoid modifying the original list of curves 68 | 69 | // todo: first curve could be the furthest from the center 70 | // now the last curve of the list 71 | Curve currentCurve = curves[curves.Count - 1]; 72 | curves.RemoveAt(curves.Count - 1); 73 | sortedCurves.Add(currentCurve); 74 | 75 | // find ouf next curve either startpoint or endpoint is closest to the end point of the current curve 76 | 77 | while (curves.Count != 0) 78 | { 79 | int bestI = 0; 80 | double bestDistance = double.MaxValue; 81 | Point3d currentPoint = currentCurve.PointAtEnd; 82 | for (int i = 0; i < curves.Count; ++i) 83 | { 84 | Curve c = curves[i]; 85 | double d = Math.Min(currentPoint.DistanceTo(c.PointAtStart), currentPoint.DistanceTo(c.PointAtEnd)); 86 | if (bestDistance > d) 87 | { 88 | bestI = i; 89 | bestDistance = d; 90 | } 91 | } 92 | 93 | currentCurve = curves[bestI]; 94 | curves.RemoveAt(bestI); 95 | if (currentPoint.DistanceTo(currentCurve.PointAtEnd) < currentPoint.DistanceTo(currentCurve.PointAtStart)) 96 | { 97 | currentCurve.Reverse(); 98 | } 99 | 100 | sortedCurves.Add(currentCurve); 101 | } 102 | return sortedCurves; 103 | }*/ 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_Printer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore.Geometry; 7 | using Voxel2GCodeCore; 8 | 9 | namespace Voxel2GCodeGH 10 | { 11 | public class V2GH_Printer : GH_Component 12 | { 13 | /// 14 | /// Initializes a new instance of the V2GPrinter class. 15 | /// 16 | public V2GH_Printer() 17 | : base("Construct Printer", "V2GPrinter", 18 | "Generates printable G-code from printable geometry objects.", 19 | "V2G", "G-code") 20 | { 21 | } 22 | 23 | /// 24 | /// Registers all the input parameters for this component. 25 | /// 26 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 27 | { 28 | pManager.AddGenericParameter("Printables", "Printables", 29 | "A set of printable geometries.", 30 | GH_ParamAccess.list); 31 | pManager.AddGenericParameter("Settings", "Settings", 32 | "Custom printing settings", 33 | GH_ParamAccess.item); 34 | //pManager.AddBooleanParameter("Verbose", "Verbose", 35 | // "Display G-code comments.", 36 | // GH_ParamAccess.item, false); 37 | } 38 | 39 | /// 40 | /// Registers all the output parameters for this component. 41 | /// 42 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 43 | { 44 | pManager.AddTextParameter("GCode", "GCode", "Generated printable GCode.", GH_ParamAccess.item); 45 | } 46 | 47 | /// 48 | /// This is the method that actually does the work. 49 | /// 50 | /// The DA object is used to retrieve from inputs and store in outputs. 51 | protected override void SolveInstance(IGH_DataAccess DA) 52 | { 53 | // Variables 54 | List printables = new List(); 55 | V2GSettings settings = new V2GSettings(); 56 | 57 | // Get Data 58 | DA.GetDataList(0, printables); 59 | DA.GetData(1, ref settings); 60 | //if (!DA.GetData(1, ref settings)) 61 | //{ 62 | // settings = new V2GSettings(); 63 | // } 64 | 65 | // Stuff 66 | System.Text.StringBuilder sb = new System.Text.StringBuilder(); 67 | 68 | // Create Printer and adjust settings 69 | V2GState printer = new V2GState(); 70 | printer.SetSettings(settings); 71 | 72 | // Create Model 73 | V2GModel model = new V2GModel(); 74 | 75 | // Append PrintPolylines 76 | foreach (V2GPrintable printable in printables) 77 | { 78 | if(printable is V2GPrintPolyline) 79 | { 80 | model.AppendAsPath(printable as Voxel2GCodeCore.Geometry.V2GPrintPolyline); 81 | } else if (printable is V2GPrintPosition) 82 | { 83 | /// TODO: implement model.AppendAsPath(V2GPrintPosition position) { } 84 | } 85 | } 86 | 87 | model.AppendAsRelativeMovement(new V2GPrintPosition(0, 0, 10.0), 0, 7200); 88 | 89 | // Generate GCode 90 | model.GenerateGCode(sb, printer); 91 | 92 | // Set Data 93 | DA.SetData(0, sb.ToString()); 94 | } 95 | 96 | /// 97 | /// Provides an Icon for the component. 98 | /// 99 | protected override System.Drawing.Bitmap Icon 100 | { 101 | get 102 | { 103 | //You can add image files to your project resources and access them like this: 104 | // return Resources.IconForThisComponent; 105 | return null; 106 | } 107 | } 108 | 109 | /// 110 | /// Gets the unique ID for this component. Do not change this ID after release. 111 | /// 112 | public override Guid ComponentGuid 113 | { 114 | get { return new Guid("{e12a17be-2812-4a4e-8d58-9dcbc2dce6f4}"); } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /src/Voxel2GCode.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel2GCodeCore", "Voxel2GCodeCore\Voxel2GCodeCore.csproj", "{BCB34B54-0384-47A9-98E1-E4F43F520023}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel2GCodeDesignScript", "Voxel2GCodeDesignScript\Voxel2GCodeDesignScript.csproj", "{9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel2GCodeDynamo", "Voxel2GCodeDynamo\Voxel2GCodeDynamo.csproj", "{CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel2GCodeGH", "Voxel2GCodeGH\Voxel2GCodeGH.csproj", "{6F0508DE-90BE-4134-B69A-1BB68E925F36}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel2GCodeRhinoCommon", "Voxel2GCodeRhinoCommon\Voxel2GCodeRhinoCommon.csproj", "{3F73C724-8A83-47C7-AE44-1BAF6CFD2147}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Debug32|Any CPU = Debug32|Any CPU 20 | Debug64|Any CPU = Debug64|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Debug32|Any CPU.ActiveCfg = Debug|Any CPU 27 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Debug32|Any CPU.Build.0 = Debug|Any CPU 28 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Debug64|Any CPU.ActiveCfg = Debug|Any CPU 29 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Debug64|Any CPU.Build.0 = Debug|Any CPU 30 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {BCB34B54-0384-47A9-98E1-E4F43F520023}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Debug32|Any CPU.ActiveCfg = Debug|Any CPU 35 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Debug32|Any CPU.Build.0 = Debug|Any CPU 36 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Debug64|Any CPU.ActiveCfg = Debug|Any CPU 37 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Debug64|Any CPU.Build.0 = Debug|Any CPU 38 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {9C56FD2E-E684-45F2-A424-BF8FB5C20D8E}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Debug32|Any CPU.ActiveCfg = Debug|Any CPU 43 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Debug32|Any CPU.Build.0 = Debug|Any CPU 44 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Debug64|Any CPU.ActiveCfg = Debug|Any CPU 45 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Debug64|Any CPU.Build.0 = Debug|Any CPU 46 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug|Any CPU.ActiveCfg = Debug64|Any CPU 49 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug|Any CPU.Build.0 = Debug64|Any CPU 50 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug32|Any CPU.ActiveCfg = Debug32|Any CPU 51 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug32|Any CPU.Build.0 = Debug32|Any CPU 52 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug64|Any CPU.ActiveCfg = Debug64|Any CPU 53 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Debug64|Any CPU.Build.0 = Debug64|Any CPU 54 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {6F0508DE-90BE-4134-B69A-1BB68E925F36}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Debug32|Any CPU.ActiveCfg = Debug|Any CPU 59 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Debug32|Any CPU.Build.0 = Debug|Any CPU 60 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Debug64|Any CPU.ActiveCfg = Debug|Any CPU 61 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Debug64|Any CPU.Build.0 = Debug|Any CPU 62 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {3F73C724-8A83-47C7-AE44-1BAF6CFD2147}.Release|Any CPU.Build.0 = Release|Any CPU 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_PrintPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeGH 9 | { 10 | public class V2GH_PrintPoint : GH_Component 11 | { 12 | /// 13 | /// Initializes a new instance of the V2GPrintPoint class. 14 | /// 15 | public V2GH_PrintPoint() 16 | : base("Construct PrintPoint", "PrintPoint", 17 | "Construct a PrintPoint from a Point3d.", 18 | "V2G", "G-code") 19 | { 20 | } 21 | 22 | /// 23 | /// Registers all the input parameters for this component. 24 | /// 25 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 26 | { 27 | pManager.AddPointParameter("Point", "Point", 28 | "Point to define a printable segment.", 29 | GH_ParamAccess.list); 30 | pManager.AddNumberParameter("Material per mm", "Material per mm", 31 | "Amount of filament to extrude per linear mm, i.e. E value, spread between E and A if using dual extruder.", 32 | GH_ParamAccess.list, 0.033); 33 | pManager.AddNumberParameter("Speed", "Speed", 34 | "Feedrate at which extrude the material.", 35 | GH_ParamAccess.list, 700.0); 36 | pManager.AddIntegerParameter("Tool-head", "Tool-head", 37 | "Number of the corresponding tool-head to use, e.g. T0 (left extruder), T1 (right extruder), T3 (dual pro extruder mix), etc.", 38 | GH_ParamAccess.list, 0); 39 | pManager.AddNumberParameter("Mix Percetage", "Mix Percentage", 40 | "Amount of secondary material to mix with dual extruder, i.e. 0 for 100%-0%, 0.5 for 50%-50% 1.0 for 0%-100%).", 41 | GH_ParamAccess.list, 0); 42 | } 43 | 44 | /// 45 | /// Registers all the output parameters for this component. 46 | /// 47 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 48 | { 49 | pManager.AddGenericParameter("PrintPoint", "PrintPoint", "Printable point wrapper.", GH_ParamAccess.list); 50 | } 51 | 52 | /// 53 | /// This is the method that actually does the work. 54 | /// 55 | /// The DA object is used to retrieve from inputs and store in outputs. 56 | protected override void SolveInstance(IGH_DataAccess DA) 57 | { 58 | List PrintPoints = new List(); 59 | List InputPoints = new List(); 60 | List MaterialAmount = new List(); 61 | List Speed = new List(); 62 | List Toolhead = new List(); 63 | List MixPercentage = new List(); 64 | 65 | if (!DA.GetDataList(0, InputPoints)) return; 66 | if (!DA.GetDataList(1, MaterialAmount)) return; 67 | if (!DA.GetDataList(2, Speed)) return; 68 | if (!DA.GetDataList(3, Toolhead)) return; 69 | if (!DA.GetDataList(4, MixPercentage)) return; 70 | 71 | int idx = 0; 72 | double _Speed = Speed[0]; 73 | double _MaterialAmount = MaterialAmount[0]; 74 | int _Head = Toolhead[0]; 75 | double _MixPercentage = MixPercentage[0]; 76 | foreach (Point3d p in InputPoints) 77 | { 78 | if (Speed.Count - 1 >= idx) _Speed = Speed[idx]; 79 | if (MaterialAmount.Count - 1 >= idx) _MaterialAmount = MaterialAmount[idx]; 80 | if (Toolhead.Count - 1 >= idx) _Head = Toolhead[idx]; 81 | if (MixPercentage.Count - 1 >= idx) _MixPercentage = MixPercentage[idx]; 82 | 83 | V2GPrintPosition position = new V2GPrintPosition(V2GH.V2GPoint(p), _Speed, _MaterialAmount, _Head, _MixPercentage); 84 | PrintPoints.Add(new V2GPrintPosition(p.X, p.Y, p.Z)); 85 | idx++; 86 | } 87 | 88 | DA.SetDataList(0, PrintPoints); 89 | } 90 | 91 | /// 92 | /// Provides an Icon for the component. 93 | /// 94 | protected override System.Drawing.Bitmap Icon 95 | { 96 | get 97 | { 98 | //You can add image files to your project resources and access them like this: 99 | // return Resources.IconForThisComponent; 100 | return null; 101 | } 102 | } 103 | 104 | /// 105 | /// Gets the unique ID for this component. Do not change this ID after release. 106 | /// 107 | public override Guid ComponentGuid 108 | { 109 | get { return new Guid("{ebdbafc2-c9a3-4a0c-aa74-dfb137eb007f}"); } 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Voxel2GCodeCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BCB34B54-0384-47A9-98E1-E4F43F520023} 8 | Library 9 | Properties 10 | Voxel2GCodeCore 11 | Voxel2GCodeCore 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\Voxel2GCodeCore.xml 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\CGeometrica.dll 39 | 40 | 41 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\CSerializer.dll 42 | 43 | 44 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MalachiteNet.dll 45 | 46 | 47 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MonolithCore.dll 48 | 49 | 50 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MonolithLib.dll 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | True 87 | True 88 | Settings.settings 89 | 90 | 91 | 92 | 93 | SettingsSingleFileGenerator 94 | Settings.Designer.cs 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | 3 | ## Ignore Visual Studio temporary files, build results, and 4 | ## files generated by popular Visual Studio add-ons. 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # DNX 46 | project.lock.json 47 | artifacts/ 48 | 49 | *_i.c 50 | *_p.c 51 | *_i.h 52 | *.ilk 53 | *.meta 54 | *.obj 55 | *.pch 56 | *.pdb 57 | *.pgc 58 | *.pgd 59 | *.rsp 60 | *.sbr 61 | *.tlb 62 | *.tli 63 | *.tlh 64 | *.tmp 65 | *.tmp_proj 66 | *.log 67 | *.vspscc 68 | *.vssscc 69 | .builds 70 | *.pidb 71 | *.svclog 72 | *.scc 73 | 74 | # Chutzpah Test files 75 | _Chutzpah* 76 | 77 | # Visual C++ cache files 78 | ipch/ 79 | *.aps 80 | *.ncb 81 | *.opendb 82 | *.opensdf 83 | *.sdf 84 | *.cachefile 85 | *.VC.db 86 | *.VC.VC.opendb 87 | 88 | # Visual Studio profiler 89 | *.psess 90 | *.vsp 91 | *.vspx 92 | *.sap 93 | 94 | # TFS 2012 Local Workspace 95 | $tf/ 96 | 97 | # Guidance Automation Toolkit 98 | *.gpState 99 | 100 | # ReSharper is a .NET coding add-in 101 | _ReSharper*/ 102 | *.[Rr]e[Ss]harper 103 | *.DotSettings.user 104 | 105 | # JustCode is a .NET coding add-in 106 | .JustCode 107 | 108 | # TeamCity is a build add-in 109 | _TeamCity* 110 | 111 | # DotCover is a Code Coverage Tool 112 | *.dotCover 113 | 114 | # NCrunch 115 | _NCrunch_* 116 | .*crunch*.local.xml 117 | nCrunchTemp_* 118 | 119 | # MightyMoose 120 | *.mm.* 121 | AutoTest.Net/ 122 | 123 | # Web workbench (sass) 124 | .sass-cache/ 125 | 126 | # Installshield output folder 127 | [Ee]xpress/ 128 | 129 | # DocProject is a documentation generator add-in 130 | DocProject/buildhelp/ 131 | DocProject/Help/*.HxT 132 | DocProject/Help/*.HxC 133 | DocProject/Help/*.hhc 134 | DocProject/Help/*.hhk 135 | DocProject/Help/*.hhp 136 | DocProject/Help/Html2 137 | DocProject/Help/html 138 | 139 | # Click-Once directory 140 | publish/ 141 | 142 | # Publish Web Output 143 | *.[Pp]ublish.xml 144 | *.azurePubxml 145 | # TODO: Comment the next line if you want to checkin your web deploy settings 146 | # but database connection strings (with potential passwords) will be unencrypted 147 | *.pubxml 148 | *.publishproj 149 | 150 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 151 | # checkin your Azure Web App publish settings, but sensitive information contained 152 | # in these scripts will be unencrypted 153 | PublishScripts/ 154 | 155 | # NuGet Packages 156 | *.nupkg 157 | # The packages folder can be ignored because of Package Restore 158 | **/packages/* 159 | # except build/, which is used as an MSBuild target. 160 | !**/packages/build/ 161 | # Uncomment if necessary however generally it will be regenerated when needed 162 | #!**/packages/repositories.config 163 | # NuGet v3's project.json files produces more ignoreable files 164 | *.nuget.props 165 | *.nuget.targets 166 | 167 | # Microsoft Azure Build Output 168 | csx/ 169 | *.build.csdef 170 | 171 | # Microsoft Azure Emulator 172 | ecf/ 173 | rcf/ 174 | 175 | # Windows Store app package directories and files 176 | AppPackages/ 177 | BundleArtifacts/ 178 | Package.StoreAssociation.xml 179 | _pkginfo.txt 180 | 181 | # Visual Studio cache files 182 | # files ending in .cache can be ignored 183 | *.[Cc]ache 184 | # but keep track of directories ending in .cache 185 | !*.[Cc]ache/ 186 | 187 | # Others 188 | ClientBin/ 189 | ~$* 190 | *~ 191 | *.dbmdl 192 | *.dbproj.schemaview 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_BoundingFrames.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Voxel2GCodeCore.Utilities; 6 | using Voxel2GCodeRhino.Utilities; 7 | using Rhino.Geometry; 8 | 9 | namespace Voxel2GCodeGH 10 | { 11 | public class V2GH_BoundingFrames : GH_Component 12 | { 13 | // TODO: Fix glitches at some parameters 14 | 15 | /// 16 | /// Initializes a new instance of the V2GUtilBoundingFrames class. 17 | /// 18 | public V2GH_BoundingFrames() 19 | : base("Get Bounding Frames", "BoundingFrames", 20 | "Get a set of bounding frames for a given geometry.", 21 | "V2G", "Slicer") 22 | { 23 | } 24 | 25 | /// 26 | /// Registers all the input parameters for this component. 27 | /// 28 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 29 | { 30 | pManager.AddGeometryParameter("Geometry", "Geometry", "Geometry to extract frames from.", GH_ParamAccess.item); 31 | pManager.AddNumberParameter("X Span", "X Span", "Span between x-axis frames.", GH_ParamAccess.item, 0.2); 32 | pManager.AddNumberParameter("Y Span", "Y Span", "Span between y-axis frames.", GH_ParamAccess.item, 0.2); 33 | pManager.AddNumberParameter("Z Span", "Z Span", "Span between z-axis frames.", GH_ParamAccess.item, 0.2); 34 | pManager.AddNumberParameter("DX Span", "DX Span", "Span between diagonal-x-axis frames.", GH_ParamAccess.item, 0.2); 35 | pManager.AddNumberParameter("DY Span", "DY Span", "Span between diagonal-y-axis frames.", GH_ParamAccess.item, 0.2); 36 | pManager.AddNumberParameter("Diagonal Angle", "Angle", "Angle of rotation of diagonal frames.", GH_ParamAccess.item, 45.0); 37 | } 38 | 39 | /// 40 | /// Registers all the output parameters for this component. 41 | /// 42 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 43 | { 44 | pManager.AddPlaneParameter("X Frames", "X Frames", "Frames on the x-axis.", GH_ParamAccess.list); 45 | pManager.AddPlaneParameter("Y Frames", "Y Frames", "Frames on the y-axis.", GH_ParamAccess.list); 46 | pManager.AddPlaneParameter("Z Frames", "Z Frames", "Frames on the z-axis.", GH_ParamAccess.list); 47 | pManager.AddPlaneParameter("DX Frames", "DX Frames", "Frames on the diagonal-x-axis.", GH_ParamAccess.list); 48 | pManager.AddPlaneParameter("DY Frames", "DY Frames", "Frames on the diagonal-y-axis.", GH_ParamAccess.list); 49 | pManager.AddGenericParameter("Frames", "Frames", "Lists containing all frames.", GH_ParamAccess.list); 50 | } 51 | 52 | /// 53 | /// This is the method that actually does the work. 54 | /// 55 | /// The DA object is used to retrieve from inputs and store in outputs. 56 | protected override void SolveInstance(IGH_DataAccess DA) 57 | { 58 | GeometryBase Geometry = null; 59 | double XSpan = 0.2; 60 | double YSpan = 0.2; 61 | double ZSpan = 0.2; 62 | double DXSpan = 0.2; 63 | double DYSpan = 0.2; 64 | double Angle = 45.0; 65 | double minSpan = 0.0001; 66 | if(!DA.GetData(0, ref Geometry)) return; 67 | DA.GetData(1, ref XSpan); 68 | DA.GetData(2, ref YSpan); 69 | DA.GetData(3, ref ZSpan); 70 | DA.GetData(4, ref DXSpan); 71 | DA.GetData(5, ref DYSpan); 72 | DA.GetData(6, ref Angle); 73 | 74 | if (XSpan < minSpan) XSpan = minSpan; 75 | if (YSpan < minSpan) YSpan = minSpan; 76 | if (ZSpan < minSpan) ZSpan = minSpan; 77 | if (DXSpan < minSpan) DXSpan = minSpan; 78 | if (DXSpan < minSpan) DXSpan = minSpan; 79 | 80 | List> Frames = V2GRhinoGeometry.BoundingFrames( 81 | Geometry, 82 | XSpan, 83 | YSpan, 84 | ZSpan, 85 | DXSpan, 86 | DYSpan, 87 | Angle// Optional 88 | ); 89 | 90 | DA.SetDataList(0, Frames[0]); 91 | DA.SetDataList(1, Frames[1]); 92 | DA.SetDataList(2, Frames[2]); 93 | DA.SetDataList(3, Frames[3]); 94 | DA.SetDataList(4, Frames[4]); 95 | DA.SetDataList(5, Frames); 96 | } 97 | 98 | /// 99 | /// Provides an Icon for the component. 100 | /// 101 | protected override System.Drawing.Bitmap Icon 102 | { 103 | get 104 | { 105 | //You can add image files to your project resources and access them like this: 106 | // return Resources.IconForThisComponent; 107 | return null; 108 | } 109 | } 110 | 111 | /// 112 | /// Gets the unique ID for this component. Do not change this ID after release. 113 | /// 114 | public override Guid ComponentGuid 115 | { 116 | get { return new Guid("{0a39c99b-02ca-418b-b22b-f6a0c2f0d69e}"); } 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_PrintPolylineData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeGH 9 | { 10 | public class V2GH_PrintPolylineData : GH_Component 11 | { 12 | /// 13 | /// Initializes a new instance of the V2GPrintPolylineData class. 14 | /// 15 | public V2GH_PrintPolylineData() 16 | : base("Extract PrintPolyline Data", "PrintPolylineData", 17 | "Extract the metadata of a PrintPolyline.", 18 | "V2G", "G-code") 19 | { 20 | } 21 | 22 | /// 23 | /// Registers all the input parameters for this component. 24 | /// 25 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 26 | { 27 | pManager.AddGenericParameter("PrintPolyline", "PrintPolyline", "PrintPolyine(s) to extract data from.", GH_ParamAccess.list); 28 | } 29 | 30 | /// 31 | /// Registers all the output parameters for this component. 32 | /// 33 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 34 | { 35 | pManager.AddCurveParameter("Polyline", "Polyline", 36 | "Polyline contained inside the PrintPolyline.", 37 | GH_ParamAccess.list); 38 | pManager.AddPointParameter("Positions", "Positions", 39 | "List of print positions for each of the printable polylines.", 40 | GH_ParamAccess.list); 41 | pManager.AddNumberParameter("Material per mm", "Material per mm", 42 | "Amount of filament to extrude per linear mm, i.e. E value, spread between E and A if using dual extruder.", 43 | GH_ParamAccess.list); 44 | pManager.AddNumberParameter("Speed", "Speed", 45 | "Feedrate at which extrude the material.", 46 | GH_ParamAccess.list); 47 | pManager.AddIntegerParameter("Tool-head", "Tool-head", 48 | "Number of the corresponding tool-head to use, e.g. T0 (left extruder), T1 (right extruder), T3 (dual pro extruder mix), etc.", 49 | GH_ParamAccess.list); 50 | pManager.AddNumberParameter("Mix Percetage", "Mix Percentage", 51 | "Amount of secondary material to mix with dual extruder, i.e. 0 for 100%-0%, 0.5 for 50%-50% 1.0 for 0%-100%).", 52 | GH_ParamAccess.list); 53 | } 54 | 55 | /// 56 | /// This is the method that actually does the work. 57 | /// 58 | /// The DA object is used to retrieve from inputs and store in outputs. 59 | protected override void SolveInstance(IGH_DataAccess DA) 60 | { 61 | List printPolylines = new List(); 62 | List> Points = new List>(); 63 | 64 | List RhinoPolyline = new List(); 65 | List RhinoPositions = new List(); 66 | List MaterialAmount = new List(); 67 | List Speed = new List(); 68 | List Head = new List(); 69 | List MixPercentage = new List(); 70 | 71 | if (!DA.GetDataList(0, printPolylines)) return; 72 | 73 | foreach(V2GPrintPolyline ppl in printPolylines) 74 | { 75 | Points.Add(ppl.PrintPositions); 76 | List RhinoPoints = new List(); 77 | foreach (V2GPrintPosition PrintPosition in ppl.PrintPositions) 78 | { 79 | Speed.Add(PrintPosition.Speed); 80 | MaterialAmount.Add(PrintPosition.MaterialAmount); 81 | Head.Add(PrintPosition.Head); 82 | MixPercentage.Add(PrintPosition.MixPercentage); 83 | RhinoPoints.Add(V2GH.Point3d(PrintPosition.Position)); 84 | } 85 | RhinoPolyline.Add(new Rhino.Geometry.Polyline(RhinoPoints)); 86 | // TODO: Create a GH_Tree with points 87 | RhinoPositions.AddRange(RhinoPoints); 88 | } 89 | 90 | DA.SetDataList(0, RhinoPolyline); 91 | DA.SetDataList(1, RhinoPositions); 92 | DA.SetDataList(2, MaterialAmount); 93 | DA.SetDataList(3, Speed); 94 | DA.SetDataList(4, Head); 95 | DA.SetDataList(5, MixPercentage); 96 | } 97 | 98 | /// 99 | /// Provides an Icon for the component. 100 | /// 101 | protected override System.Drawing.Bitmap Icon 102 | { 103 | get 104 | { 105 | //You can add image files to your project resources and access them like this: 106 | // return Resources.IconForThisComponent; 107 | return null; 108 | } 109 | } 110 | 111 | /// 112 | /// Gets the unique ID for this component. Do not change this ID after release. 113 | /// 114 | public override Guid ComponentGuid 115 | { 116 | get { return new Guid("{064f93d7-f1b5-453a-bb59-ecc89ad56613}"); } 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeDynamo/Voxel2GCodeDynamo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CDDAC5A1-7E66-42FF-B012-B5095B1B1AC2} 8 | Library 9 | Properties 10 | Voxel2GCodeDynamo 11 | Voxel2GCode for Dynamo 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\Voxel2GCode for Dynamo.xml 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | bin\Release\Voxel2GCode for Dynamo.xml 34 | 35 | 36 | 37 | False 38 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\CGeometrica.dll 39 | 40 | 41 | False 42 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\CSerializer.dll 43 | 44 | 45 | ..\packages\DynamoVisualProgramming.DynamoServices.1.2.0\lib\net45\DynamoServices.dll 46 | True 47 | 48 | 49 | ..\packages\DynamoVisualProgramming.ZeroTouchLibrary.1.2.0\lib\net45\DynamoUnits.dll 50 | True 51 | 52 | 53 | False 54 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MalachiteNet.dll 55 | 56 | 57 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MonolithCore.dll 58 | 59 | 60 | False 61 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MonolithLib.dll 62 | 63 | 64 | ..\packages\DynamoVisualProgramming.ZeroTouchLibrary.1.2.0\lib\net45\ProtoGeometry.dll 65 | True 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | {bcb34b54-0384-47a9-98e1-e4f43f520023} 86 | Voxel2GCodeCore 87 | 88 | 89 | {9c56fd2e-e684-45f2-a424-bf8fb5c20d8e} 90 | Voxel2GCodeDesignScript 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_PrintSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore; 7 | using Voxel2GCodeCore.Geometry; 8 | 9 | namespace Voxel2GCodeGH 10 | { 11 | public class V2GH_PrintSettings : GH_Component 12 | { 13 | /// 14 | /// Initializes a new instance of the V2GH_PrintSettings class. 15 | /// 16 | public V2GH_PrintSettings() 17 | : base("Construct Printer Settings", "V2GSettings", 18 | "Create custom printing settings for a V2GPrinter", 19 | "V2G", "G-code") 20 | { 21 | } 22 | 23 | /// 24 | /// Registers all the input parameters for this component. 25 | /// 26 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 27 | { 28 | /* 29 | /// (true by default) 30 | /// (true by default) 31 | /// (true by default) 32 | /// (true by default) 33 | /// (true by default) 34 | /// (true by default) 35 | /// (true by default) 36 | /// (true by default) 37 | /// Printing settings.*/ 38 | 39 | pManager.AddPointParameter("StartPoint", "StartPoint", 40 | "Start point for the print job.", 41 | GH_ParamAccess.item, new Point3d(25,25,0)); 42 | pManager.AddPointParameter("EndPoint", "EndPoint", 43 | "End point for the print job.", 44 | GH_ParamAccess.item, new Point3d(25,25,0)); 45 | pManager.AddBooleanParameter("ShouldHeatUpOnStart", "ShouldHeatUpOnStart", 46 | "Determine if the printer should heat up at the beginning of the print.", 47 | GH_ParamAccess.item, true); 48 | pManager.AddBooleanParameter("ShouldCoolDownOnEnd", "ShouldCoolDownOnEnd", 49 | "Determine if the printer should cool down at the end of the print.", 50 | GH_ParamAccess.item, true); 51 | pManager.AddNumberParameter("ZOffset", "ZOffset", 52 | "Offset from the bed to the extrusion in mm.", 53 | GH_ParamAccess.item, 0.2); 54 | pManager.AddNumberParameter("BedTemperature", "BedTemperature", 55 | "Temperature of the heated bed (if your printer has one) in celsius degrees.", 56 | GH_ParamAccess.item, 60.0); 57 | pManager.AddNumberParameter("T0Temperature", "T0Temperature", 58 | "Temperature of the primary extruder head in celsius degrees.", 59 | GH_ParamAccess.item, 200.0); 60 | pManager.AddNumberParameter("T1Temperature", "T1Temperature", 61 | "Temperature of the secondary extruder head in celsius degrees.", 62 | GH_ParamAccess.item, 200.0); 63 | pManager.AddBooleanParameter("Verbose", "Verbose", 64 | "Generate G-code with inline comments.", 65 | GH_ParamAccess.item, false); 66 | 67 | } 68 | 69 | /// 70 | /// Registers all the output parameters for this component. 71 | /// 72 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 73 | { 74 | pManager.AddGenericParameter("Settings", "Settings", 75 | "Custom print settings for a V2GPrinter.", 76 | GH_ParamAccess.item); 77 | } 78 | 79 | /// 80 | /// This is the method that actually does the work. 81 | /// 82 | /// The DA object is used to retrieve from inputs and store in outputs. 83 | protected override void SolveInstance(IGH_DataAccess DA) 84 | { 85 | Point3d StartPoint = new Point3d(); 86 | Point3d EndPoint = new Point3d(); 87 | bool ShouldHeatUpOnStart = false; 88 | bool ShouldCoolDownOnEnd = false; 89 | double ZOffset = 0.2; 90 | double BedTemperature = 60.0; 91 | double T0Temperature = 200.0; 92 | double T1Temperature = 200.0; 93 | bool IsVerbose = false; 94 | 95 | DA.GetData(0, ref StartPoint); 96 | DA.GetData(1, ref EndPoint); 97 | DA.GetData(2, ref ShouldHeatUpOnStart); 98 | DA.GetData(3, ref ShouldCoolDownOnEnd); 99 | DA.GetData(4, ref ZOffset); 100 | DA.GetData(5, ref BedTemperature); 101 | DA.GetData(6, ref T0Temperature); 102 | DA.GetData(7, ref T1Temperature); 103 | DA.GetData(8, ref IsVerbose); 104 | 105 | V2GSettings settings = new V2GSettings(); 106 | settings.StartPoint = new V2GPrintPosition(V2GH.V2GPoint(StartPoint)); 107 | settings.EndPoint = new V2GPrintPosition(V2GH.V2GPoint(EndPoint)); 108 | settings.ShouldHeatUpOnStart = ShouldHeatUpOnStart; 109 | settings.ShouldCoolDownOnEnd = ShouldCoolDownOnEnd; 110 | settings.ZOffset = ZOffset; 111 | settings.BedTemperature = BedTemperature; 112 | settings.T0Temperature = T0Temperature; 113 | settings.T1Temperature = T1Temperature; 114 | settings.IsVerbose = IsVerbose; 115 | 116 | DA.SetData(0, settings); 117 | } 118 | 119 | /// 120 | /// Provides an Icon for the component. 121 | /// 122 | protected override System.Drawing.Bitmap Icon 123 | { 124 | get 125 | { 126 | //You can add image files to your project resources and access them like this: 127 | // return Resources.IconForThisComponent; 128 | return null; 129 | } 130 | } 131 | 132 | /// 133 | /// Gets the unique ID for this component. Do not change this ID after release. 134 | /// 135 | public override Guid ComponentGuid 136 | { 137 | get { return new Guid("{b78c03ff-9442-4acf-9c34-30460cbe7ade}"); } 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Geometry/V2GPrintPosition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Voxel2GCodeCore.Geometry 8 | { 9 | /// 10 | /// This struct holds a printable point 11 | /// 12 | public class V2GPrintPosition : V2GPrintable 13 | { 14 | /// 15 | /// Position to print toward. 16 | /// 17 | public V2GPoint Position; 18 | /// 19 | /// Default feed rate to move and extrude, i.e. velocity in mm/min. 20 | /// 21 | public double Speed = 700.0; 22 | /// 23 | /// Default amount of material to be fed per mm. (If using a dual extruder, the material distributes among using the MixPercentage value.) 24 | /// 25 | public double MaterialAmount = 0.033; 26 | /// 27 | /// Extruder-head to be used to print this. (e.g. T0 for left extruder, T1 for right extruder, T3 for dual extruder, etc.) This values vary from printer to printer. 28 | /// 29 | public int Head = 1; 30 | /// 31 | /// Percentage of material to extrude with the secondary extruder. 32 | /// 33 | public double MixPercentage = 0.0; 34 | /// 35 | /// Create a point from XYZ coordinates. 36 | /// 37 | /// 38 | /// 39 | /// 40 | public V2GPrintPosition(double x, double y, double z) 41 | { 42 | this.X = x; 43 | this.Y = y; 44 | this.Z = z; 45 | } 46 | 47 | /// 48 | /// 49 | /// 50 | /// 51 | public V2GPrintPosition(V2GPoint position) 52 | { 53 | this.X = position.X; 54 | this.Y = position.Y; 55 | this.Z = position.Z; 56 | } 57 | 58 | /// 59 | /// 60 | /// 61 | /// 62 | /// 63 | /// 64 | /// 65 | /// 66 | public V2GPrintPosition(V2GPoint position, double speed, double materialAmount, int head, double mixPercentage) 67 | { 68 | this.Position = position; 69 | this.Speed = speed; 70 | this.MaterialAmount = materialAmount; 71 | this.Head = head; 72 | this.MixPercentage = mixPercentage; 73 | } 74 | 75 | public double X 76 | { 77 | get { return Position.X; } 78 | set { Position.X = value; } 79 | } 80 | 81 | public double Y 82 | { 83 | get { return Position.Y; } 84 | set { Position.Y = value; } 85 | } 86 | 87 | public double Z 88 | { 89 | get { return Position.Z; } 90 | set { Position.Z = value; } 91 | } 92 | 93 | /// 94 | /// Returns the distance of this PrintPoint to another. 95 | /// 96 | /// 97 | /// 98 | public double DistanceTo(V2GPrintPosition p) 99 | { 100 | return Math.Sqrt( 101 | (this.X - p.X) * (this.X - p.X) + 102 | (this.Y - p.Y) * (this.Y - p.Y) + 103 | (this.Z - p.Z) * (this.Z - p.Z) 104 | ); 105 | } 106 | 107 | public static V2GPrintPosition operator +(V2GPrintPosition p1, V2GPrintPosition p2) 108 | { 109 | return new V2GPrintPosition(p1.X + p2.X, p1.Y + p2.Y, p1.Z + p2.Z); 110 | } 111 | 112 | public static V2GPrintPosition operator -(V2GPrintPosition p) 113 | { 114 | return new V2GPrintPosition(-p.X, -p.Y, -p.Z); 115 | } 116 | 117 | public static V2GPrintPosition operator -(V2GPrintPosition p1, V2GPrintPosition p2) 118 | { 119 | return new V2GPrintPosition(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z); 120 | } 121 | 122 | public static V2GPrintPosition operator *(Double s, V2GPrintPosition p) 123 | { 124 | return new V2GPrintPosition(s * p.X, s * p.Y, s * p.Z); 125 | } 126 | 127 | public static V2GPrintPosition operator *(V2GPrintPosition p, Double s) 128 | { 129 | return new V2GPrintPosition(s * p.X, s * p.Y, s * p.Z); 130 | } 131 | 132 | public static V2GPrintPosition operator +(V2GPrintPosition pp, V2GPoint p) 133 | { 134 | return new V2GPrintPosition(pp.X + p.X, pp.Y + p.Y, pp.Z + p.Z); 135 | } 136 | 137 | public static V2GPrintPosition operator -(V2GPrintPosition pp, V2GPoint p) 138 | { 139 | return new V2GPrintPosition(pp.X - p.X, pp.Y - p.Y, pp.Z - p.Z); 140 | } 141 | 142 | /// 143 | /// Add the coordinates of specified V2GPrintPoint to this one. 144 | /// 145 | /// 146 | public void Add(V2GPrintPosition p) 147 | { 148 | this.X += p.X; 149 | this.Y += p.Y; 150 | this.Z += p.Z; 151 | } 152 | 153 | /// 154 | /// Add the coordinates of specified V2GPoint to this one. 155 | /// 156 | /// 157 | public void Add(V2GPoint p) 158 | { 159 | this.X += p.X; 160 | this.Y += p.Y; 161 | this.Z += p.Z; 162 | } 163 | 164 | /// 165 | /// Substract the coordinates of specified V2GPrintPoint to this one. 166 | /// 167 | /// 168 | public void Substract(V2GPrintPosition p) 169 | { 170 | this.X += -p.X; 171 | this.Y += -p.Y; 172 | this.Z += -p.Z; 173 | } 174 | 175 | /// 176 | /// Substract the coordinates of specified V2GPoint to this one. 177 | /// 178 | /// 179 | public void Substract(V2GPoint p) 180 | { 181 | this.X += -p.X; 182 | this.Y += -p.Y; 183 | this.Z += -p.Z; 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/Voxel2GCodeGH.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug32 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {6F0508DE-90BE-4134-B69A-1BB68E925F36} 9 | Library 10 | Properties 11 | Voxel2GCodeGH 12 | Voxel2GCodeGH 13 | v4.5 14 | 512 15 | false 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | true 29 | full 30 | false 31 | bin\ 32 | DEBUG;TRACE 33 | prompt 34 | false 35 | 36 | 37 | pdbonly 38 | true 39 | bin\ 40 | TRACE 41 | prompt 42 | 4 43 | false 44 | 45 | 46 | 47 | False 48 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\CGeometrica.dll 49 | 50 | 51 | False 52 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\CSerializer.dll 53 | 54 | 55 | ..\..\..\..\..\..\..\..\AppData\Roaming\McNeel\Rhinoceros\5.0\Plug-ins\Grasshopper {B45A29B1-4343-4035-989E-044E8580D9CF}\0.9.76.0\GH_IO.dll 56 | 57 | 58 | ..\..\..\..\..\..\..\..\AppData\Roaming\McNeel\Rhinoceros\5.0\Plug-ins\Grasshopper {B45A29B1-4343-4035-989E-044E8580D9CF}\0.9.76.0\Grasshopper.dll 59 | 60 | 61 | False 62 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MalachiteNet.dll 63 | 64 | 65 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MonolithCore.dll 66 | 67 | 68 | False 69 | ..\..\..\..\..\..\..\..\..\..\Program Files\Monolith\MonolithLib.dll 70 | 71 | 72 | 73 | 74 | 75 | 76 | False 77 | ..\..\..\..\..\..\..\..\..\..\Program Files\Rhinoceros 5 (64-bit)\System\RhinoCommon.dll 78 | False 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | {bcb34b54-0384-47a9-98e1-e4f43f520023} 100 | Voxel2GCodeCore 101 | 102 | 103 | {3f73c724-8a83-47c7-ae44-1baf6cfd2147} 104 | Voxel2GCodeRhinoCommon 105 | 106 | 107 | 108 | 115 | 116 | Copy "$(TargetPath)" "$(TargetDir)$(ProjectName).gha" 117 | Erase "$(TargetPath)" 118 | 119 | 120 | 121 | 122 | Program 123 | c:\Program Files (x86)\Rhinoceros 5\System\Rhino4.exe 124 | false 125 | 126 | 127 | en-US 128 | 129 | 130 | c:\Program Files\Rhinoceros 5 (64-bit)\System\Rhino.exe 131 | 132 | 133 | Program 134 | false 135 | 136 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/V2GState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeCore 9 | { 10 | /// 11 | /// A class to hold the state of a printer. 12 | /// 13 | public class V2GState 14 | { 15 | /// 16 | /// Contains a PrintSettings object with the printing settings of this printer. 17 | /// 18 | public V2GSettings settings = new V2GSettings(); 19 | 20 | /// 21 | /// Current position of the tool-head (x, y, z). 22 | /// 23 | public V2GPrintPosition Position; 24 | 25 | /// 26 | /// Current amount of material feeded to the primary extruder head of the printer. (e.g. T0, T1, or first head on T3.) 27 | /// 28 | public double E = 0.0; 29 | 30 | /// 31 | ///Current amount of material feeded to the secondary extruder head of the printer. (e.g. second head on T3.) 32 | /// 33 | public double A = 0.0; 34 | 35 | /// 36 | /// Current feed rate of the printer, i.e. speed, in mm/min. 37 | /// 38 | public double F = 700.0; 39 | 40 | /// 41 | /// Current extruder-head being used to print. (e.g. T0 for left extruder, T1 for right extruder, T3 for dual extruder, etc.) This values vary from printer to printer. 42 | /// 43 | public int Head = 0; 44 | 45 | /// 46 | /// Current amount of material . 47 | /// 48 | public double EPerMM = 0.033; 49 | 50 | /// 51 | /// Constructor of a printer. 52 | /// 53 | public V2GState() { 54 | /// 55 | } 56 | 57 | /// 58 | /// Set the 59 | /// 60 | /// 61 | public void SetSettings(V2GSettings Settings) 62 | { 63 | this.settings = Settings; 64 | this.F = Settings.Speed; 65 | } 66 | 67 | /// 68 | /// Set material settings. 69 | /// 70 | /// 71 | 72 | public void SetMaterial(string Material) 73 | { 74 | if(Material.Equals("PLA")) 75 | { 76 | this.settings.BedTemperature = 60.0; 77 | this.settings.T0Temperature = 200.0; 78 | this.settings.T1Temperature = 200.0; 79 | } 80 | else if (Material.Equals("ABS")) 81 | { 82 | this.settings.BedTemperature = 60.0; 83 | this.settings.T0Temperature = 240.0; 84 | this.settings.T1Temperature = 240.0; 85 | } 86 | else if (Material.Equals("NinjaFlex")) 87 | { 88 | this.settings.BedTemperature = 80.0; 89 | this.settings.T0Temperature = 220.0; 90 | this.settings.T1Temperature = 220.0; 91 | } 92 | } 93 | 94 | /// 95 | /// Set the active head. 96 | /// 97 | /// StringBuilder to store the generated G-code. 98 | /// Integer identifying the printing head. (e.g. 0 for T0, 1 for T1, etc.) 99 | public void SetHead(StringBuilder s, int Head) 100 | { 101 | if (this.Head != Head) 102 | { 103 | this.Head = Head; 104 | this.ResetHead(s); 105 | } 106 | } 107 | 108 | /// 109 | /// Generate G-code instructions to set the current material feeding position as zero. 110 | /// 111 | /// StringBuilder to store the generated G-code. 112 | public void ResetHead(StringBuilder s) 113 | { 114 | this.E = 0; 115 | this.A = 0; 116 | s.Append("\nT" + (this.Head)); 117 | s.Append("\nG92 E0.0"); 118 | if (this.Head == 3) s.Append("\nG92 A0.0"); // e.g. Dual PRO right filament 119 | } 120 | 121 | /// 122 | /// Generate G-code instructions to feed more material along a printing path. 123 | /// 124 | /// StringBuilder to store the generated G-code. 125 | /// Amount of material to feed per mm. 126 | /// Length of the path to extrude along in mm. 127 | /// Material percentage of the secondary extruder. (e.g. 0.5 feeds 50% of each when using a dual head.) 128 | public void IncreaseE(StringBuilder s, double EPerMM, double PathLength, double MaterialPercentage = 0.0) 129 | { 130 | double prevA = this.A; 131 | double prevE = this.E; 132 | 133 | if (this.Head == 3) 134 | { 135 | this.E += EPerMM * PathLength * (1.0 - MaterialPercentage); 136 | this.A += EPerMM * PathLength * MaterialPercentage; 137 | if (this.E != prevE) s.Append(" E" + Math.Round(this.E,4)); 138 | if (this.A != prevA) s.Append(" A" + Math.Round(this.A,4)); 139 | } 140 | else 141 | { 142 | this.E += EPerMM * PathLength; 143 | if (this.E != prevE) s.Append(" E" + Math.Round(this.E, 4)); 144 | } 145 | } 146 | 147 | /// 148 | /// Set the position of the printer's extruder head. 149 | /// 150 | /// A PrintPoint. 151 | public void SetPosition(V2GPrintPosition p, StringBuilder s = null) 152 | { 153 | if ( s != null && Math.Abs(this.Position.Z - p.Z + this.settings.ZOffset) > 0.01 ) 154 | { 155 | if (this.settings.IsVerbose) 156 | { 157 | s.Append("\n(Z Changed)"); 158 | s.Append(" (from " + this.Position.Z + " to " + p.Z +")"); 159 | } 160 | this.ResetHead(s); 161 | } 162 | this.Position = new V2GPrintPosition(p.X, p.Y, p.Z + this.settings.ZOffset); 163 | } 164 | 165 | /// 166 | /// Transform a PrintPoint from absolute coordinates to printer space coordinates. 167 | /// 168 | /// A PrintPoint. 169 | /// 170 | public V2GPrintPosition PrintPointOnBase(V2GPrintPosition p) 171 | { 172 | return new V2GPrintPosition(p.X, p.Y, p.Z + this.settings.ZOffset); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/Voxel2GCodeGH/V2GH_PrintPolyline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Grasshopper.Kernel; 5 | using Rhino.Geometry; 6 | using Voxel2GCodeCore.Geometry; 7 | 8 | namespace Voxel2GCodeGH 9 | { 10 | public class V2GH_PrintPolyline : GH_Component 11 | { 12 | /// 13 | /// Each implementation of GH_Component must provide a public 14 | /// constructor without any arguments. 15 | /// Category represents the Tab in which the component will appear, 16 | /// Subcategory the panel. If you use non-existing tab or panel names, 17 | /// new tabs/panels will automatically be created. 18 | /// 19 | public V2GH_PrintPolyline() 20 | : base("Construct PrintPolyline", "PrintPolyline", 21 | "Construct a PrintPolyline from a Polyline with printing properties.", 22 | "V2G", "G-code") 23 | { 24 | 25 | } 26 | 27 | /// 28 | /// Registers all the input parameters for this component. 29 | /// 30 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) 31 | { 32 | pManager.AddCurveParameter("Polyline", "Polyline", 33 | "Polyline to print.", 34 | GH_ParamAccess.list); 35 | pManager.AddNumberParameter("Material per mm", "Material per mm", 36 | "Amount of filament to extrude per linear mm, i.e. E value, spread between E and A if using dual extruder.", 37 | GH_ParamAccess.list, 0.033); 38 | pManager.AddNumberParameter("Speed", "Speed", 39 | "Feedrate at which extrude the material.", 40 | GH_ParamAccess.list, 700.0); 41 | pManager.AddIntegerParameter("Tool-head", "Tool-head", 42 | "Number of the corresponding tool-head to use, e.g. T0 (left extruder), T1 (right extruder), T3 (dual pro extruder mix), etc.", 43 | GH_ParamAccess.list, 0); 44 | pManager.AddNumberParameter("Mix Percetage", "Mix Percentage", 45 | "Amount of secondary material to mix with dual extruder, i.e. 0 for 100%-0%, 0.5 for 50%-50% 1.0 for 0%-100%).", 46 | GH_ParamAccess.list, 0); 47 | } 48 | 49 | /// 50 | /// Registers all the output parameters for this component. 51 | /// 52 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) 53 | { 54 | // Use the pManager object to register your output parameters. 55 | // Output parameters do not have default values, but they too must have the correct access type. 56 | 57 | pManager.AddGenericParameter("PrintPolyline", "PrintPolyline", "Printable polyline wrapper.", GH_ParamAccess.list); 58 | pManager.AddCurveParameter("Polyline", "Polyline", "Filtered list of Polylines.", GH_ParamAccess.list); 59 | // Sometimes you want to hide a specific parameter from the Rhino preview. 60 | // You can use the HideParameter() method as a quick way: 61 | //pManager.HideParameter(0); 62 | } 63 | 64 | /// 65 | /// This is the method that actually does the work. 66 | /// 67 | /// The DA object can be used to retrieve data from input parameters and 68 | /// to store data in output parameters. 69 | protected override void SolveInstance(IGH_DataAccess DA) 70 | { 71 | List curves = new List(); 72 | List polylines = new List(); 73 | List printPolylines = new List(); 74 | List points = new List(); 75 | 76 | List MaterialAmount = new List(); 77 | List Speed = new List(); 78 | List Toolhead = new List(); 79 | List MixPercentage = new List(); 80 | 81 | if (!DA.GetDataList(0, curves)) return; 82 | if (!DA.GetDataList(1, MaterialAmount)) return; 83 | if (!DA.GetDataList(2, Speed)) return; 84 | if (!DA.GetDataList(3, Toolhead)) return; 85 | if (!DA.GetDataList(4, MixPercentage)) return; 86 | 87 | foreach (Curve c in curves) 88 | { 89 | if(c.IsPolyline()) 90 | { 91 | Polyline pl; 92 | if (c.TryGetPolyline(out pl)) 93 | { 94 | polylines.Add(pl); 95 | /*foreach (Point3d p in pl) 96 | { 97 | points.Add(p); 98 | }*/ 99 | } 100 | } 101 | } 102 | 103 | int idx = 0; 104 | double _Speed = Speed[0]; 105 | double _MaterialAmount = MaterialAmount[0]; 106 | int _Head = Toolhead[0]; 107 | double _MixPercentage = MixPercentage[0]; 108 | 109 | foreach (Polyline pl in polylines) 110 | { 111 | if (Speed.Count - 1 >= idx) _Speed = Speed[idx]; 112 | if (MaterialAmount.Count - 1 >= idx) _MaterialAmount = MaterialAmount[idx]; 113 | if (Toolhead.Count - 1 >= idx) _Head = Toolhead[idx]; 114 | if (MixPercentage.Count - 1 >= idx) _MixPercentage = MixPercentage[idx]; 115 | 116 | V2GPrintPolyline ppl = new V2GPrintPolyline(); 117 | foreach(Point3d p in pl) 118 | { 119 | ppl.AddPrintPosition(new V2GPoint(p.X, p.Y, p.Z), _Speed, _MaterialAmount, _Head, _MixPercentage); 120 | } 121 | printPolylines.Add(ppl); 122 | idx++; 123 | } 124 | 125 | DA.SetDataList(0, printPolylines); 126 | DA.SetDataList(1, polylines); 127 | } 128 | 129 | 130 | /// 131 | /// The Exposure property controls where in the panel a component icon 132 | /// will appear. There are seven possible locations (primary to septenary), 133 | /// each of which can be combined with the GH_Exposure.obscure flag, which 134 | /// ensures the component will only be visible on panel dropdowns. 135 | /// 136 | public override GH_Exposure Exposure 137 | { 138 | get { return GH_Exposure.primary; } 139 | } 140 | 141 | /// 142 | /// Provides an Icon for every component that will be visible in the User Interface. 143 | /// Icons need to be 24x24 pixels. 144 | /// 145 | protected override System.Drawing.Bitmap Icon 146 | { 147 | get 148 | { 149 | // You can add image files to your project resources and access them like this: 150 | //return Resources.IconForThisComponent; 151 | return null; 152 | } 153 | } 154 | 155 | /// 156 | /// Each component must have a unique Guid to identify it. 157 | /// It is vital this Guid doesn't change otherwise old ghx files 158 | /// that use the old ID will partially fail during loading. 159 | /// 160 | public override Guid ComponentGuid 161 | { 162 | get { return new Guid("{b6739c27-3de6-4a1a-a4b5-2e6e2eecec12}"); } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/Utilities/V2GVoxel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MalachiteNet; 7 | using MonolithLib; 8 | using CGeometrica; 9 | using CSerializer; 10 | using Voxel2GCodeCore.Geometry; 11 | 12 | namespace Voxel2GCodeCore.Utilities 13 | { 14 | /// 15 | /// A class with utilities for Monolith voxel-based model operations. 16 | /// 17 | public class V2GVoxel 18 | { 19 | /// 20 | /// Augment a point with voxel information. 21 | /// 22 | /// 23 | /// 24 | /// 25 | public static V2GVoxelPoint GetVoxelPoint(VoxelImage Voxel, V2GPoint _Point) 26 | { 27 | return new V2GVoxelPoint(Voxel, _Point); 28 | } 29 | 30 | /// 31 | /// Get the interpolated value of a voxel field at a given point with coordinates. 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | /// 38 | public static double GetVoxelFieldValue(VoxelChannel vc, double x, double y, double z) 39 | { 40 | double res = 0.0; 41 | if (vc.GetDataAtPointTriL(new CVector(x, y, z), out res)) return res; 42 | return 0.0; 43 | } 44 | 45 | /// 46 | /// Get the interpolated value of a voxel field at a given Point3d. 47 | /// 48 | /// 49 | /// 50 | /// 51 | 52 | public static double GetVoxelFieldValue(VoxelChannel vc, V2GPoint p) 53 | { 54 | double res = 0.0; 55 | if (vc.GetDataAtPointTriL(new CVector(p.X, p.Y, p.Z), out res)) return res; 56 | return 0.0; 57 | } 58 | 59 | /// 60 | /// Walk through the contour and gradient curves of a voxel field. 61 | /// 62 | /// A voxel. 63 | /// A Point3d. 64 | /// 65 | /// 66 | /// 67 | /// 68 | 69 | public static List VoxelCurvePoints(VoxelImage VoxelImage, V2GPoint Point, double SegmentLength = 0.0001, int MaxIterations = 10000, int VectorType = 0) 70 | { 71 | List Points = new List(); 72 | List lines = new List(); 73 | 74 | V2GPoint lastPoint = Point; 75 | bool ContourEnded = false; 76 | 77 | int i = 0; 78 | Points.Add(Point); 79 | while (ContourEnded == false) 80 | { 81 | if (i > MaxIterations) ContourEnded = true; 82 | V2GPoint pathVector = new V2GPoint(); 83 | V2GVoxelPoint voxelPoint = V2GVoxel.GetVoxelPoint(VoxelImage as VoxelImage, lastPoint); 84 | if (voxelPoint.FieldValue > 0.995) ContourEnded = true; 85 | if (voxelPoint.FieldValue < 0.005) ContourEnded = true; 86 | 87 | if (Points.Count > 500 && lastPoint.DistanceTo(Points[Points.Count - 20]) < 0.001) ContourEnded = true; 88 | 89 | switch (VectorType) 90 | { 91 | case 0: 92 | pathVector = voxelPoint.ContourVector; 93 | break; 94 | case 1: 95 | pathVector = voxelPoint.GradientVector; 96 | break; 97 | case 2: 98 | pathVector = voxelPoint.ContourVector3d; 99 | break; 100 | default: 101 | pathVector = voxelPoint.ContourVector; 102 | break; 103 | } 104 | 105 | V2GPoint newPoint = lastPoint + pathVector * SegmentLength; 106 | 107 | lines.Add(new V2GLine(newPoint, Point)); 108 | Points.Add(newPoint); 109 | lastPoint = newPoint; 110 | if (i > 50 && newPoint.DistanceTo(Point) < 0.001) 111 | { 112 | ContourEnded = true; 113 | Points.Add(Point); 114 | } 115 | ++i; 116 | } 117 | return Points; 118 | } 119 | 120 | /// 121 | /// Walk through the contour and gradient curves of a voxel field limiting the field range (for gradient curves). 122 | /// 123 | /// A voxel. 124 | /// A Point3d. 125 | /// The length of each of the steps to walk. 126 | /// 127 | /// Restrict the maximum field range to walk (only for contour curves). 128 | /// 129 | /// 130 | 131 | public static List VoxelCurvePoints(VoxelImage VoxelImage, V2GPoint Point, double SegmentLength = 0.0001, int MaxIterations = 10000, double FieldRange = 0.1, int VectorType = 1) 132 | { 133 | List Points = new List(); 134 | List lines = new List(); 135 | 136 | VoxelImage voxelImage = VoxelImage as VoxelImage; 137 | V2GVoxelPoint StartVoxelPoint = V2GVoxel.GetVoxelPoint(voxelImage, Point); 138 | 139 | V2GPoint lastPoint = Point; 140 | bool ContourEnded = false; 141 | 142 | int i = 0; 143 | Points.Add(Point); 144 | while (ContourEnded == false) 145 | { 146 | if (i > MaxIterations) ContourEnded = true; 147 | V2GPoint pathVector = new V2GPoint(); 148 | V2GVoxelPoint voxelPoint = V2GVoxel.GetVoxelPoint(voxelImage, lastPoint); 149 | 150 | if (voxelPoint.FieldValue > 0.995 || 151 | voxelPoint.FieldValue < 0.005 || 152 | Points.Count > 500 && lastPoint.DistanceTo(Points[Points.Count - 20]) < 0.001 || 153 | Math.Abs(StartVoxelPoint.FieldValue - voxelPoint.FieldValue) > FieldRange) 154 | { 155 | ContourEnded = true; 156 | } 157 | 158 | switch (VectorType) 159 | { 160 | case 0: 161 | pathVector = voxelPoint.ContourVector; 162 | break; 163 | case 1: 164 | pathVector = voxelPoint.GradientVector; 165 | break; 166 | case 2: 167 | pathVector = voxelPoint.ContourVector3d; 168 | break; 169 | default: 170 | pathVector = voxelPoint.ContourVector; 171 | break; 172 | } 173 | 174 | V2GPoint newPoint = lastPoint + pathVector * SegmentLength; 175 | 176 | lines.Add(new V2GLine(newPoint, Point)); 177 | Points.Add(newPoint); 178 | lastPoint = newPoint; 179 | if (i > 50 && newPoint.DistanceTo(Point) < 0.001) 180 | { 181 | ContourEnded = true; 182 | Points.Add(Point); 183 | } 184 | ++i; 185 | } 186 | return Points; 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Voxel2GCode 2 | 3 | *A set of workflows to transform geometric objects and voxel-based models into 3D-printable G-code instructions.* 4 | 5 | ![Material Gradients with Monolith](docs/img/main-header.jpg) 6 | 7 | `Voxel2GCode` is a project which aims for a flexible, customizable workflow for 3D printing, which started as part of the **Material Gradients with Monolith** project by [Nono Martínez Alonso](http://nono.ma) while working with the Autodesk Generative Design Group, during the summer of 2016. 8 | The project facilitates the generation of custom printing and slicing workflows, in an effort to simplify the delivery of instructions to 3D printers and the fabrication of artifacts from geometric objects and voxel-based models with low cost multi-material 3D printers. 9 | 10 | [Tweet this](https://twitter.com/intent/tweet?text=Voxel2GCode%20transforms%20geometry%20%26%20voxel-based%20models%20into%203D-printable%20instructions%20w/%20%23gh3d%20@DynamoBIM%20github.com/nonoesp/Voxel2GCode%20by%20@nonoesp). 11 | 12 | In a nutshell, Voxel2GCode provides five tools: 13 | * Voxel2GCodeCore as a standalone .NET library. 14 | * Voxel2GCodeRhinoCommon for scripting with C# using RhinoCommon. 15 | * Voxel2GCodeGH as a Grasshopper for Rhino plugin. 16 | * Voxel2GCodeDesignScript for scripting with C# using DesignScript. 17 | * Voxel2GCodeDynamo as a Dynamo package. 18 | 19 | ## Download 20 | 21 | * [Voxel2GCode.zip](http://gettingarchitecturedone.com/files/Voxel2GCode.zip) 22 | * The voxel utilities of V2G require you to install [Monolith](http://monolith.zone/download), everything else should work fine without it. 23 | 24 | ![Material Gradients with Monolith](docs/img/161117-artifacts.gif) 25 | 26 | ## Table of Contents 27 | 28 | * [Installation](#installation) 29 | * [Reference](#reference) 30 | * [Basic Usage](#basic-usage) 31 | 32 | ## Installation 33 | 34 | ### Voxel2GCode for Grasshopper and RhinoCommon 35 | 36 | * Copy and paste all files inside the `Voxel2GCode for Grasshopper` into your Grasshopper components folder -- accessible via `Grasshopper > File > Special Folders > Components Folder`. 37 | * (In case you want to use the voxel components you'd have to install [Monolith](http://monolith.zone/download).) 38 | 39 | ### Voxel2GCode for Dynamo and DesignScript 40 | 41 | * Open a new Dynamo document. 42 | * Under the nodes tab, click on `Import`, and select the `Voxel2GCode for Dynamo.dll` library. 43 | * (In case you want to use the voxel components you'd have to install [Monolith](http://monolith.zone/download).) 44 | 45 | ### Voxel2GCodeCore.dll 46 | 47 | * You can use the `Voxel2GCodeCore.dll` library, for instance, as a reference in your C# project, or to script inside Grasshopper components. 48 | * (In case you want to use the voxel components you'd have to install [Monolith](http://monolith.zone/download).) 49 | 50 | ## Reference 51 | 52 | ### Voxel2GCodeCore 53 | 54 | A .NET library to write G-code instructions from geometric objects. 55 | 56 | * V2GModel 57 | * V2GPath 58 | * V2GSettings 59 | * V2GSlice 60 | * V2GState 61 | 62 | #### Primitives 63 | 64 | * V2GPoint 65 | * V2GLine 66 | * V2GCurve 67 | * V2GVoxelPoint 68 | 69 | #### Printables 70 | 71 | Geometric objects augmented with printing metadata. 72 | 73 | * V2GPrintable 74 | * V2GPrintPosition 75 | * V2GPrintPolyline 76 | 77 | #### Instructions 78 | 79 | * V2GInstruction 80 | * V2GMovement 81 | * V2GPrintSegment 82 | 83 | #### Utilities 84 | 85 | * V2GGeometry 86 | * V2GMath 87 | * V2GPrint 88 | * V2GVoxel 89 | 90 | ### Voxel2GCodeRhinoCommon 91 | 92 | A .NET library for RhinoCommon-specific functions of Voxel2GCode. It subclasses and expands classes of the Core library to use specific RhinoCommon functions. 93 | 94 | * V2GRhinoCurve 95 | * V2GRhinoGeometry 96 | 97 | ### Voxel2GCodeGH 98 | 99 | A Grasshopper for Rhino plugin. 100 | 101 | #### G-code 102 | 103 | * Construct PrintPoint 104 | * Construct PrintPolyline 105 | * Construct Printer 106 | * Construct Printing Settings 107 | * Construct Printer 108 | * *PrintingBoundaries (TODO)* 109 | * *Export G-code (TODO)* 110 | * Extract PrintPolylineData 111 | 112 | #### Slicer 113 | 114 | * Sort Curves 115 | * Get Bounding Frames 116 | * Get Slice Planes 117 | 118 | #### Voxel 119 | 120 | * Construct VoxelPoint 121 | * Get VoxelCurvePoints 122 | 123 | Implementation of Voxel2GCodeLib for Grasshopper. 124 | 125 | ### Voxel2GCodeDesignScript 126 | 127 | A .NET library for DesignScript-specific functions of Voxel2GCode. 128 | 129 | * V2GDesignScriptCurve 130 | * V2GDesignScriptGeometry 131 | 132 | ### Voxel2GCodeDynamo 133 | 134 | A ZeroTouch Dynamo package. 135 | 136 | * PrintPoint 137 | * PrintPolyline 138 | * PrintPolylineData 139 | * Printer 140 | * PrintSettings 141 | * Export 142 |   143 | * CurveSort 144 | * CurveSinusoidalPoints 145 | 146 | ## Basic Usage 147 | 148 | Here are a few examples on how to use the library for scripting, with Grasshopper for Rhino, and with Dynamo. More in detail examples are being developed. 149 | 150 | ### Voxel2GCodeCore 151 | 152 | #### Printing A Polyline 153 | 154 | ```csharp 155 | // Create a printer 156 | V2GState printer = new V2GState(); 157 | 158 | // Create a printable model 159 | V2GModel model = new V2GModel(); 160 | 161 | // Create a list of points to hold positions 162 | List positions = new List(); 163 | 164 | // Add positions 165 | positions.Add(new V2GPoint(25.0, 40.0, 0.0)); 166 | positions.Add(new V2GPoint(30.0, 45.0, 0.0)); 167 | positions.Add(new V2GPoint(35.0, 40.0, 0.0)); 168 | 169 | // Create a printable polyline 170 | V2GPrintPolyline printPolyline = new V2GPrintPolyline(); 171 | foreach(V2GPoint position in positions) { 172 | Print(position.ToString() + " " + position.X); 173 | printPolyline.AddPrintPosition(position); 174 | } 175 | 176 | // Append the printable polylines as paths to the model 177 | model.AppendAsPath(printPolyline); 178 | 179 | // Create a StringBuilder to store G-code 180 | System.Text.StringBuilder sb = new System.Text.StringBuilder(); 181 | model.GenerateGCode(sb, printer); 182 | 183 | // Create a string with G-code 184 | string GCode = sb.ToString(); 185 | ``` 186 | 187 | #### Create a Printer with Custom Settings 188 | 189 | ```csharp 190 | // Create a printer 191 | V2GState printer = new V2GState(); 192 | 193 | // Create printing settings 194 | V2GSettings settings = new V2GSettings(); 195 | 196 | // Override some parameters 197 | settings.T0Temperature = 220.0; 198 | settings.BedTemperature = 80.0; 199 | settings.ZOffset = 0.5; 200 | settings.Retraction_Length = 0.3; 201 | 202 | // Attach the settings to the printer 203 | printer.SetSettings(settings); 204 | ``` 205 | 206 | ### Voxel2GCodeGH 207 | 208 | #### Printing A Polyline With Custom Settings 209 | 210 | ![Voxel2GCodeGH Polyline Workflow.](docs/img/160826-grasshopper-workflow.png) 211 | 212 | #### Extract Gradient and Contour Curves From A Monolith Vol File 213 | 214 | ![Voxel2GCodeGH Voxel Workflow.](docs/img/160824-grasshopper-voxel-workflow.png) 215 | 216 | ![Lemon — Contour and Gradient Curves with Voxel2GCode](docs/img/160824-contour-curves-filter-800px.gif) 217 | 218 | ### Voxel2GCodeDynamo 219 | 220 | #### Printing A PolyCurve 221 | 222 | ![Voxel2GCodeDynamo PolyCurve Workflow.](docs/img/160816-dynamo-workflow-polycurve.png) 223 | 224 | ## Sample Files 225 | 226 | Grasshopper and Dynamo sample files will be posted soon. 227 | 228 | ## Acknowledgements 229 | 230 | The development of Voxel2GCode was sponsored by [Autodesk Inc](http://www.autodesk.com/), as part of a summer research residency project in Boston, 2016. Please take a look at the [detailed list of acknowledgments](docs/Acknowledgments.md). 231 | 232 | Voxel2GCode was created and is maintained by [Nono Martínez Alonso](http://nono.ma). 233 | 234 | ## License 235 | 236 | Voxel2GCode is licensed under the [MIT license](LICENSE). 237 | 238 | ## Me 239 | 240 | I'm [Nono Martínez Alonso](http://nono.ma) (nono.ma), a computational designer and architect with a penchant for simplicity. 241 | I tweet at [@nonoesp](http://www.twitter.com/nonoesp) and write at [Getting Simple](http://gettingsimple.com/). If you use Voxel2GCode, I would love to hear about it. Thanks! 242 | 243 | ## Contributing 244 | 245 | In its early stages, Voxel2GCode sets a base structure for growth and flexibility. Any kind of contribution or collaboration is welcome. If you are interested in playing around with this library [shoot me a tweet](https://twitter.com/intent/tweet?text=Hi%20@nonoesp,%20I%27ve%20seen%20Voxel2GCode%20and%20your-message-here.). 246 | -------------------------------------------------------------------------------- /src/Voxel2GCodeRhinoCommon/Utilities/V2GRhinoGeometry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Voxel2GCodeCore.Utilities; 7 | using Rhino.Geometry; 8 | 9 | namespace Voxel2GCodeRhino.Utilities 10 | { 11 | /// 12 | /// Test to see if we can add extension methods to core through a different project. 13 | /// 14 | public static class V2GRhinoGeometry 15 | { 16 | /// 17 | /// Extract bounding Z frames -- slice planes -- of a given geometry. 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | /// 27 | public static List SlicePlanes( 28 | GeometryBase G, 29 | double LayerHeight, 30 | double OffsetBottomGlobal = 0, 31 | double OffsetBottom = 0, 32 | double OffsetTop = 0, 33 | bool ShouldForceTop = false) 34 | { 35 | List Frames = new List(); 36 | 37 | // Default BoundingBox 38 | BoundingBox bb = G.GetBoundingBox(true); 39 | Point3d[] corners = bb.GetCorners(); 40 | Line ZLine = new Line(corners[0], corners[4]); 41 | double ZLineLength = ZLine.Length; 42 | 43 | // Safety 44 | int FrameCap = 150; 45 | if (ZLineLength / LayerHeight > FrameCap - 1) LayerHeight = ZLine.Length / (FrameCap - 1); 46 | 47 | // Z Frames 48 | double ZAmount = ZLineLength / LayerHeight; 49 | bool HasTopLayer = false; 50 | 51 | for (double i = 0; i <= ZAmount; i++) 52 | { 53 | double distance = i * LayerHeight + OffsetBottomGlobal; 54 | if (i == 0) distance += OffsetBottom; 55 | if (distance == ZLineLength) HasTopLayer = true; 56 | if (distance == ZLineLength || !ShouldForceTop && LayerHeight * (i + 1) + OffsetBottomGlobal > ZLineLength) distance += -OffsetTop; 57 | double param = distance / ZLineLength; 58 | if (param <= 1) 59 | { 60 | Plane pl; 61 | ZLine.ToNurbsCurve().PerpendicularFrameAt(param, out pl); 62 | Frames.Add(pl); 63 | } 64 | } 65 | if (ShouldForceTop && !HasTopLayer) 66 | { 67 | Plane pl; 68 | double param = 1 - OffsetTop / ZLineLength; 69 | if (param > 1) param = 1; 70 | ZLine.ToNurbsCurve().PerpendicularFrameAt(param, out pl); 71 | Frames.Add(pl); 72 | } 73 | return Frames; 74 | } 75 | 76 | /// 77 | /// Extract bounding frames to slice a given geometry. 78 | /// 79 | /// 80 | /// 81 | /// 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | public static List> BoundingFrames(GeometryBase G, double XSpan, double YSpan, double ZSpan, double DXSpan, double DYSpan, double AngleDegrees = 45.0) 88 | { 89 | // Nono.Util 90 | // BoundingFrames 91 | // Nono Martínez Alonso (nono.ma) 92 | // 160622, Autodesk Generative Design 93 | 94 | List> Frames = new List>(); 95 | 96 | // 1. Default BoundingBox 97 | 98 | BoundingBox bb = G.GetBoundingBox(true); 99 | Point3d[] corners = bb.GetCorners(); 100 | 101 | Line XLine = new Line(corners[0], corners[1]); 102 | Line YLine = new Line(corners[0], corners[3]); 103 | Line ZLine = new Line(corners[0], corners[4]); 104 | 105 | List XFrames = new List(); 106 | List YFrames = new List(); 107 | List ZFrames = new List(); 108 | 109 | // X Frames 110 | if (XSpan > 0) 111 | { 112 | double XAmount = Math.Floor(XLine.Length / XSpan); 113 | double XStep = XLine.Length / XAmount; 114 | double Xt = 0; 115 | for (double i = 0; i <= XAmount; i++) 116 | { 117 | Plane pl; 118 | Xt = i * XStep / XLine.Length; 119 | XLine.ToNurbsCurve().PerpendicularFrameAt(Xt, out pl); 120 | XFrames.Add(pl); 121 | } 122 | } 123 | 124 | // Y Frames 125 | if (YSpan > 0) 126 | { 127 | double YAmount = Math.Floor(YLine.Length / YSpan); 128 | double YStep = YLine.Length / YAmount; 129 | double Yt = 0; 130 | for (double i = 0; i <= YAmount; i++) 131 | { 132 | Plane pl; 133 | Yt = i * YStep / YLine.Length; 134 | YLine.ToNurbsCurve().PerpendicularFrameAt(Yt, out pl); 135 | YFrames.Add(pl); 136 | } 137 | } 138 | 139 | // Z Frames 140 | double ZAmount = ZLine.Length / ZSpan; 141 | for (double i = 0; i <= ZAmount; i++) 142 | { 143 | Plane pl; 144 | ZLine.ToNurbsCurve().PerpendicularFrameAt(i * ZSpan / ZLine.Length, out pl); 145 | ZFrames.Add(pl); 146 | } 147 | 148 | // 2. Diagonal BoundingBox 149 | 150 | Transform rotate = Transform.Rotation(-V2GMath.DEGREES_TO_RADIANS * AngleDegrees, new Vector3d(0, 0, 1), bb.Center); 151 | Transform rotateBack = Transform.Rotation(V2GMath.DEGREES_TO_RADIANS * AngleDegrees, new Vector3d(0, 0, 1), bb.Center); 152 | G.Transform(rotate); 153 | 154 | BoundingBox Dbb = G.GetBoundingBox(true); 155 | Point3d DbbCenter = Dbb.Center; 156 | Point3d[] Dcorners = Dbb.GetCorners(); 157 | 158 | Line DXLine = new Line(Dcorners[0], Dcorners[1]); 159 | Line DYLine = new Line(Dcorners[0], Dcorners[3]); 160 | 161 | List DXFrames = new List(); 162 | List DYFrames = new List(); 163 | 164 | // DX Frames 165 | if (DXSpan > 0) 166 | { 167 | double DXAmount = Math.Floor(DXLine.Length / DXSpan); 168 | double DXStep = DXLine.Length / DXAmount; 169 | double DXt = 0; 170 | for (double i = 0; i <= DXAmount; i++) 171 | { 172 | Plane pl; 173 | DXt = i * DXStep / DXLine.Length; 174 | DXLine.ToNurbsCurve().PerpendicularFrameAt(DXt, out pl); 175 | pl.Transform(rotateBack); 176 | 177 | DXFrames.Add(pl); 178 | } 179 | } 180 | 181 | // DY Frames 182 | if (DYSpan > 0) 183 | { 184 | double DYAmount = Math.Floor(DYLine.Length / DYSpan); 185 | double DYStep = DYLine.Length / DYAmount; 186 | double DYt = 0; 187 | for (double i = 0; i <= DYAmount; i++) 188 | { 189 | Plane pl; 190 | DYt = i * DYStep / DYLine.Length; 191 | DYLine.ToNurbsCurve().PerpendicularFrameAt(DYt, out pl); 192 | pl.Transform(rotateBack); 193 | DYFrames.Add(pl); 194 | } 195 | } 196 | 197 | Frames.Add(XFrames); 198 | Frames.Add(YFrames); 199 | Frames.Add(ZFrames); 200 | Frames.Add(DXFrames); 201 | Frames.Add(DYFrames); 202 | 203 | return Frames; 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/Voxel2GCodeCore/Classes/V2GModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection; 7 | using Voxel2GCodeCore.Geometry; 8 | using Voxel2GCodeCore.Instructions; 9 | 10 | namespace Voxel2GCodeCore 11 | { 12 | /// 13 | /// A class to hold a printable model which contains printable paths and slices. 14 | /// 15 | public class V2GModel 16 | { 17 | /// 18 | /// A dictionary with slices of the model. 19 | /// 20 | public Dictionary Slices = new Dictionary(); 21 | /// 22 | /// A list of paths of the model. 23 | /// 24 | public List Paths = new List(); 25 | 26 | /* 27 | // TODO 28 | public void AppendAsPath(Printable printable) 29 | { 30 | this.Paths.Add(printable.GetPath()); 31 | 32 | or 33 | 34 | this.Path.Add(Printable.GenerateInstructions()) 35 | } 36 | */ 37 | 38 | /// 39 | /// Append a PrintPolyline as a path. 40 | /// 41 | /// 42 | public void AppendAsPath(V2GPrintPolyline ppl) 43 | { 44 | V2GPath path = new V2GPath(); 45 | foreach(V2GPrintPosition PrintPosition in ppl.PrintPositions) 46 | { 47 | V2GInstruction seg; 48 | if (path.Segments.Count == 0) 49 | { 50 | seg = new V2GMovement(PrintPosition, 7200.0); // First: PrintMovement 51 | } 52 | else 53 | { 54 | seg = new V2GPrintSegment(PrintPosition); // Others: PrintSegment 55 | } 56 | path.Segments.Add(seg); 57 | } 58 | Paths.Add(path); 59 | } 60 | 61 | // TODO: Implement with V2GMovement 62 | public void AppendAsMovementPath(List pl) 63 | { 64 | V2GPath path = new V2GPath(); 65 | 66 | foreach (V2GPrintPosition p in pl) 67 | { 68 | V2GInstruction seg; 69 | seg = new PrintMovementOld(); 70 | (seg as PrintMovementOld).p = p; 71 | path.Segments.Add(seg); 72 | } 73 | Paths.Add(path); 74 | } 75 | 76 | // TODO: Implement with V2GMovement 77 | public void AppendAsRelativeMovement(V2GPrintPosition p) 78 | { 79 | V2GPath path = new V2GPath(); 80 | 81 | V2GInstruction seg; 82 | seg = new PrintMovementOld(); 83 | (seg as PrintMovementOld).p = p; 84 | (seg as PrintMovementOld).IsRelative = true; 85 | (seg as PrintMovementOld).speed = 2400; 86 | path.Segments.Add(seg); 87 | 88 | Paths.Add(path); 89 | } 90 | 91 | public void AppendAsRelativeMovement(V2GPrintPosition p, double Retraction, double Speed = 2400) 92 | { 93 | V2GPath path = new V2GPath(); 94 | 95 | V2GInstruction seg; 96 | seg = new PrintMovementOld(); 97 | (seg as PrintMovementOld).p = p; 98 | (seg as PrintMovementOld).IsRelative = true; 99 | (seg as PrintMovementOld).ForceFilamentOperations = true; 100 | (seg as PrintMovementOld).FilamentRetract = Retraction; // mm 101 | (seg as PrintMovementOld).speed = Speed; 102 | path.Segments.Add(seg); 103 | 104 | Paths.Add(path); 105 | } 106 | 107 | /* 108 | /// 109 | /// Append a polyline as a path. 110 | /// 111 | /// 112 | public void AppendAsPath(Polyline pl) 113 | { 114 | this.AppendAsPath(pl, 0.05, 700, true); 115 | } 116 | 117 | /// 118 | /// Append a polyline as a path with a given speed. 119 | /// 120 | /// 121 | /// 122 | public void AppendAsPath2(Polyline pl, double speed) 123 | { 124 | PrintPath path = new PrintPath(); 125 | 126 | foreach (Point3d p in pl) 127 | { 128 | //seg.IsFirst = (path.Segments.Count == 0); 129 | PrintInstruction seg; 130 | if (path.Segments.Count == 0) 131 | { 132 | // First: PrintMovement 133 | seg = new PrintMovement2(); 134 | (seg as PrintMovement2).p = p; 135 | (seg as PrintMovement2).speed = 7200; 136 | } 137 | else 138 | { 139 | // Others: PrintSegment 140 | seg = new PrintSegment2(); 141 | (seg as PrintSegment2).p = p; 142 | (seg as PrintSegment2).speed = speed; 143 | } 144 | path.Segments.Add(seg); 145 | } 146 | Paths.Add(path); 147 | } 148 | 149 | public void AppendAsPath(Polyline pl, double thickness, double speed, bool AllowsGroundOverride = true, double HeightFactor = 1.0, double MovementZ = 0.3) 150 | { 151 | PrintPath path = new PrintPath(); 152 | 153 | foreach (Point3d p in pl) 154 | { 155 | //seg.IsFirst = (path.Segments.Count == 0); 156 | PrintInstruction seg; 157 | if (path.Segments.Count == 0) 158 | { 159 | // First: PrintMovement 160 | seg = new PrintMovement(); 161 | (seg as PrintMovement).p = p; 162 | (seg as PrintMovement).zDelta = MovementZ; // how much the printer moves when moving to the new path 163 | (seg as PrintMovement).FilamentRetract = 1.0; 164 | (seg as PrintMovement).FilamentFeed = 1.0; // 2.00; // mm 165 | (seg as PrintMovement).speed = 4000; 166 | } 167 | else 168 | { 169 | // Others: PrintSegment 170 | seg = new PrintSegment(); 171 | (seg as PrintSegment).p = p; 172 | (seg as PrintSegment).thickness = thickness; 173 | (seg as PrintSegment).speed = speed; 174 | (seg as PrintSegment).HeightFactor = HeightFactor; 175 | (seg as PrintSegment).AllowsGroundOverride = AllowsGroundOverride; 176 | } 177 | path.Segments.Add(seg); 178 | } 179 | Paths.Add(path); 180 | } 181 | 182 | public void AppendAsPath(Polyline pl, double speed) 183 | { 184 | 185 | } 186 | 187 | public void AppendAsPath(Polyline pl, double speed0, double speed1) 188 | { 189 | 190 | } 191 | 192 | public delegate double SpeedDelegate(Point3d p, double len); 193 | 194 | public PrintPath AppendAsPath(Polyline pl, SpeedDelegate speedDel) 195 | { 196 | if (pl == null || pl.Count < 2) return null; 197 | 198 | PrintPath path = new PrintPath(); 199 | 200 | double length = 0.0; 201 | Point3d p0 = pl[0]; 202 | Point3d lastP = p0; 203 | 204 | foreach(Point3d p in pl) 205 | { 206 | PrintSegment seg = new PrintSegment(); 207 | 208 | length += p.DistanceTo(lastP); 209 | 210 | seg.p = p; 211 | seg.speed = speedDel(p, length); 212 | 213 | lastP = p; 214 | 215 | 216 | path.Segments.Add(seg); 217 | } 218 | 219 | return path; 220 | } 221 | 222 | public delegate PrintInstruction SegDelegate(PrintPath path, Point3d prevP, Point3d p, double len); 223 | 224 | public PrintPath AppendAsPath(Polyline pl, SegDelegate segmentProvider) 225 | { 226 | if (pl == null || pl.Count < 2) return null; 227 | 228 | PrintPath path = new PrintPath(); 229 | 230 | double length = 0.0; 231 | Point3d p0 = pl[0]; 232 | Point3d lastP = p0; 233 | 234 | foreach (Point3d p in pl) 235 | { 236 | // p.Z += zBase; 237 | length += p.DistanceTo(lastP); 238 | PrintInstruction seg = segmentProvider(path, lastP, p, length); 239 | 240 | if (seg != null) 241 | { 242 | path.Segments.Add(seg); 243 | } 244 | 245 | lastP = p; 246 | } 247 | 248 | Paths.Add(path); 249 | return path; 250 | } 251 | 252 | public void AppendAsPath(List pt) 253 | { 254 | Polyline pl = new Polyline(); 255 | AppendAsPath(pl, (p, len) => { 256 | return len; 257 | }); 258 | 259 | AppendAsPath(pl, (path, lastP, p, len) => { 260 | PrintInstruction s = null; 261 | 262 | // path.Segments.Add(new PrintMovement()); 263 | if (p.X<0.0) 264 | { 265 | s = new PrintWaveSegment(); 266 | (s as PrintWaveSegment).speed = p.Y; 267 | } 268 | else 269 | { 270 | s = new PrintSegment(); 271 | (s as PrintSegment).speed = p.Y*0.5; 272 | } 273 | 274 | return s; 275 | }); 276 | } 277 | 278 | public void AppendAsPath(List pt) 279 | { 280 | 281 | } 282 | 283 | public void AppendAndSlice(object o) 284 | { 285 | if (o is Mesh) 286 | { 287 | Mesh m = o as Mesh; 288 | // Curve [] c=Mesh.CreateContourCurves(m, ) 289 | } 290 | else if (o is Curve) 291 | { 292 | 293 | } 294 | else if (o is Line) 295 | { 296 | 297 | } 298 | } 299 | */ 300 | 301 | public void GenerateGCodeOpen(StringBuilder s, V2GState printer) 302 | { 303 | // GCode: Start 304 | // - Header. 305 | // - Model-specific initialization. 306 | 307 | // If left as "0.1.*" the version number will fill the Build and Revision parameters automatically. 308 | // Build will be the number is the number of days since the year 2000 309 | // Revision will be the number of seconds since midnight (divided by 2) 310 | 311 | Version versionInfo = Assembly.GetExecutingAssembly().GetName().Version; 312 | String versionStr = String.Format("{0}.{1}.{2}.{3}", versionInfo.Major.ToString(), versionInfo.Minor.ToString(), (versionInfo.Build - 6082).ToString(), versionInfo.Revision.ToString()); 313 | 314 | // Header 315 | s.Append("\n; Voxel2GCodeLib " + versionStr); 316 | s.Append("\n; Material Gradients with Monolith"); 317 | s.Append("\n; Autodesk Generative Design"); 318 | s.Append("\n; Nono Martínez Alonso (www.nono.ma)"); 319 | s.Append("\n; G-code generated on " + DateTime.Now.ToString("MMMM dd, yyyy (hh:mm:ss)")); 320 | s.Append("\n"); 321 | 322 | // Printer settings. 323 | //s.Append("\n; Filament diameter: " + printer.settings.FilamentThickness + " mm"); 324 | //s.Append("\n; Layer height: " + printer.settings.LayerHeight + " mm"); 325 | 326 | // Warm head up 327 | if(printer.settings.ShouldHeatUpOnStart) 328 | { 329 | s.Append("\n\n; Heat Up On Start"); 330 | s.Append("\nT0"); 331 | s.Append("\nM104 S" + printer.settings.T0Temperature + "; set temp for extruder 0 do not wait"); 332 | s.Append("\nT1"); 333 | s.Append("\nM104 S" + printer.settings.T1Temperature + "; set temp for extruder 1 do not wait"); 334 | s.Append("\nM140 S" + printer.settings.BedTemperature + "; set temp for bed do not wait"); 335 | s.Append("\nM190 S" + printer.settings.BedTemperature + "; wait for bed to reach temp"); 336 | s.Append("\nT0"); 337 | s.Append("\nM109 S" + printer.settings.T0Temperature + "; wait for extruder 0 to reach temp"); 338 | s.Append("\nT1"); 339 | s.Append("\nM109 S" + printer.settings.T1Temperature + "; wait for extruder 1 to reach temp"); 340 | } 341 | 342 | // Initialization. 343 | s.Append("\n\n; Initialization"); 344 | s.Append("\nG91"); 345 | s.Append("\nG1 Z1.000 F200.000"); 346 | s.Append("\nG90"); 347 | s.Append("\nG28 X0.000 Y0.000"); 348 | printer.SetPosition(printer.settings.StartPoint); 349 | s.Append("\nG1 X" + printer.Position.X + " Y" + printer.Position.Y + " F8000.000"); // Start point 350 | if (printer.settings.IsVerbose) s.Append(" (Start Point) (Z" + printer.Position.Z + ")"); 351 | s.Append("\nG28 Z0.000"); // G28 Returns to machine's reference position, the "zero position" 352 | s.Append("\nT1"); 353 | s.Append("\nG92 E0.00000"); 354 | s.Append("\nT0"); 355 | s.Append("\nG92 E0.00000"); 356 | s.Append("\n"); 357 | } 358 | 359 | public void GenerateGCodeClose(StringBuilder s, V2GState printer) 360 | { 361 | // GCode: End 362 | // - Move tool-head backwards 363 | // - Cool down 364 | 365 | // Move tool-head backwards. 366 | s.Append("\n\n; Move tool-head to end point and 15 mm up."); 367 | s.Append("\nG91"); 368 | s.Append("\nG1 E-3.00000 F1800.000"); 369 | s.Append("\nG90"); // absolute positioning 370 | printer.Position.Z += 0.5; 371 | s.Append("\nG1 Z" + Math.Round(printer.Position.Z, 4)); 372 | s.Append("\nG1 X" + Math.Round(printer.settings.EndPoint.X, 4) + 373 | " Y" + Math.Round(printer.settings.EndPoint.Y, 4) + 374 | " Z" + Math.Round(printer.settings.EndPoint.Z, 4) + 375 | " F3400.000"); 376 | printer.Position = printer.settings.EndPoint; 377 | s.Append("\nG91"); // incremental positioning 378 | s.Append("\nG1 Z15"); 379 | 380 | // Cool down. 381 | if (printer.settings.ShouldCoolDownOnEnd) 382 | { 383 | s.Append("\n\n;Cool down"); 384 | s.Append("\nT0;"); 385 | s.Append("\nM104 S0; extruder 0 heater off"); 386 | s.Append("\nT1;"); 387 | s.Append("\nM104 S0; extruder 1 heater off"); 388 | s.Append("\nM140 S0; bed heater off"); 389 | //s.Append("\nM106 S0; wait until extruder off"); 390 | } 391 | 392 | // TODO: Add end instructions 393 | // The following is an example 394 | // from the Cura settings file 395 | // for the ZMorph 2.0 396 | /* 397 | s.Append("\n\nG91; relative positioning"); 398 | s.Append("\nG1 E-1 F300; retract the filament a bit before lifting the nozzle, to release some of the pressure"); 399 | s.Append("\nG1 Z+0.5 E-5 X-20 Y-20 F1200; move Z up a bit and retract filament even more"); 400 | s.Append("\nG28 X0 Y0; move X/ Y to min endstops, so the head is out of the way"); 401 | s.Append("\nM84; steppers off"); 402 | s.Append("\nG90; absolute positioning"); 403 | */ 404 | } 405 | 406 | public void GenerateGCode(StringBuilder s, V2GState printer) 407 | { 408 | // GCode: Open 409 | this.GenerateGCodeOpen(s, printer); 410 | 411 | // GCode: Body (Slices & paths) 412 | s.Append("\n; PrintModel."); 413 | 414 | /*foreach (PrintSlice sl in Slices) 415 | { 416 | sl.GenerateGCode(s, printer); 417 | }*/ 418 | 419 | foreach (V2GPath p in Paths) 420 | { 421 | p.GenerateGCode(s, printer); 422 | } 423 | 424 | // GCode: Close 425 | this.GenerateGCodeClose(s, printer); 426 | } 427 | 428 | } 429 | 430 | 431 | } 432 | --------------------------------------------------------------------------------