So, back in the saddle after an eventful week off, back in the UK. Aside from the extremely changeable weather (even by British standards) and the heightened security at UK airports, the week went swimmingly... :-)
It's now Friday night, and disappointingly I've spent nearly two days regaining control of my inbox. I really wanted to make a quick post before the weekend, so rather than diving into the issue I'd planned on tackling (Palettes), I decided to take a shot at a request I'd received by email a few weeks ago: to show how to create a gradient fill using .NET.
I started by reusing the code from this previous post: so much of the code I needed was there already, it had to be easy to adjust the hatch to use a gradient fill, right? Well, no - it took me much longer than I'd expected to work this one out. Maybe I should have stuck with Palettes, after all...
I decided to use a spherical gradient fill of two colours (the default colours used when you create a two-tone gradient fill using the UI), as this shows one of the trickier parts of the API, that of specifying the colours themselves. One other call it took me a while to work out was to set the HatchObjectType property - if you don't do that then you'll get an eAmbiguousOutput exception.
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Colors;
namespace HatchGradient
{
public class Commands
{
[CommandMethod("GFH")]
static public void GradientFillHatch()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Ask the user to select a hatch boundary
PromptEntityOptions opt =
new PromptEntityOptions(
"\nSelect boundary: "
);
opt.SetRejectMessage("\nObject must be a curve.");
opt.AddAllowedClass(typeof(Curve), false);
PromptEntityResult res =
ed.GetEntity(opt);
if (res.Status == PromptStatus.OK)
{
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
// Check the entity is a closed curve
DBObject obj =
tr.GetObject(
res.ObjectId,
OpenMode.ForRead
);
Curve cur = obj as Curve;
if (cur != null && cur.Closed == false)
{
ed.WriteMessage("\nLoop must be a closed curve.");
}
else
{
// We'll add the hatch to the model space
BlockTable bt =
(BlockTable)tr.GetObject(
doc.Database.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);
Hatch hat = new Hatch();
hat.SetDatabaseDefaults();
// Firstly make it clear we want a gradient fill
hat.HatchObjectType =
HatchObjectType.GradientObject;
// Let's use the pre-defined spherical gradient
hat.SetGradient(
GradientPatternType.PreDefinedGradient,
"SPHERICAL");
// We're defining two colours
hat.GradientOneColorMode = false;
GradientColor[] gcs = new GradientColor[2];
gcs[0] =
new GradientColor(
Color.FromRgb(0, 0, 255),
0 // First colour must have value of 0
);
gcs[1] =
new GradientColor(
Color.FromRgb(255, 255, 153),
1 // Second colour must have value of 1
);
hat.SetGradientColors(gcs);
// Add the hatch to the model space
// and the transaction
ObjectId hatId = btr.AppendEntity(hat);
tr.AddNewlyCreatedDBObject(hat, true);
// Add the hatch loop and complete the hatch
ObjectIdCollection ids =
new ObjectIdCollection();
ids.Add(res.ObjectId);
hat.Associative = true;
hat.AppendLoop(
HatchLoopTypes.Default,
ids
);
hat.EvaluateHatch(true);
tr.Commit();
}
}
}
}
}
}
Here's what you get when you run the GFH command and select a polyline boundary you've created previously:
That's it for this week - have a great weekend, all of you.