As mentioned a few posts ago, I’m working towards generating a set of surfaces from some polyline profiles, to programmatically create a space shuttle. Most of the surfaces are “lofted”, so that seems a good place to start. Today we’re going to implement a simple command that creates a lofted surface from three circular profiles. This is based on functionality added in AutoCAD 2011, so apologies to those using prior versions.
If anyone’s interested in where the term “lofted” comes from, the ever-useful Wikipedia has some information for us:
The term lofting originally came from the shipbuilding industry where loftsmen worked on "barn loft" type structures to create the keel and bulkhead forms out of wood. This was then passed on to the aircraft then automotive industries who also required streamline [sic] shapes.
Here’s the C# code implementing our CLS command (for CreateLoftedSurface, although I do admit to a wee bit of nostalgia from implementing a CLS command :-):
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace SurfaceModelling
{
public class Commands
{
[CommandMethod("CLS")]
public void CreateLoftedSurface()
{
Database db =
HostApplicationServices.WorkingDatabase;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);
// Add our 3 circles to the database and created
// corresponding loft profiles
Circle c1 =
new Circle(
new Point3d(0, 0, 0), new Vector3d(0, 0, 1), 2
);
btr.AppendEntity(c1);
tr.AddNewlyCreatedDBObject(c1, true);
LoftProfile lp1 = new LoftProfile(c1);
Circle c2 =
new Circle(
new Point3d(0, 0, 5), new Vector3d(0, 0, 1), 5
);
btr.AppendEntity(c2);
tr.AddNewlyCreatedDBObject(c2, true);
LoftProfile lp2 = new LoftProfile(c2);
Circle c3 =
new Circle(
new Point3d(0, 0, 10), new Vector3d(0, 0, 1), 3
);
btr.AppendEntity(c3);
tr.AddNewlyCreatedDBObject(c3, true);
LoftProfile lp3 = new LoftProfile(c3);
// Create an array of our loft profiles
LoftProfile[] lps = new LoftProfile[3]{lp1, lp2, lp3};
// Create our lofted surface
Autodesk.AutoCAD.DatabaseServices.Surface.
CreateLoftedSurface(
lps, null, null, new LoftOptions(), true
);
tr.Commit();
}
}
}
}
A few comments on this code:
- There are two versions of the static CreateLoftedSurface() method
- The one we have used takes an additional “associativity” flag and takes care of adding the new surface to the modelspace (and presumably the outermost transaction)
- The other one returns a surface that requires manual adding to a block table record and to a transaction and does not add any associativity
- We are passing an empty LoftOptions() object
- We could, of course, assign it to a variable and modified the options before making the call, should we so wish
- Passing null is not an option, however: AutoCAD will crash
And let’s see the results:
And just to prove we have an associative surface, we can stretch the middle circle to fatten it:
In the next post I’ll put this into the “copy code to clipboard” solution, to place code on the clipboard to generate the lofted components of our space shuttle.