/// <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 virtual Result Execute(ExternalCommandData commandData , ref string message, ElementSet elements) { // Get the document from external command data. UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; if (null == doc) { return(Result.Failed); } // The transaction and its status, using Revit's Transaction class Autodesk.Revit.DB.Transaction trans = new Autodesk.Revit.DB.Transaction(doc, "Delete structural connection"); TransactionStatus ts = TransactionStatus.Uninitialized; try { // We get the connection to be deleted. We use Revit's StructuralConnectionHandler class // for more details, please consult http://www.autodesk.com/adv-steel-api-walkthroughs-2019-enu StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc); if (null == conn) { return(Result.Failed); } // Start the transaction. trans.Start(); // Delete selected structural connection. doc.Delete(conn.Id); // Commit the transaction ts = trans.Commit(); if (ts != TransactionStatus.Committed) { message = "Failed to commit the current transaction !"; trans.RollBack(); return(Result.Failed); } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); return(Result.Cancelled); } return(Result.Succeeded); }
/// <summary> /// Loads one ore more family documents into a specified family document. /// </summary> /// <param name="pathToContainerFamily">Path to the document into which the families will be loaded.</param> /// <param name="pathToFamiliesToLoad">Path to the families to load.</param> /// <returns></returns> public static bool LoadFamilyIntoFamilyDocument(string pathToContainerFamily, string[] pathToFamiliesToLoad) { Autodesk.Revit.DB.Document familyDoc = null; var app = DocumentManager.Instance.CurrentUIApplication.Application; familyDoc = app.OpenDocumentFile(pathToContainerFamily); if (!familyDoc.IsFamilyDocument) { throw new ArgumentException("The specified document is not a family document (.rfa)"); } using (Autodesk.Revit.DB.Transaction transaction = new Autodesk.Revit.DB.Transaction(familyDoc)) { if (transaction.Start("Load family into family") == TransactionStatus.Started) { for (int i = 0; i < pathToFamiliesToLoad.Length; i++) { familyDoc.LoadFamily(pathToFamiliesToLoad[i]); } if (TransactionStatus.Committed != transaction.Commit()) { transaction.RollBack(); } } } // The Close() method saves the document familyDoc.Close(); return(true); }
public void CreateInDynamoModifyInRevitToCauseFailure() { //Create a wall in Dynamo string dynFilePath = Path.Combine(workingDirectory, @".\ElementBinding\CreateWallInDynamo.dyn"); string testPath = Path.GetFullPath(dynFilePath); ViewModel.OpenCommand.Execute(testPath); RunCurrentModel(); //Modify the wall in Revit using (var trans = new Transaction(DocumentManager.Instance.CurrentUIDocument.Document, "ModifyInRevit")) { bool hasError = false; trans.Start(); try { IList <Element> rps = GetAllWallElements(false); Assert.AreEqual(1, rps.Count); Wall wall = rps.First() as Wall; List <XYZ> ctrlPnts = new List <XYZ>(); ctrlPnts.Add(new XYZ(0.0, 1.0, 0.0)); ctrlPnts.Add(new XYZ(1.0, 0.0, 0.0)); ctrlPnts.Add(new XYZ(2.0, 0.0, 0.0)); ctrlPnts.Add(new XYZ(3.0, 1.0, 0.0)); List <double> weights = new List <double>(); weights.Add(1.0); weights.Add(1.0); weights.Add(1.0); weights.Add(1.0); var spline = NurbSpline.Create(ctrlPnts, weights); var wallLocation = wall.Location as LocationCurve; wallLocation.Curve = spline; } catch (Exception e) { hasError = true; trans.RollBack(); } if (!hasError) { trans.Commit(); } } RunCurrentModel(); IList <Element> rps2 = GetAllWallElements(false); Assert.AreEqual(1, rps2.Count); }
protected void CommitTransaction(DB.Document doc, DB.Transaction transaction) { var options = transaction.GetFailureHandlingOptions(); #if !DEBUG options = options.SetClearAfterRollback(true); #endif options = options.SetDelayedMiniWarnings(true); options = options.SetForcedModalHandling(true); options = options.SetFailuresPreprocessor(this); options = options.SetTransactionFinalizer(this); // Disable Rhino UI if any warning-error dialog popup { External.EditScope editScope = null; EventHandler <DialogBoxShowingEventArgs> _ = null; try { Revit.ApplicationUI.DialogBoxShowing += _ = (sender, args) => { if (editScope is null) { editScope = new External.EditScope(); } }; if (transaction.GetStatus() == DB.TransactionStatus.Started) { OnBeforeCommit(doc, transaction.GetName()); transaction.Commit(options); } else { transaction.RollBack(options); } } finally { Revit.ApplicationUI.DialogBoxShowing -= _; if (editScope is IDisposable disposable) { disposable.Dispose(); } } } }
internal static bool PickPointOnFace(UIDocument doc, string prompt, out DB.XYZ point, ObjectSnapTypes snapSettings = DefaultSnapTypes) { point = null; if (doc.ActiveView.ViewType != DB.ViewType.ThreeD) { try { point = doc.Selection.PickPoint(snapSettings, prompt + "Please pick a point on the current work plane"); } catch (OperationCanceledException) { } } else { var reference = doc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Face, prompt + "Please select a face to define a work plane"); if (doc.Document.GetElement(reference.ElementId) is DB.Element element) { if (element.GetGeometryObjectFromReference(reference) is DB.Face face) { if (Keyboard.IsKeyDown(Key.LeftCtrl)) { point = face.Evaluate(reference.UVPoint); } else { var plane = DB.Plane.CreateByNormalAndOrigin(face.ComputeNormal(reference.UVPoint), face.Evaluate(reference.UVPoint)); using (var transaction = new DB.Transaction(doc.Document)) { transaction.Start("PickPointOnFace"); doc.ActiveView.SketchPlane = DB.SketchPlane.Create(doc.Document, plane); doc.ActiveView.ShowActiveWorkPlane(); try { point = doc.Selection.PickPoint(snapSettings, prompt + "Please pick a point on the defined work plane"); } catch (OperationCanceledException) { } transaction.RollBack(); } } } } } return(null != point); }
/// <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 virtual Result Execute(ExternalCommandData commandData , ref string message, ElementSet elements) { // Get the document from external command data. UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; if (null == doc) { return(Result.Failed); } // The transaction and its status, using Revit's Transaction class Autodesk.Revit.DB.Transaction trans = new Autodesk.Revit.DB.Transaction(doc, "Remove subelements from custom connection"); TransactionStatus ts = TransactionStatus.Uninitialized; try { // Selecting the custom connection, using Revit's StructuralConnectionHandler class // for more details, please consult http://www.autodesk.com/adv-steel-api-walkthroughs-2019-enu StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc); // If the connection is not a custom one if (!(conn.IsCustom())) { return(Result.Failed); } IList <Subelement> ide = new List <Subelement>(); // Prompt to select subelements IList <Reference> refs = activeDoc.Selection.PickObjects(ObjectType.Subelement, "Select subelements:").ToList(); // Populate the reference list foreach (Reference eRef in refs) { ide.Add(doc.GetSubelement(eRef)); } if (ide.Count <= 0) { return(Result.Failed); } // Start the transaction trans.Start(); // Removing the subelements from the custom connection StructuralConnectionHandlerType.RemoveMainSubelementsFromCustomConnection(conn, ide); // Committing the transaction ts = trans.Commit(); if (ts != TransactionStatus.Committed) { message = "Failed to commit the current transaction !"; trans.RollBack(); return(Result.Failed); } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); return(Result.Cancelled); } catch (Autodesk.Revit.Exceptions.ArgumentException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); message = "Custom connection already contains the selected element(s)! / Can't delete all subelements!"; return(Result.Failed); } return(Result.Succeeded); }
/// <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 virtual Result Execute(ExternalCommandData commandData , ref string message, ElementSet elements) { // Get the document from external command data. UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; if (null == doc) { return(Result.Failed); } // The transaction and its status, using Revit's Transaction class Autodesk.Revit.DB.Transaction trans = new Autodesk.Revit.DB.Transaction(doc, "Remove element(s) from structural connection"); TransactionStatus ts = TransactionStatus.Uninitialized; try { // Select the connection we need to remove elements from. // We use Revit's StructuralConnectionHandler class for the connection. // for more details, please consult http://www.autodesk.com/adv-steel-api-walkthroughs-2019-enu StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc); if (null == conn) { return(Result.Failed); } // Select elements to remove from connection. IList <ElementId> ids = Utilities.Functions.SelectConnectionElements(activeDoc, "Select elements to remove from connection :"); if (ids.Count() <= 0) { return(Result.Failed); } // Starting the transaction trans.Start(); // Removing the elements from the connection conn.RemoveElementIds(ids); // Committing the transaction ts = trans.Commit(); if (ts != TransactionStatus.Committed) { message = "Failed to commit the current transaction !"; if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } return(Result.Failed); } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); return(Result.Cancelled); } catch (Autodesk.Revit.Exceptions.ArgumentException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); message = "Invalid elements selected!"; return(Result.Failed); } return(Result.Succeeded); }
/// <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 virtual Result Execute(ExternalCommandData commandData , ref string message, ElementSet elements) { // Get the document from external command data. UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; if (null == doc) { return(Result.Failed); } // The transaction and its status. We use Revit's Transaction class for this purpose Autodesk.Revit.DB.Transaction trans = new Autodesk.Revit.DB.Transaction(doc, "Add ranges of applicability"); TransactionStatus ts = TransactionStatus.Uninitialized; try { // Select the connection to add ranges, using Revit's StructuralConnectionHandler class StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc); if (null == conn) { return(Result.Failed); } StructuralConnectionHandlerType connectionType = doc.GetElement(conn.GetTypeId()) as StructuralConnectionHandlerType; if (null == connectionType) { return(Result.Failed); } RuleApplicabilityRangeTable rangeTable = ApplicabilityRangesAccess.GetRanges(connectionType); // Create the rows and add the conditions to them RuleApplicabilityRangeRow rangeRow1 = new RuleApplicabilityRangeRow(); rangeRow1.Key = "My new range 1"; rangeRow1.Ranges = CreateConditionsForRow1(); RuleApplicabilityRangeRow rangeRow2 = new RuleApplicabilityRangeRow(); rangeRow2.Key = "My new range 2"; rangeRow2.Ranges = CreateConditionsForRow2(); // get existing rows RuleApplicabilityRangeRow[] rows = rangeTable.Rows; RuleApplicabilityRangeRow[] newRows = new RuleApplicabilityRangeRow[] { rangeRow1, rangeRow2 }; // set back the rows rangeTable.Rows = rows.Concat(newRows).ToArray(); // we can also verify if the conditions added in the ranges are met. If the result is false it means that the input elements are out of the defined conditions bool validate = ApplicabilityRangeValidator.Validate(conn, rangeTable, "Revit", ""); // Start the transaction trans.Start(); // Save the ranges ApplicabilityRangesAccess.SaveRanges(connectionType, rangeTable); // Commit the transaction ts = trans.Commit(); if (ts != TransactionStatus.Committed) { message = "Failed to commit the current transaction !"; trans.RollBack(); return(Result.Failed); } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); return(Result.Cancelled); } catch (Autodesk.Revit.Exceptions.ArgumentException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); message = "Failed to add ranges"; return(Result.Failed); } return(Result.Succeeded); }
/// <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 virtual Result Execute(ExternalCommandData commandData , ref string message, ElementSet elements) { // Get the document from external command data. UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; if (null == doc) { return(Result.Failed); } // The transaction and its status. We use Revit's Transaction class for this purpose Autodesk.Revit.DB.Transaction trans = new Autodesk.Revit.DB.Transaction(doc, "Add element(s) to custom connection"); TransactionStatus ts = TransactionStatus.Uninitialized; try { // Selecting the custom connection, using Revit's StructuralConnectionHandler class // for more details, please consult http://www.autodesk.com/adv-steel-api-walkthroughs-2019-enu StructuralConnectionHandler conn = Utilities.Functions.SelectConnection(activeDoc); if (null == conn) { return(Result.Failed); } if (!(conn.IsCustom())) { return(Result.Failed); } // Select elements to add to connection. IList <Reference> refs = Utilities.Functions.SelectConnectionElementsCustom(activeDoc); if (refs.Count() <= 0) { return(Result.Failed); } // Start transaction trans.Start(); // Adding the elements to the custom connection, using Revit's StructuralConnectionHandlerType class StructuralConnectionHandlerType.AddElementsToCustomConnection(conn, refs); // Commit the transaction ts = trans.Commit(); if (ts != TransactionStatus.Committed) { message = "Failed to commit the current transaction !"; trans.RollBack(); return(Result.Failed); } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); return(Result.Cancelled); } catch (Autodesk.Revit.Exceptions.ArgumentException) { if (ts != TransactionStatus.Uninitialized) { trans.RollBack(); } trans.Dispose(); message = "Custom connection already contains the selected element(s)!"; return(Result.Failed); } return(Result.Succeeded); }