I guess Great minds do think alike.
Just pulled the code for direct shape before your post, it will be an option, but I may just go with the family so I can control the rebar as a group and assign materials etc.
For now I just drew model lines on each face of the compound floor and using routines to collect the lines into individual loops in a curve array array, then will sweep each curve array with the profile of the rebar number.
Eventually will have the user pick the floor and then the direction of the rebar, then the rebar number, then the spacing, then the cover offset for sides and top, and will generate the linework over the floor via the api (cropping the ends by the side cover, then move the whole system down by the top cover amount at the end.
public void FloorRebarGenerate()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
Autodesk.Revit.DB.View activev = doc.ActiveView;
FilteredElementCollector collector = new FilteredElementCollector(doc, doc.ActiveView.Id).WherePasses(new ElementClassFilter(typeof(CurveElement)));
CurveArray carray = new CurveArray();
CurveArrArray carrarray = new CurveArrArray();
ReferenceArray refArray = new ReferenceArray();
foreach (CurveElement cele in collector)
{
ModelLine ml = cele as ModelLine;
Curve cv = ml.GeometryCurve;
carray.Append(cv);
Reference cvref = cv.Reference;
refArray.Append(cvref);
}
CurveArrArray newcurarr = new CurveArrArray();
carrarray.Append(carray);
SortCurveLoops0(carrarray, doc);
SortCurvesContiguousArray(carrarray);
//Solid solid = null;
//solid = GeometryCreationUtilities.CreateSweptGeometry();
//ElementId categoryId = new ElementId(BuiltInCategory.OST_GenericModel);
//DirectShape ds = DirectShape.CreateElement(doc, Guid.NewGuid().ToString());
//solids = new List<GeometryObject>() { solid };
//ds.SetShape(solids);
//ds.Name = "Rebar1";
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Document docfamily;
Family fam;
string ftitle = doc.Title;
string fpath = doc.PathName;
int ftitlelen = ftitle.Length + 4;
int fpathlen = fpath.Length;
int finpathlen = fpathlen - ftitlelen;
string sfinpath = fpath.Substring(0,finpathlen);
string famname = "CompoundRebar";
string fext = ".rfa";
int counter = 1;
while (counter < 100)
{
famname = ("CompoundRebar" + counter as String);
Family family = FindElementByName(doc,typeof(Family),famname)as Family;
if( null == family )
{
sfinpath = (sfinpath + famname + fext);
counter = 200;
}
counter += 1;
}
FilteredElementCollector collector0 = new FilteredElementCollector(doc);
ICollection<Element> collection0 = collector0.WhereElementIsNotElementType().ToElements();
List<FamilySymbol> fsym0 = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().ToList();
FamilySymbol famsymb0 = null;
foreach (FamilySymbol symb in fsym0)
{
if (symb.Name == "CompoundRebarBase")
{
famsymb0 = symb as FamilySymbol;
}
}
fam = famsymb0.Family;
docfamily = doc.EditFamily(fam);
try
{
docfamily.SaveAs(@sfinpath);
}
catch
{
TaskDialog.Show("Revit", "Could Not Save Rebar Family");
}
SketchPlane sketch;
using (Autodesk.Revit.DB.Transaction trans = new Autodesk.Revit.DB.Transaction(docfamily))
{
trans.Start("Make Compound Rebar Family");
ElementId delid = null;
FamilySymbol profsymbol = null;
// Get Profiles
collector = new FilteredElementCollector( docfamily );
foreach(Element element in collector.OfClass(typeof(FamilySymbol)))
{
if (element.Category.Name.ToString() == "Profiles")
{
//TaskDialog.Show("Revit", element.Name.ToString());
if (element.Name.ToString().StartsWith("3/4"))
{
profsymbol = element as FamilySymbol;
}
}
}
//TaskDialog.Show("Revit", profsymbol.ToString());
collector = new FilteredElementCollector( docfamily );
foreach(Element element in collector.OfClass(typeof(GenericForm)))
{
delid = element.Id;
}
try
{
docfamily.Delete(delid);
}
catch
{
}
FilteredElementCollector levcoll = new FilteredElementCollector(docfamily).WherePasses(new ElementClassFilter(typeof(Level), false));
ElementId levid = null;
foreach (Level le in levcoll)
{
//TaskDialog.Show("Revit LevName", le.Name.ToString());
if (le.Name.ToString() == "Ref. Level" && levid == null)
{
//TaskDialog.Show("Revit LevName is Ref Lev", le.Name.ToString());
levid = le.Id as ElementId;
}
}
sketch = SketchPlane.Create(docfamily, levid);
//Sweep sweep = familydoc.FamilyCreate.NewSweep(true, refArray, profile, 0, ProfilePlaneLocation.Start);
trans.Commit();
}
docfamily.Save();
docfamily.LoadFamily(doc, new CustomFamilyLoadOption());
docfamily.Close();
File.Delete(sfinpath);
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TaskDialog.Show("Revit", carrarray.Size.ToString());
//ModelCurve.ChangeToReferenceLine()
// create a circle as bottom shape for the cable
// IList<XYZ> points = sweepPath.GeometryCurve.Tessellate();
// XYZ center = points[0];
// Plane workingPlane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, center);
// Arc bottomShape = Arc.Create(workingPlane, _radius, 0, 2 * Math.PI);
//
// // create profile
// CurveArray curveArray = new CurveArray();
// curveArray.Append(bottomShape);
// CurveArrArray arrArray = new CurveArrArray();
// arrArray.Append(curveArray);
// SweepProfile profile = _rvApp.Create.NewCurveLoopsProfile(arrArray) as SweepProfile;
//
// // create path
// XYZ sweepPathDirection = points[1] - points[0];
// double angle = sweepPathDirection.AngleTo(XYZ.BasisZ);
// XYZ direction = sweepPathDirection.CrossProduct(XYZ.BasisZ);
// Line axis = Line.CreateUnbound(center, direction);
// ElementTransformUtils.RotateElement(familydoc, sweepPath.Id, axis, angle);
// CurveArray path = new CurveArray();
// path.Append(sweepPath.GeometryCurve);
//
// // create sketch plane
// Plane plane = Plane.CreateByNormalAndOrigin(new XYZ(10, 0, 0), refPointArray.get_Item(0).Position);
// SketchPlane pathPlane = SketchPlane.Create(familydoc, plane);
//
// // create the cable
// // Sweep sweep = familydoc.FamilyCreate.NewSweep(true, curveArray, pathPlane, profile, 0, ProfilePlaneLocation.Start);
// ReferenceArray refArray = new ReferenceArray();
// refArray.Append(sweepPath.GeometryCurve.Reference);
// Sweep sweep = familydoc.FamilyCreate.NewSweep(true, refArray, profile, 0, ProfilePlaneLocation.Start);
}

The autodesk response for this functionality was that is was too complex for now, dunno, I'm not a programmer by trade or education, but I will have it in a day or so.