Hey all,
I decided to create an example command to further illustrate what I am trying to accomplish and the issues arising:
namespace AutodeskCommunityFormHelpExample { using System; using System.Collections.Generic; using System.Linq; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] [Journaling(JournalingMode.UsingCommandData)] public class CutTrackExampleCommand : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Document activeDoc = commandData.Application.ActiveUIDocument.Document; // Collect a Structural Framing FamilySymbol from the document. // The FamilySymbol used in this example is from the default family library. // C:\ProgramData\Autodesk\RVT 2015\Libraries\US Imperial\Structural Framing\Wood\Dimension Lumber FamilySymbol famSymbol = new FilteredElementCollector(activeDoc) .WherePasses(new ElementClassFilter(typeof(FamilySymbol))) .WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_StructuralFraming)) .Cast<FamilySymbol>().GroupBy(e => e.Family.Name) .Where(e => e.Key.Equals("Dimension Lumber")) .First()
.First(); // Lookup FamilySymbol depth to calculate triangle for cut. double symbolDepth = famSymbol.LookupParameter("d").AsDouble(); // Collect a level to place FamilyInstances on. Level level = new FilteredElementCollector(activeDoc) .WherePasses(new ElementClassFilter(typeof(Level), false)) .Cast<Level>() .OrderBy(l => l.Elevation) .First(); // Create two axes for two FamilyInstances. List<Line> axes = new List<Line>(); axes.Add(Line.CreateBound(new XYZ(0, 0, 10), new XYZ(10, 0, 8))); axes.Add(Line.CreateBound(new XYZ(15, 0, 8), new XYZ(25, 0, 4))); using (Transaction tx = new Transaction(activeDoc, "Example Transaction")) { tx.Start(); foreach (Line axis in axes) { // Create FamilyInstance. FamilyInstance instance = activeDoc.Create.NewFamilyInstance(axis, famSymbol, level, StructuralType.Beam); // Calculate axis direction and normal. XYZ axisStart = axis.GetEndPoint(0); XYZ axisEnd = axis.GetEndPoint(1); XYZ direction = (axisEnd - axisStart) / (axisEnd - axisStart).GetLength(); // Rotate direction 90 degrees to get normal. // Rotating around XYZ.BasisY in this example as we know the axis runs along the X axis with no change in Y. XYZ normal = Transform.CreateRotation(XYZ.BasisY, (Math.PI / 2.0)).OfVector(direction); // Caclulate angle of axis. // Using angle to XYZ.BasisX in this example as we know the axis runs along the X axis. double angle = direction.AngleTo(XYZ.BasisX); // Calculate end points of curves for Structural opening cut. XYZ p0 = axisStart; XYZ p1 = axisStart + (symbolDepth * normal); XYZ p2 = p0 - ((symbolDepth / Math.Cos(angle)) * XYZ.BasisZ); // Create a CurveArray for the Structural opening cut. CurveArray curves = new CurveArray(); curves.Append(Line.CreateBound(p0, p1)); curves.Append(Line.CreateBound(p1, p2)); curves.Append(Line.CreateBound(p2, p0)); activeDoc.Create.NewOpening(instance, curves, Autodesk.Revit.Creation.eRefFace.CenterZ); } tx.Commit(); } return Result.Succeeded; } } }
Unlike my previous attempts, this command is actually not placing even a single Structural opening cut, even though my previous code would place at least one before throwing an error. I will look into my previous code to find what the difference may be, but this command should still be able to get across what I am trying to to do.
The error message resulting from the command is as follows:
If I remove the line that creates the opening and instead place the curves as model lines, eg:
... ////activeDoc.Create.NewOpening(instance, curves, Autodesk.Revit.Creation.eRefFace.CenterZ);
SketchPlane sketchPlane = SketchPlane.Create(activeDoc, new Plane(XYZ.BasisY, XYZ.Zero)); foreach (Curve curve in curves) { activeDoc.Create.NewModelCurve(curve, sketchPlane); } ...
the resulting FamilyInstances with model lines are shown here:
Any help would be greatly appreciated.
Thanks,
Benjamin.