I want to create a new Arrow Type "22 Degree Filled Arrow" and "22 Degree Filled Arrow"
Arrow Style: Arrow
Fill Tick: = ON
Arrow Closed : OFF
Arrow Width Factor = 22deg
Tick Size = 3/32"
I'm looking for a sample or tutoiral that can be used to create new arrow types using the duplicate type.
I'm using the Built In Parameter Checker to get Parameter Names which I can use to change the parameter values above.
For TextNotes I used:
ICollection<ElementId> textNotes
= collectorUsed.OfClass(typeof(TextNote))
.ToElementIds();
But I'm not sure what to replace "TextNote".
using System; using System.Collections.Generic; using System.Collections; using System.Windows.Forms; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using System.Text; using System.Linq; namespace CreateTextType { /// <summary> /// Revit Create Revit Arrow Head Style /// Created by. Matt Fleming C.E.T. /// /// KNOWN LIMITATIONS: /// /// /// </summary> /// <remarks></remarks> /// [Transaction(TransactionMode.Manual)] public class cmdArrowType : IExternalCommand { /// <summary> /// Command Entry Point /// </summary> /// <param name="commandData">Input argument providing access to the Revit application and documents</param> /// <param name="message">Return message to the user in case of error or cancel</param> /// <param name="elements">Return argument to highlight elements on the graphics screen if Result is not Succeeded.</param> /// <returns>Cancelled, Failed or Succeeded</returns> public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { try { // Action Code Starts Here List<Element> ret = new List<Element>(); Document doc = commandData.Application.ActiveUIDocument.Document; /// Retrieve access to all arrowType Elements FilteredElementCollector collectorUsed = new FilteredElementCollector(doc); ICollection<ElementId> arrowTypes = collectorUsed.OfClass(typeof(ArrowType))//ArrowType is Wrong .ToElementIds(); foreach (ElementId arrowTypeId in arrowTypes) { ArrowType arrownote = doc.GetElement(//ArrowType is Wrong arrowTypeid) as ArrowType;//ArrowType is Wrong Transaction trans = new Transaction(doc); trans.Start("CreateNewArrow"); // Create a duplicate Element ele = arrownote.arrowType.Duplicate(newArrowType); arrowTypeType arrowType = ele as arrowTypeType;//arrowTypeType is Wrong // Change font parameter if (null != arrowType) { // Arrow Filled 1 = ON 0 = OFF arrowType.get_Parameter(BuiltInParameter.ARROW_FILLED).Set(1); // Arrow Size Double arrowType.get_Parameter(BuiltInParameter.ARROW_SIZE).Set(0.125); // Arrow Type Integer arrowType.get_Parameter(BuiltInParameter.ARROW_TYPE).Set(8); // Arrow Leader Width Double Degrees arrowType.get_Parameter(BuiltInParameter.ARROW_LEADER_ARROW_WIDTH).Set(22); // Arrow Closed 1 = ON 0 = OFF arrowType.get_Parameter(BuiltInParameter.ARROW_CLOSED).Set(0); } trans.Commit(); } // Return Success return Result.Succeeded; } catch (Exception ex) { // Failure Message message = ex.Message; return Result.Failed; } } } }
Matt
Hi Matt
I would insert an instance of the arrow in the current Revit model and then use the Revit Lookup tool after selecting the instance and dig out the category, type, etc information and plug those in the code.
If you need further help with this, can you please specify which specific family can I use to create an instance of this in a Revit model. Or if you want to include the arrow family file as an attachment, I could take a further look if you need me to. Please do ensure that any of your attachments do not include any confidential information.
hope this helps.
This is a very old question. But I can't find any examples of this on the internet. So posting my finding as an answer. I have created a new arrowhead type as follows,
var provider = new ParameterValueProvider(new ElementId(BuiltInParameter.ALL_MODEL_FAMILY_NAME)); var collector = new FilteredElementCollector(doc).OfClass(typeof(ElementType)).WherePasses(new ElementParameterFilter(new FilterStringRule(provider, new FilterStringEquals(), "Arrowhead", false))); var elements = collector.ToElements().Cast<ElementType>().ToList(); var newArrow = elements.FirstOrDefault(x => x.Name.StartsWith("NEW Arrow")); if (newArrow == null) { var arrowDefault = elements.FirstOrDefault(x => x.Name.StartsWith("Arrow 30")); if (arrowDefault != null) { newArrow = arrowDefault.Duplicate("NEW Arrow"); newArrow.SetParameterValue("Tick Size", 0.01); newArrow.SetParameterValue("Arrow Closed", 1); newArrow.SetParameterValue("Fill Tick", 1); } }
Thank you Gowthaman Selvam, FANTASTIC, this would have taken me 4 hours to figure our.
Instead of SetParameterValue you can use BuiltInParameter like the following:
newArrow.get_Parameter(BuiltInParameter.ARROW_SIZE).Set((3.0) * (1 / 304.8)); newArrow.get_Parameter(BuiltInParameter.ARROW_TYPE).Set("Arrow"); newArrow.get_Parameter(BuiltInParameter.ARROW_CLOSED).Set(0); newArrow.get_Parameter(BuiltInParameter.LEADER_ARROW_WIDTH).Set(Math.PI / 8); newArrow.get_Parameter(BuiltInParameter.ARROW_FILLED).Set(1);
public enum ARROW_TYPE_CONVERT
{
LOOP = 12,
ELEVATION_TARGET = 11,
BOX = 10,
DATUM_TRIANGLE = 9,
ARROW = 8,
HEAVY_END_TICK_MARK = 7,
DOT = 3,
DIAGONAL = 0
}
//and use like
newArrow.get_Parameter(BuiltInParameter.ARROW_TYPE).Set((int)ARROW_TYPE_CONVERT.ARROW);