Well, not exactly what I had expected to do...
I was thinking Anchor all the way, but thought I could leave the Body on the surface of the Fitting.
I only type of Anchor I could make stick was literally "to the curve".
Then, you're limited in positioning mobility only in the X direction - along the curve.
Funny...but if you manually use a Curve Anchor, you have X, Y, and Z positioning available ?!?
So, I had to add to the Body, to extend all the way down to the curve, to compensate.
I guess that's why take-offs literally extend back to the curve - there's no other way (at least that I could find).
I tested this code with a 26 x 16 90 degree Rectangular Mitered Elbow.
Oh yeah, I forgot Anchors are like magnets.
So, moving the Fitting to the origin is no longer a prerequisite before running the command.
It's only drawing the Body at the origin.
The Body is stuck on there good until you release it.
You can take the fitting and Rotate 3D, move one or the other, and it all stays together.
And, of course, the Body doesn't have to stick out of the top of the Fitting.
There are options to rotate it off to the side.
With a little planning ahead, you could make this work with whatever Fitting you choose.
Have fun with it.
[CommandMethod("ACAClassCode", "ExModelerModifyBody", CommandFlags.Modal)]
public static void ModifyBody()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptEntityOptions prEntOpts = new PromptEntityOptions("\nSelect duct fitting to modify");
prEntOpts.SetRejectMessage("\nSelected entity must be of type duct fitting");
prEntOpts.AddAllowedClass(typeof(AecBldgHvacDbSvcs.DuctFitting), false);
PromptEntityResult prEntRes = ed.GetEntity(prEntOpts);
if (prEntRes.Status != PromptStatus.OK)
return;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
AecDbSvcs.MassElement me = AecDbSvcs.MassElement.Create(AecDbSvcs.ShapeType.BoundaryRepresentation);
Autodesk.Aec.Modeler.Body bNew = null;
Autodesk.Aec.Modeler.Body b1 = Autodesk.Aec.Modeler.Body.Cone(new LineSegment3d(new Point3d(0, 0, 8), new Point3d(0, 0, 13)), 2, 1.5, 10);
Autodesk.Aec.Modeler.Body b2 = Autodesk.Aec.Modeler.Body.Sphere(new Point3d(0, 0, 13), 0.5, 10);
Autodesk.Aec.Modeler.Body b3 = Autodesk.Aec.Modeler.Body.Cone(new LineSegment3d(new Point3d(0, 0, 0), new Point3d(0, 0, 8)), 2, 2, 10);
bNew = b1 + b2 + b3;
me.SetBody(bNew, true);
me.Body.Combine(bNew);
BlockTableRecord btrModelSpace = (BlockTableRecord)SymbolUtilityServices.GetBlockModelSpaceId(db).GetObject(OpenMode.ForWrite);
btrModelSpace.AppendEntity(me);
trans.AddNewlyCreatedDBObject(me, true);
AecBldgHvacDbSvcs.DuctFitting df = (AecBldgHvacDbSvcs.DuctFitting)trans.GetObject(prEntRes.ObjectId, OpenMode.ForRead);
if (df.AnchorId.IsNull)
{
ed.WriteMessage("\nAnchoring MassElement to DuctFitting.\n");
AecBldgDbSvcs.AnchorEntityToMember anchor = new AecBldgDbSvcs.AnchorEntityToMember();
anchor.SubSetDatabaseDefaults(db);
anchor.SetToStandard(db);
anchor.AnchorX.OffsetDistance = 15;
anchor.CurveId = df.ObjectId;
me.SetAnchor(anchor);
anchor.ForceUpdateToAnchorEntityToCurve = true;
}
trans.Commit();
}
}