Revit 2019/ VS Community 2017 15.9/ Framework 4.7
Hi All,
Below is a visual step-by-step of what I am trying to accomplish. Below is code and project is attached. Apologies if my code is sloppy. First-timer after watching tutorials and learning from Jeremy Tammik.
First I needed to select walls and store the LocationCurves as Curves in a list to be extruded in the next step. This I completed.
Next, I need to use the curves to generate a new extrusion in a Conceptual Mass Family Document then place the instance back into the current document. I'm close I feel, but an ambiguous error is thrown when calling this line.
return factory.NewExtrusion(true, curveArrArray, sketch, thickness);
I've debugged and found my sketch plane is present from the massing document so the problem may be in the way I have stored my curves from the wall selection (I do claim to not fully understand curveArrArray).
Anyways, if I can manage to get through that headache then my next step would be to divide the bottom surface of the mass (bonus if we can get the user to specify grid sizing, but I can get there eventually).
#region Constants
/// <summary>
/// Family template filename extension
/// </summary>
const string _family_template_ext = ".rft";
/// <summary>
/// Revit family filename extension
/// </summary>
const string _rfa_ext = ".rfa";
/// <summary>
/// Family template library path
/// </summary>
const string _path = @"C:\ProgramData\Autodesk\RVT 2019\Family Templates\English\Conceptual Mass";
/// <summary>
/// Family template filename stem
/// </summary>
const string _family_template_name = "Metric Mass";
// family template path and filename
//const string _path = "C:/ProgramData/Autodesk/RST 2012/Family Templates/English_I";
//const string _family_name = "Structural Stiffener";
/// <summary>
/// Name of the generated family
/// </summary>
const string _family_name = "Arktura_Ceilng";
#endregion
#region Find Element
Element FindElement(
Document doc,
Type targetType,
string targetName)
{
return new FilteredElementCollector(doc)
.OfClass(targetType)
.First<Element>(e => e.Name.Equals(targetName));
}
#endregion
#region CreateExtrusion
public Extrusion CreateExtrusion(Autodesk.Revit.DB.Document doc, CurveArray crvs, double thickness)
{
FamilyItemFactory factory = doc.FamilyCreate;
Autodesk.Revit.Creation.Application creapp = doc.Application.Create;
SketchPlane sketch = FindElement(doc, typeof(SketchPlane), "Level 1") as SketchPlane;
CurveArrArray curveArrArray = new CurveArrArray();
curveArrArray.Append( crvs );
return factory.NewExtrusion(true, curveArrArray, sketch, thickness);
}
#endregion
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//Get UIDocument and Document
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
const double _thicknessMm = 20.0;
try
{
#region Collect Curves from Walls
WallFilter wallf = new WallFilter();
IList<Reference> walls = uidoc.Selection.PickObjects(ObjectType.Element, wallf, "Please Pick Walls to Enclose Ceiling");
TaskDialog.Show("Walls", string.Format("{0} walls counted!", walls.Count));
CurveArray curves = new CurveArray();
List<XYZ> pts = new List<XYZ>();
foreach (Reference wall in walls)
{
ElementId eleId = wall.ElementId;
Element ele = doc.GetElement(eleId);
Curve locc = (ele.Location as LocationCurve).Curve;
curves.Append(locc);
pts.Add(locc.GetEndPoint(0));
}
#endregion
#region Transaction
string templateFileName = Path.Combine(_path,
_family_template_name + _family_template_ext );
Document fdoc = app.NewFamilyDocument(
templateFileName);
if (null == fdoc)
{
message = "Cannot create family document.";
return Result.Failed;
}
Transaction t = new Transaction(fdoc,
"Create structural stiffener family");
t.Start();
CreateExtrusion(fdoc, curves, _thicknessMm);
t.Commit();
// save our new family background document
// and reopen it in the Revit user interface:
string filename = Path.Combine(
Path.GetTempPath(), "Ceiling");
SaveAsOptions opt = new SaveAsOptions();
opt.OverwriteExistingFile = true;
fdoc.SaveAs(filename, opt);
// cannot close the newly generated family file
// if it is the only open document; that throws
// an exception saying "The active document may
// not be closed from the API."
fdoc.Close(false);
#endregion
}
catch (Exception e)
{
message = e.Message;
return Result.Failed;
}
return Result.Succeeded;
}
}
public class WallFilter : ISelectionFilter
{
public bool AllowElement(Element elem)
{
return (elem.Category.Id.IntegerValue.Equals((int)BuiltInCategory.OST_Walls));
}
public bool AllowReference(Reference reference, XYZ position)
{
return false;
}
}
}
Hey All,
First message may have been a bit much. I've actually made progress. Created a surface using NewFormByCap and now I looking to divide the surface. I cannot find the NewDivideSurface method anymore. Is there a method in the revit 2019 API that allows for this?
Can't find what you're looking for? Ask the community or share your knowledge.