/// <summary> /// Create the CorbelFrame object with the given trapezoid face, corbel and its host information. /// </summary> /// <param name="corbel">Corbel instance</param> /// <param name="depthEdge">Depth Edge which is vertical with trapezoid face</param> /// <param name="leftEdge">Left edge of trapezoid</param> /// <param name="bottomEdge">Bottom edge of trapezoid</param> /// <param name="rightEdge">Right edge of trapezoid</param> /// <param name="topEdge">Top edge of trapezoid</param> /// <param name="revitDoc">Revit Document</param> /// <param name="trapezoidFace">Trapezoid Face</param> /// <param name="hostDepth">Corbel Host depth</param> /// <param name="hostTopCoverDistance">Corbel Host Top face cover distance</param> /// <returns>CorbelFrame object</returns> private static CorbelFrame ConstructCorbelFrame( FamilyInstance corbel, Edge depthEdge, Edge leftEdge, Edge bottomEdge, Edge rightEdge, Edge topEdge, Document revitDoc, PlanarFace trapezoidFace, double hostDepth, double hostTopCoverDistance) { XYZ leftEdgeDir = (leftEdge.Evaluate(1.0) - leftEdge.Evaluate(0.0)).Normalize(); XYZ leftEdgeV0 = leftEdge.Evaluate(0.0); Line leftEdgeLine = Line.get_Unbound(leftEdgeV0, leftEdgeDir); XYZ rightEdgeDir = (rightEdge.Evaluate(1.0) - rightEdge.Evaluate(0.0)).Normalize(); XYZ rightEdgeV0 = rightEdge.Evaluate(0.0); Line rightEdgeLine = Line.get_Unbound(rightEdgeV0, rightEdgeDir); XYZ topEdgeDir = (topEdge.Evaluate(1.0) - topEdge.Evaluate(0.0)).Normalize(); XYZ topEdgeV0 = topEdge.Evaluate(0.0); Line topEdgeLine = Line.get_Unbound(topEdgeV0, topEdgeDir); IntersectionResultArray intersections; topEdgeLine.Intersect(leftEdgeLine, out intersections); XYZ prevX = intersections.get_Item(0).XYZPoint; topEdgeLine.Intersect(rightEdgeLine, out intersections); XYZ nextX = intersections.get_Item(0).XYZPoint; XYZ edgeV0 = GetCommonVertex(bottomEdge, leftEdge); XYZ edgeV1 = GetCommonVertex(bottomEdge, rightEdge); Line topBoundLine = Line.get_Bound(nextX, prevX); Line leftBoundLine = Line.get_Bound(prevX, edgeV0); Line bottomBoundLine = Line.get_Bound(edgeV0, edgeV1); Line rightBoundLine = Line.get_Bound(edgeV1, nextX); Trapezoid profile = new Trapezoid(topBoundLine, leftBoundLine, bottomBoundLine, rightBoundLine); XYZ depthEdgeV0 = depthEdge.Evaluate(0.0); XYZ depthEdgeV1 = depthEdge.Evaluate(1.0); Line depthLine = null; if (depthEdgeV0.IsAlmostEqualTo(edgeV0)) { depthLine = Line.get_Bound(depthEdgeV0, depthEdgeV1); } else if (depthEdgeV1.IsAlmostEqualTo(edgeV0)) { depthLine = Line.get_Bound(depthEdgeV1, depthEdgeV0); } CorbelFrame frame = new CorbelFrame(corbel, profile, depthLine, hostDepth, hostTopCoverDistance); return(frame); }
///<summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements) { // A List to store the Corbels which are suitable to be reinforced. List <CorbelFrame> corbelsToReinforce = new List <CorbelFrame>(); // Filter out the Corbels which can be reinforced by this sample // from the selected elements. ElementSet elems = new ElementSet(); foreach (ElementId elementId in commandData.Application.ActiveUIDocument.Selection.GetElementIds()) { elems.Insert(commandData.Application.ActiveUIDocument.Document.GetElement(elementId)); } foreach (Element elem in elems) { FamilyInstance corbel = elem as FamilyInstance; // Make sure it's a Corbel firstly. if (corbel != null && IsCorbel(corbel)) { try { // If the Corbel is sloped, this should return a non-null object. CorbelFrame frame = CorbelFrame.Parse(corbel); corbelsToReinforce.Add(frame); } // If the Corbel is not sloped, it will throw exception. catch (System.Exception ex) { // Collect the error message, in case there is no any suitable corbel to be reinforced, // Let user know what's happened. message += ex.ToString(); } } } // Check to see if there is any Corbel to be reinforced. if (corbelsToReinforce.Count == 0) { // If there is no suitable Corbel to be reinforced, prompt a message. if (string.IsNullOrEmpty(message)) { message += "Please select sloped corbels."; } // Return cancelled for invalid selection. return(Result.Cancelled); } // Show a model dialog to get Rebar creation options. Document revitDoc = commandData.Application.ActiveUIDocument.Document; CorbelReinforcementOptions reinforcementOptions = new CorbelReinforcementOptions(revitDoc); using (CorbelReinforcementOptionsForm reinforcementOptionsForm = new CorbelReinforcementOptionsForm(reinforcementOptions)) { if (reinforcementOptionsForm.ShowDialog() == DialogResult.Cancel) { // Cancelled by user. return(Result.Cancelled); } } // Encapsulate operation "Reinforce Corbels" into one transaction. Transaction reinforceTransaction = new Transaction(revitDoc); try { // Start the transaction. reinforceTransaction.Start("Reinforce Corbels"); // Reinforce all the corbels in list. foreach (CorbelFrame corbel in corbelsToReinforce) { // Reinforce the sloped Corbel. corbel.Reinforce(reinforcementOptions); } // Submit the transaction reinforceTransaction.Commit(); } catch (System.Exception ex) { // Rollback the transaction for any exception. reinforceTransaction.RollBack(); message += ex.ToString(); // Return failed for any exception. return(Result.Failed); } // No any error, return succeeded. return(Result.Succeeded); }
/// <summary> /// Create the CorbelFrame object with the given trapezoid face, corbel and its host information. /// </summary> /// <param name="corbel">Corbel instance</param> /// <param name="depthEdge">Depth Edge which is vertical with trapezoid face</param> /// <param name="leftEdge">Left edge of trapezoid</param> /// <param name="bottomEdge">Bottom edge of trapezoid</param> /// <param name="rightEdge">Right edge of trapezoid</param> /// <param name="topEdge">Top edge of trapezoid</param> /// <param name="revitDoc">Revit Document</param> /// <param name="trapezoidFace">Trapezoid Face</param> /// <param name="hostDepth">Corbel Host depth</param> /// <param name="hostTopCoverDistance">Corbel Host Top face cover distance</param> /// <returns>CorbelFrame object</returns> private static CorbelFrame ConstructCorbelFrame( FamilyInstance corbel, Edge depthEdge, Edge leftEdge, Edge bottomEdge, Edge rightEdge, Edge topEdge, Document revitDoc, PlanarFace trapezoidFace, double hostDepth, double hostTopCoverDistance) { XYZ leftEdgeDir = (leftEdge.Evaluate(1.0) - leftEdge.Evaluate(0.0)).Normalize(); XYZ leftEdgeV0 = leftEdge.Evaluate(0.0); Line leftEdgeLine = Line.get_Unbound(leftEdgeV0, leftEdgeDir); XYZ rightEdgeDir = (rightEdge.Evaluate(1.0) - rightEdge.Evaluate(0.0)).Normalize(); XYZ rightEdgeV0 = rightEdge.Evaluate(0.0); Line rightEdgeLine = Line.get_Unbound(rightEdgeV0, rightEdgeDir); XYZ topEdgeDir = (topEdge.Evaluate(1.0) - topEdge.Evaluate(0.0)).Normalize(); XYZ topEdgeV0 = topEdge.Evaluate(0.0); Line topEdgeLine = Line.get_Unbound(topEdgeV0, topEdgeDir); IntersectionResultArray intersections; topEdgeLine.Intersect(leftEdgeLine, out intersections); XYZ prevX = intersections.get_Item(0).XYZPoint; topEdgeLine.Intersect(rightEdgeLine, out intersections); XYZ nextX = intersections.get_Item(0).XYZPoint; XYZ edgeV0 = GetCommonVertex(bottomEdge, leftEdge); XYZ edgeV1 = GetCommonVertex(bottomEdge, rightEdge); Line topBoundLine = Line.get_Bound(nextX, prevX); Line leftBoundLine = Line.get_Bound(prevX, edgeV0); Line bottomBoundLine = Line.get_Bound(edgeV0, edgeV1); Line rightBoundLine = Line.get_Bound(edgeV1, nextX); Trapezoid profile = new Trapezoid(topBoundLine, leftBoundLine, bottomBoundLine, rightBoundLine); XYZ depthEdgeV0 = depthEdge.Evaluate(0.0); XYZ depthEdgeV1 = depthEdge.Evaluate(1.0); Line depthLine = null; if (depthEdgeV0.IsAlmostEqualTo(edgeV0)) { depthLine = Line.get_Bound(depthEdgeV0, depthEdgeV1); } else if (depthEdgeV1.IsAlmostEqualTo(edgeV0)) { depthLine = Line.get_Bound(depthEdgeV1, depthEdgeV0); } CorbelFrame frame = new CorbelFrame(corbel, profile, depthLine, hostDepth, hostTopCoverDistance); return frame; }