First off, if you don't have OpenSCAD, it's a prerequisite for using OSCADSharp. Head on over to their downloads page and install it on your computer!
http://www.openscad.org/downloads.html
If you're not familiar with OpenSCAD you might also want to head on over to the OpenSCAD Documentation base to get an understanding of what OSCADSharp is meant to leverage.
http://www.openscad.org/documentation.html
In Visual Studio, you can add OSCADSharp to any project with the following NuGet command:
Install-Package OSCADSharp_0.6
OSCADSharp supports a subset of of OpenSCAD's capabilities, including the three basic solids (Cube, Cylinder, Sphere) and Text.
You can create these solids by instantiating them and passing attributes into the constructors in much the same way you would call an OpenSCAD function.
Cubecube=newCube(10/*length*/,7/*width*/,9/*height*/);Cylindercylinder=newCylinder(20/*diameter*/,10/*height*/,true/* center=true*/);Spheresphere=newSphere(15/*radius*/){Resolution=30};Text3Dtext=newText3D("Are we Human, or are we Dancers?",12/* font size */);In OSCADSharp all objects that represent nodes in OpenSCAD inherit from OSCADObject. The result of .ToString() on these objects produces the OpenSCAD script generated by the object. In this way calling .ToString on the above objects will yield their direct OpenSCAD counterpart, as demonstrated below.
cube.ToString() =
cube(size=[10,7,9],center=false);cylinder.ToString() =
cylinder(center=true,r1=10,r2=10,h=10);sphere.ToString() =
sphere(r=7.5, $fn=30);text.ToString() =
linear_extrude(height=1){text("Are we Human, or are we Dancers?",size=12,halign="center",valign="center");}With the exception of Text3D (which is two operations), most objects and methods in OSCADSharp are directly analogous to an OpenSCAD method.
Creating objects is pretty neat, but you'll need to do a lot more than that to create functional 3D models. Luckily OSCADSharp supports almost all of the transforms in OpenSCAD.
Supported transforms (as of 3/6/2016) are:
- Translate
- Rotate
- Scale
- Color
- Resize
- Mirror
- Hull
- Minkowski
Transforms are used by calling methods on OSCADObjects. Every transform method returns and OSCADObject that is the result of the transform.
In this way you could chain transforms in a big stack of method calls, like so:
//A cylinder that's translated, rotated, then scaled (in that order).OSCADObjectcylinder=newCylinder(20,10,true).Translate(0,0,10).Rotate(90,0,0).Scale(1,1,2);Likewise you can use transforms as single statements, but you need to assign the result to a variable in order to use it.
OSCADObjectcube=newCube(10,7,9);//This statement does nothingcube.Resize(5,5,5);//This statement assigns a resized cube to a variableOSCADObjectresizedCube=cube.Resize(5,5,5);The Color transform only supports OpenSCAD's string-based colors. RBG values aren't supported out of sheer laziness. You can view the guide in the OpenSCAD documentatino for a full list of the options: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#color
There are many options, and the usage is what you might expect:
varmySeagreenName=newText3D("Mike").Color("Seagreen");The Hull and Minkowski transforms are actually block statements that require more than one OSCADObject to perform, so the only difference here is that you'll need to pass in another object for them to work.
varmyHull=newCube().Hull(newSphere().Translate(0,5,5));varmyMinkowski=newText3D("Hi!").Minkowski(newSphere());As with boolean operations in OpenSCAD, boolean operations in OSCADSharp require an initial OSCADObject, and at least one additional OSCADObject to perform the operation on.
All boolean operations are supported in OSCADSharp, these are:
- Union
- Difference
- Intersection
The Union operator merges two objects together. Which is actually a lot more useful in OSCADSharp because it is the only way to combine multiple OSCADObjects into a block. Because this operation is so fundamental, the + operator on OSCADObjects is overloaded to perform a Union on them.
As such, these two statements are equivalent.
OSCADObjectmyUnion1=newCube(10,7,9).Union(newSphere(15));OSCADObjectmyUnion2=newCube(10,7,9)+newSphere(15);Union and all other boolean operations support passing multiple parameters.
OSCADObjectmyUnion3=newCube(10,7,9).Union(newSphere(15),newText3D("Word"),newCylinder());//The + operator is also smart enough to combine chained operations into a single UnionOSCADObjectmyUnion4=newCube(10,7,9)+newSphere(15)+newText3D("Word")+newCylinder();As you might expect, Difference subtracts two objects from each other. The same syntax as Union is supported, and much like Union, the - operator is overloaded to perform Difference operations when used on two OSCADObjects.
vardifference=newCube()-newSphere();vardifference2=newCube().Difference(newSphere());Intersection is the same, but there is no operator shorthand.
varintersect=newCube().Intersection(newSphere());The Variable class in OSCADSharp is analogous to variables in OpenSCAD. Variables have no functional purpose outside of making your generated script easier to manipulate, or to potentially support Thingiverse Customizer functionality somewhere down the road.
The main things you need to know about Variables are as follows:
- After being instantiated, variables must be bound to properties on OSCADObjects
- In order to appear in script output, variables must be added to Variables.Global, which appear at the top of your generated files
- You can perform dynamic operations on variables, as long as it's valid for the data type
There are multiple ways to use Variables, but the simplest form is as follows:
vardiameter=newVariable("diam",Inches.Half,true/*Automatically adds to globals*/);varsphere=newSphere(diameter);In a slightly longer version of the same code, I could skip the true flag which automatically adds my variable to globals, and bind the sphere's diameter property manually.
vardiameter=newVariable("diam",Inches.Half);Variables.Global.Add(diameter);varsphere=newSphere();sphere.Bind("Diameter",diameter);The .Bind method is important because it's the only other way to bind Solids outside of the constructor that supports Variables, which has optional parameters for every possible variable binding.
Luckily variable bindings for Transforms like Translate, Rotate, Scale (etc) are a little bit more fluent, because every possible permutation of their usage is supported. Take this cube for example, which uses literals for its constructor, a variable for a translation, then two literals and one variable for a rotation.
varzRot=newVariable("zRot",90,true);vartranslation=newVariable("upMovement",newVector3(0,0,15),true);varcube=newCube(15,15,10).Translate(translation).Rotate(0,0,zRot);You can use variables inline with multiple operators to produce relativistic values. Use variables to define the values that will be crucial to the overall structure of your 3d objects, then leverage mathematical operators on your variables to produce relative values for everything else.
//Up at the top of your code file...privatestaticVariablewheelThickness=newVariable("wheelThickness",Inches.Eigth+Inches.Sixteenth,true);privatestaticVariablewheelDiameter=newVariable("wheelDiameter",Inches.ToMillimeters(1.5),true);//Much later on, after lots of code...//Note that in your output script, the length of your cube will literally read "wheelDiameter * 2 - 4",//BUT the actual Cube object in OSCADSharp will know the numerical value as well.OSCADObjecttop=newCube(wheelDiameter*2-4,wheelDiameter+4,wheelThickness){Center=true};Writing to file is the simplest step by far. Combine all objects together, then simply call .ToFile("filenName.scad") to write to disk.
The previous example for variables can be saved like so:
varzRot=newVariable("zRot",90,true);vartranslation=newVariable("upMovement",newVector3(0,0,15),true);varcube=newCube(15,15,10).Translate(translation).Rotate(0,0,zRot);cube.ToFile("myCube.scad");Which yields a script file named myCube.scad in your output directory with this content:
/*Code Generated using OSCADSharp on 3/7/2016 12:13:39 AM. For more information, please visit https://github.com/Exolun/OSCADSharp */upMovement=[0,0,15];zRot=90;rotate([0,0,zRot]){translate(v=upMovement){cube(size=[15,15,10],center=false);}}Neat!
Try the following methods as well on the object returned from .ToFile as well to automatically open or create your .STL files after writing to .scad file.
//.ToFile returns a FileInvokervarfile=cube.ToFile("myCube.scad");//Calling .Open() launches OpenSCADfile.Open();// Calling .CreateModel uses the OpenSCAD command line to render and generate a .stl// NOTE: This operation may take a significant amount of time.file.CreateModel("myCube.stl");This section coming soon. Featured methods are:
- OSCADObject.Position()
- OSCADObject.Bounds()
- OSCADObject.Clone()
- OSCADObject.Children()
- OSCADObject.Name
- OSCADObject.Id