//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Autodesk.Revit;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI.Selection;
using Reference = Autodesk.Revit.DB.Reference;
using Exceptions = Autodesk.Revit.Exceptions;
using Creation = Autodesk.Revit.Creation;
using DialogResult = System.Windows.Forms.DialogResult;
namespace Revit.SDK.Samples.Selections.CS
{
#region A Class For Element Picks And Deletion
///
/// This command allows to pick some elements and then delete from document.
///
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
public class PickforDeletion : Autodesk.Revit.UI.IExternalCommand
{
///
/// store the application
///
UIApplication m_application;
///
/// store the document
///
UIDocument m_document;
///
/// Implement this method as an external command for Revit.
///
/// An object that is passed to the external application
/// which contains data related to the command,
/// such as the application object and active view.
/// 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.
/// A set of elements to which the external application
/// can add elements that are to be highlighted in case of failure or cancellation.
/// 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.
public Result Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, ElementSet elements)
{
m_application = commandData.Application;
m_document = m_application.ActiveUIDocument;
Transaction trans = new Transaction(m_document.Document, "PickforDeletion");
trans.Start();
try
{
// Select elements. Click "Finish" or "Cancel" buttons on the dialog bar to complete the selection operation.
List elemDeleteList = new List();
IList eRefList = m_document.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, "Please pick some element to delete. ESC for Cancel.");
foreach (Reference eRef in eRefList)
{
if (eRef != null && eRef.ElementId != ElementId.InvalidElementId)
{
elemDeleteList.Add(eRef.ElementId);
}
}
// Delete elements
m_document.Document.Delete(elemDeleteList);
trans.Commit();
return Result.Succeeded;
}
catch (Exceptions.OperationCanceledException)
{
// Selection Cancelled.
trans.RollBack();
return Result.Cancelled;
}
catch (Exception ex)
{
// If any error, give error information and return failed
message = ex.Message;
trans.RollBack();
return Result.Failed;
}
}
}
#endregion PickforDeletion
#region A Class For Place Window At Point On Wall Face
///
/// This command allows to pick a point on wall face, and then place a window with Fixed 36" x 48" type to the point.
///
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class PlaceAtPointOnWallFace : Autodesk.Revit.UI.IExternalCommand
{
///
/// store the application
///
UIApplication m_application;
///
/// store the document
///
UIDocument m_document;
///
/// Implement this method as an external command for Revit.
///
/// An object that is passed to the external application
/// which contains data related to the command,
/// such as the application object and active view.
/// 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.
/// A set of elements to which the external application
/// can add elements that are to be highlighted in case of failure or cancellation.
/// 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.
public Result Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
m_application = commandData.Application;
m_document = m_application.ActiveUIDocument;
// Pick a point on wall face.
Reference pickedRefer = PickPointOnWallFace();
if (pickedRefer != null)
{
Transaction trans = new Transaction(m_document.Document, "PlaceAtPointOnWallFace");
trans.Start();
// Place the 36" x 48" window at the reference.
PlaceWindowAtReference(pickedRefer);
trans.Commit();
}
else
{
return Result.Cancelled;
}
return Result.Succeeded;
}
catch (Exception ex)
{
// If any error, give error information and return failed
message = ex.Message;
return Result.Failed;
}
}
///
/// Pick a point on wall face.
///
/// The point reference picked on wall face. Null for selection cancel.
protected Reference PickPointOnWallFace()
{
try
{
return m_document.Selection.PickObject(ObjectType.PointOnElement, new WallFaceFilter(m_document.Document), "Please pick a point on Wall face.");
}
catch (Exceptions.OperationCanceledException)
{
return null;
}
}
///
/// // Place the 36" x 48" window at the reference.
///
/// The point reference picked from wall face.
protected void PlaceWindowAtReference(Reference eRef)
{
// Find the window type 36" x 48".
FamilySymbol windowType = FindFamilySymbol("36\" x 48\"");
if (windowType != null)
{
// Create the window.
m_document.Document.Create.NewFamilyInstance(eRef.GlobalPoint, windowType, m_document.Document.GetElement(eRef), StructuralType.NonStructural);
}
}
///
/// Finding a Family Symbol with symbol name.
///
/// The name of FamilySymbol to be found.
/// The specific FamilySymbol.
internal FamilySymbol FindFamilySymbol(string symbolName)
{
FilteredElementCollector elemCollector = new FilteredElementCollector(m_document.Document);
elemCollector.WhereElementIsElementType();
var query = from element in elemCollector where element.Name == symbolName select element;
Element elemType = query.Single();
return elemType as FamilySymbol;
}
}
#endregion PlaceAtPointOnWallFace
#region A Class For Pick Face, Set WorkPlane, Pick Point
///
/// This command allows to pick a face and set the work plane on it, then pick a point on the work plane as center to create a model circle.
///
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class PlaceAtPickedFaceWorkplane : Autodesk.Revit.UI.IExternalCommand
{
///
/// store the application.
///
UIApplication m_application;
///
/// store the document
///
UIDocument m_document;
///
/// For basic creation.
///
Creation.ItemFactoryBase m_CreationBase;
///
/// Implement this method as an external command for Revit.
///
/// An object that is passed to the external application
/// which contains data related to the command,
/// such as the application object and active view.
/// 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.
/// A set of elements to which the external application
/// can add elements that are to be highlighted in case of failure or cancellation.
/// 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.
public Result Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
m_application = commandData.Application;
m_document = m_application.ActiveUIDocument;
if (m_document.Document.IsFamilyDocument)
m_CreationBase = m_document.Document.FamilyCreate;
else
m_CreationBase = m_document.Document.Create;
//Pick a face from UI, create a new sketch plane via the face and set it to the current view.
Reference faceRef = m_document.Selection.PickObject(ObjectType.Face, new PlanarFaceFilter(m_document.Document), "Please pick a planar face to set the work plane. ESC for cancel.");
GeometryObject geoObject = m_document.Document.GetElement(faceRef).GetGeometryObjectFromReference(faceRef);
PlanarFace planarFace = geoObject as PlanarFace;
SketchPlane faceSketchPlane = CreateSketchPlane(planarFace.FaceNormal, planarFace.Origin);
if (faceSketchPlane != null)
{
Transaction changeSketchPlane = new Transaction(m_document.Document, "Change Sketch Plane.");
changeSketchPlane.Start();
m_document.Document.ActiveView.SketchPlane = faceSketchPlane;
m_document.Document.ActiveView.ShowActiveWorkPlane();
changeSketchPlane.Commit();
}
// Pick point from current work plane with snaps.
ObjectSnapTypes snapType = ObjectSnapTypes.Centers | ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections
| ObjectSnapTypes.Midpoints | ObjectSnapTypes.Nearest | ObjectSnapTypes.WorkPlaneGrid;
XYZ point = m_document.Selection.PickPoint(snapType, "Please pick a point to place component.");
// Create a model curve by a circle with picked point as center.
Transaction createModelCurve = new Transaction(m_document.Document, "Create a circle.");
createModelCurve.Start();
Curve circle = Arc.Create(point, 5, 0, Math.PI * 2, faceSketchPlane.GetPlane().XVec, faceSketchPlane.GetPlane().YVec);
m_CreationBase.NewModelCurve(circle, faceSketchPlane);
createModelCurve.Commit();
return Result.Succeeded;
}
catch (Exceptions.OperationCanceledException)
{
// Selection Cancelled. For picking face and picking point.
return Result.Cancelled;
}
catch (System.Exception ex)
{
// If any error, give error information and return failed
message = ex.Message;
return Result.Failed;
}
}
///
/// Create a sketch plane via given normal and origin points.
///
/// The vector for normal of sketch plane.
/// The vector for origin of sketch plane.
/// The new sketch plane created by specific normal and origin.
internal SketchPlane CreateSketchPlane(Autodesk.Revit.DB.XYZ normal, Autodesk.Revit.DB.XYZ origin)
{
// First create a Geometry.Plane which need in NewSketchPlane() method
Plane geometryPlane = Plane.CreateByNormalAndOrigin(normal, origin);
// Then create a sketch plane using the Geometry Plane
Transaction createSketchPlane = new Transaction(m_document.Document, "Create a sketch plane.");
createSketchPlane.Start();
SketchPlane plane = SketchPlane.Create(m_document.Document, geometryPlane);
createSketchPlane.Commit();
return plane;
}
}
#endregion PlaceAtPickedFaceWorkplane
#region A Class For Select Objects From Dialog
///
/// This command allows to pick an element and a point from dialog. After picking the point, the element will be moved to the picked point.
///
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class SelectionDialog : Autodesk.Revit.UI.IExternalCommand
{
///
/// Implement this method as an external command for Revit.
///
/// An object that is passed to the external application
/// which contains data related to the command,
/// such as the application object and active view.
/// 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.
/// A set of elements to which the external application
/// can add elements that are to be highlighted in case of failure or cancellation.
/// 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.
public Result Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
SelectionManager manager = new SelectionManager(commandData);
// Create a form to select objects.
DialogResult result = System.Windows.Forms.DialogResult.None;
while (result == DialogResult.None || result == DialogResult.Retry)
{
// Picking Objects.
if (result == DialogResult.Retry)
{
manager.SelectObjects();
}
// Show the dialog.
using (SelectionForm selectionForm = new SelectionForm(manager))
{
result = selectionForm.ShowDialog();
}
}
return Autodesk.Revit.UI.Result.Succeeded;
}
catch (Exception ex)
{
// If any error, give error information and return failed
message = ex.Message;
return Autodesk.Revit.UI.Result.Failed;
}
}
}
#endregion SelectionDialog
}