예제 #1
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            FamilyInstance inst =
                LabUtils.GetSingleSelectedElementOrPrompt(
                    uidoc, typeof(FamilyInstance))
                as FamilyInstance;

            if (null == inst)
            {
                LabUtils.ErrorMsg(
                    "Selected element is not a "
                    + "standard family instance.");

                return(Result.Cancelled);
            }

            // determine selected instance category:

            Category instCat = inst.Category;

            Dictionary <string, List <FamilySymbol> >
            mapFamilyToSymbols
                = new Dictionary <string, List <FamilySymbol> >();

            {
                WaitCursor waitCursor = new WaitCursor();

                // Collect all types applicable to this category and sort them into
                // a dictionary mapping the family name to a list of its types.
                //
                // We create a collection of all loaded families for this category
                // and for each one, the list of all loaded types (symbols).
                //
                // There are many ways how to store the matching objects, but we choose
                // whatever is most suitable for the relevant UI. We could use Revit's
                // generic Map class, but it is probably more efficient to use the .NET
                // strongly-typed Dictionary with
                // KEY = Family name (String)
                // VALUE = list of corresponding FamilySymbol objects
                //
                // find all corresponding families and types:

                FilteredElementCollector families
                    = new FilteredElementCollector(doc);

                families.OfClass(typeof(Family));

                foreach (Family f in families)
                {
                    bool categoryMatches = false;

                    ISet <ElementId> ids = f.GetFamilySymbolIds(); // 2015

                    // we cannot trust f.Category or
                    // f.FamilyCategory, so grab the category
                    // from first family symbol instead:

                    //foreach( FamilySymbol sym in f.Symbols ) // 2014

                    foreach (ElementId id in ids) // 2015
                    {
                        Element symbol = doc.GetElement(id);

                        categoryMatches = symbol.Category.Id.Equals(
                            instCat.Id);

                        break;
                    }

                    if (categoryMatches)
                    {
                        List <FamilySymbol> symbols
                            = new List <FamilySymbol>();

                        //foreach( FamilySymbol sym in f.Symbols ) // 2014
                        foreach (ElementId id in ids) // 2015
                        {
                            FamilySymbol symbol = doc.GetElement(id) as FamilySymbol;

                            symbols.Add(symbol);
                        }

                        mapFamilyToSymbols.Add(f.Name, symbols);
                    }
                }
            }

            // display the form allowing the user to select
            // a family and a type, and assign this type
            // to the instance.

            Lab3_4_Form form
                = new Lab3_4_Form(mapFamilyToSymbols);

            if (System.Windows.Forms.DialogResult.OK
                == form.ShowDialog())
            {
                using (Transaction t = new Transaction(doc))
                {
                    t.Start("Change Selected Instance Type");
                    inst.Symbol = form.cmbType.SelectedItem
                                  as FamilySymbol;
                    t.Commit();
                }

                LabUtils.InfoMsg(
                    "Successfully changed family : type to "
                    + form.cmbFamily.Text + " : "
                    + form.cmbType.Text);
            }
            return(Result.Succeeded);
        }
예제 #2
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            try
            {
                WaitCursor    waitCursor = new WaitCursor();
                UIApplication app        = commandData.Application;
                Document      doc        = app.ActiveUIDocument.Document;
                Autodesk.Revit.Creation.Application createApp = app.Application.Create;
                Autodesk.Revit.Creation.Document    createDoc = doc.Create;

                using (Transaction t = new Transaction(doc))
                {
                    t.Start("Create Little House");

                    // Determine the four corners of the rectangular house:

                    double width = 7 * LabConstants.MeterToFeet;
                    double depth = 4 * LabConstants.MeterToFeet;

                    List <XYZ> corners = new List <XYZ>(4);

                    corners.Add(XYZ.Zero);
                    corners.Add(new XYZ(width, 0, 0));
                    corners.Add(new XYZ(width, depth, 0));
                    corners.Add(new XYZ(0, depth, 0));

                    #region Test creating two levels
#if CREATE_TWO_LEVELS
                    Level          levelBottom = null;
                    Level          levelMiddle = null;
                    Level          levelTop    = null;
                    List <Element> levels      = new List <Element>();

                    Filter filterType
                        = createApp.Filter.NewTypeFilter(
                              typeof(Level));

                    doc.get_Elements(filterType, levels);
                    foreach (Element e in levels)
                    {
                        if (null == levelBottom)
                        {
                            levelBottom = e as Level;
                        }
                        else if (null == levelMiddle)
                        {
                            levelMiddle = e as Level;
                        }
                        else if (null == levelTop)
                        {
                            levelTop = e as Level;
                        }
                        else
                        {
                            break;
                        }
                    }

                    BuiltInParameter topLevelParam
                        = BuiltInParameter.WALL_HEIGHT_TYPE;

                    Line      line;
                    Wall      wall;
                    Parameter param;

                    ElementId   topId = levelMiddle.Id;
                    List <Wall> walls = new List <Wall>(8);
                    for (int i = 0; i < 4; ++i)
                    {
                        line = createApp.NewLineBound(
                            corners[i], corners[3 == i ? 0 : i + 1]);

                        wall = createDoc.NewWall(
                            line, levelBottom, false);

                        param = wall.get_Parameter(topLevelParam);
                        param.Set(ref topId);
                        walls.Add(wall);
                    }

                    topId = levelTop.Id;
                    for (int i = 0; i < 4; ++i)
                    {
                        line = createApp.NewLineBound(
                            corners[i], corners[3 == i ? 0 : i + 1]);

                        wall = createDoc.NewWall(
                            line, levelMiddle, false);

                        param = wall.get_Parameter(topLevelParam);
                        param.Set(ref topId);
                        walls.Add(wall);
                    }

                    List <Element> doorSymbols
                        = LabUtils.GetAllFamilySymbols(
                              app, BuiltInCategory.OST_Doors);

                    Debug.Assert(
                        0 < doorSymbols.Count,
                        "expected at least one door symbol"
                        + " to be loaded into project");

                    FamilySymbol door
                        = doorSymbols[0] as FamilySymbol;

                    XYZ midpoint = LabUtils.Midpoint(
                        corners[0], corners[1]);

                    FamilyInstance inst0
                        = createDoc.NewFamilyInstance(
                              midpoint, door, walls[0], levelBottom,
                              StructuralType.NonStructural);

                    midpoint.Z = levelMiddle.Elevation;

                    FamilyInstance inst1
                        = createDoc.NewFamilyInstance(
                              midpoint, door, walls[4], levelMiddle,
                              StructuralType.NonStructural);
#endif // CREATE_TWO_LEVELS
                    #endregion // Test creating two levels

                    // Determine the levels where the walls will be located:

                    Level levelBottom = null;
                    Level levelTop    = null;

                    if (!LabUtils.GetBottomAndTopLevels(doc, ref levelBottom, ref levelTop))
                    {
                        message = "Unable to determine wall bottom and top levels";
                        return(Result.Failed);
                    }
                    Debug.Print(string.Format("Drawing walls on '{0}' up to '{1}'",
                                              levelBottom.Name, levelTop.Name));

                    // Create the walls:

                    BuiltInParameter topLevelParam = BuiltInParameter.WALL_HEIGHT_TYPE;
                    ElementId        levelBottomId = levelBottom.Id;
                    ElementId        topLevelId    = levelTop.Id;
                    List <Wall>      walls         = new List <Wall>(4);

                    for (int i = 0; i < 4; ++i)
                    {
                        Line line = Line.CreateBound(corners[i], corners[3 == i ? 0 : i + 1]);
                        //Wall wall = createDoc.NewWall( line, levelBottom, false ); // 2012
                        Wall      wall  = Wall.Create(doc, line, levelBottomId, false); // 2013
                        Parameter param = wall.get_Parameter(topLevelParam);
                        param.Set(topLevelId);
                        walls.Add(wall);
                    }

                    // Determine wall thickness for tag offset and profile growth:

                    //double wallThickness = walls[0].WallType.CompoundStructure.Layers.get_Item( 0 ).Thickness; // 2011
                    //double wallThickness = walls[0].WallType.GetCompoundStructure().GetLayers()[0].Width; // 2012
                    double wallThickness = walls[0].WallType.Width; // simpler and more direct property available in 2012

                    // Add door and windows to the first wall;
                    // note that the NewFamilyInstance() api method does not automatically add door
                    // and window tags, like the ui command does. we add tags here by making additional calls
                    // to NewTag():

                    FamilySymbol door = LabUtils.GetFirstFamilySymbol(doc, BuiltInCategory.OST_Doors);
                    if (null == door)
                    {
                        LabUtils.InfoMsg("No door symbol found.");
                        return(Result.Failed);
                    }
                    FamilySymbol window = LabUtils.GetFirstFamilySymbol(
                        doc, BuiltInCategory.OST_Windows);

                    if (null == window)
                    {
                        LabUtils.InfoMsg("No window symbol found.");
                        return(Result.Failed);
                    }

                    XYZ    midpoint  = LabUtils.Midpoint(corners[0], corners[1]);
                    XYZ    p         = LabUtils.Midpoint(corners[0], midpoint);
                    XYZ    q         = LabUtils.Midpoint(midpoint, corners[1]);
                    double tagOffset = 3 * wallThickness;

                    //double windowHeight = 1 * LabConstants.MeterToFeet;
                    double windowHeight = levelBottom.Elevation + 0.3 * (
                        levelTop.Elevation - levelBottom.Elevation);

                    p = new XYZ(p.X, p.Y, windowHeight);
                    q = new XYZ(q.X, q.Y, windowHeight);
                    View view = doc.ActiveView;

                    door.Activate(); // 2016

                    FamilyInstance inst = createDoc.NewFamilyInstance(
                        midpoint, door, walls[0], levelBottom, StructuralType.NonStructural);

                    midpoint += tagOffset * XYZ.BasisY;

                    //IndependentTag tag = createDoc.NewTag(
                    //  view, inst, false, TagMode.TM_ADDBY_CATEGORY,
                    //  TagOrientation.Horizontal, midpoint ); // 2017

                    IndependentTag tag = IndependentTag.Create(
                        doc, view.Id, new Reference(inst),
                        false, TagMode.TM_ADDBY_CATEGORY,
                        TagOrientation.Horizontal, midpoint); // 2018

                    IList <FamilyPointPlacementReference> fpprefs = inst.GetFamilyPointPlacementReferences();
                    IList <Reference> refs = inst.GetReferences(FamilyInstanceReferenceType.CenterLeftRight);

                    //IndependentTag tag = IndependentTag.Create( doc,
                    //  view.Id, refs[0], false, TagMode.TM_ADDBY_CATEGORY,
                    //  TagOrientation.Horizontal, midpoint ); // 2018

                    window.Activate(); // 2016

                    inst = createDoc.NewFamilyInstance(p, window,
                                                       walls[0], levelBottom, StructuralType.NonStructural);

                    p += tagOffset * XYZ.BasisY;

                    //tag = createDoc.NewTag( view, inst,
                    //  false, TagMode.TM_ADDBY_CATEGORY,
                    //  TagOrientation.Horizontal, p ); // 2017

                    tag = IndependentTag.Create(
                        doc, view.Id, new Reference(inst),
                        false, TagMode.TM_ADDBY_CATEGORY,
                        TagOrientation.Horizontal, p); // 2018

                    inst = createDoc.NewFamilyInstance(q, window, walls[0],
                                                       levelBottom, StructuralType.NonStructural);

                    q += tagOffset * XYZ.BasisY;

                    //tag = createDoc.NewTag( view, inst,
                    //  false, TagMode.TM_ADDBY_CATEGORY,
                    //  TagOrientation.TAG_HORIZONTAL, q ); // 2011

                    //tag = createDoc.NewTag( view, inst,
                    //  false, TagMode.TM_ADDBY_CATEGORY,
                    //  TagOrientation.Horizontal, q ); // 2012

                    tag = IndependentTag.Create(
                        doc, view.Id, new Reference(inst),
                        false, TagMode.TM_ADDBY_CATEGORY,
                        TagOrientation.Horizontal, p); // 2018

                    // Grow the profile out by half the wall thickness,
                    // so the floor and roof do not stop halfway through the wall:

                    double w = 0.5 * wallThickness;
                    corners[0] -= w * (XYZ.BasisX + XYZ.BasisY);
                    corners[1] += w * (XYZ.BasisX - XYZ.BasisY);
                    corners[2] += w * (XYZ.BasisX + XYZ.BasisY);
                    corners[3] -= w * (XYZ.BasisX - XYZ.BasisY);
                    CurveArray profile = new CurveArray();
                    for (int i = 0; i < 4; ++i)
                    {
                        //Line line = createApp.NewLineBound( // 2013

                        Line line = Line.CreateBound( // 2014
                            corners[i], corners[3 == i ? 0 : i + 1]);

                        profile.Append(line);
                    }

                    // Add a floor, a roof and the roof slope:

                    bool  structural = false;
                    Floor floor      = createDoc.NewFloor(
                        profile, structural);

                    List <Element> roofTypes
                        = new List <Element>(
                              LabUtils.GetElementsOfType(
                                  doc, typeof(RoofType),
                                  BuiltInCategory.OST_Roofs));

                    Debug.Assert(0 < roofTypes.Count,
                                 "expected at least one roof type"
                                 + " to be loaded into project");

                    // Ensure that we get a valid roof type.
                    // In Revit 2013, the first one encountered
                    // is sloped glazing with zero entries in
                    // its compound layers; actually, the entire
                    // compound structure is null:

                    //RoofType roofType = null;
                    //foreach( RoofType rt in roofTypes )
                    //{
                    //  CompoundStructure cs = rt.GetCompoundStructure();
                    //  if( null != cs
                    //    && 0 < cs.GetLayers().Count )
                    //  {
                    //    roofType = rt;
                    //    break;
                    //  }
                    //}

                    RoofType roofType = roofTypes
                                        .Cast <RoofType>()
                                        .FirstOrDefault <RoofType>(typ
                                                                   => null != typ.GetCompoundStructure());

                    ModelCurveArray modelCurves
                        = new ModelCurveArray();

                    FootPrintRoof roof
                        = createDoc.NewFootPrintRoof(profile,
                                                     levelTop, roofType, out modelCurves);

                    // Regenerate the model after roof creation,
                    // otherwise the calls to set_DefinesSlope and
                    // set_SlopeAngle throw the exception "Unable
                    // to access curves from the roof sketch."

                    doc.Regenerate();

                    // The argument to set_SlopeAngle is NOT an
                    // angle, it is really a slope, i.e. relation
                    // of height to distance, e.g. 0.5 = 6" / 12",
                    // 0.75  = 9" / 12", etc.

                    double slope = 0.3;

                    foreach (ModelCurve curve in modelCurves)
                    {
                        roof.set_DefinesSlope(curve, true);
                        roof.set_SlopeAngle(curve, slope);
                    }

                    // Add a room and a room tag:

                    Room room = createDoc.NewRoom(levelBottom,
                                                  new UV(0.5 * width, 0.5 * depth));

                    //RoomTag roomTag = createDoc.NewRoomTag(
                    //  room, new UV( 0.5 * width, 0.7 * depth ),
                    //  null ); // 2014

                    RoomTag roomTag = createDoc.NewRoomTag(
                        new LinkElementId(room.Id),
                        new UV(0.5 * width, 0.7 * depth),
                        null); // 2015

                    //doc.AutoJoinElements(); // todo: remove this, the transaction should perform this automatically

                    //LabUtils.InfoMsg( "Little house was created successfully." );

                    //#region Test setting BaseOffset and LimitOffset
                    //// 11334196 [Failed to set Room.BaseOffset and Room.LimitOffset properties]
                    //double h = 0.123;
                    //room.BaseOffset = -h;
                    //room.LimitOffset = h + h;
                    //#endregion // Test setting BaseOffset and LimitOffset

                    t.Commit();

                    return(Result.Succeeded);
                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
                return(Result.Failed);
            }
        }
예제 #3
0
        /// <summary>
        /// Revit external command to list all valid built-in parameters for a given selected element.
        /// </summary>
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document   doc   = uidoc.Document;

            Element e
                = LabUtils.GetSingleSelectedElementOrPrompt(
                      uidoc);

            if (null == e)
            {
                return(Result.Cancelled);
            }

            bool isSymbol = false;

            #region Check for FamilyInstance
#if CHECK_FOR_FAMILY_INSTANCE
            //
            // for a family instance, ask user whether to
            // display instance or type parameters;
            // in a similar manner, we could add dedicated
            // switches for Wall --> WallType,
            // Floor --> FloorType etc. ...
            //
            if (e is FamilyInstance)
            {
                FamilyInstance inst = e as FamilyInstance;
                if (null != inst.Symbol)
                {
                    string symbol_name
                        = LabUtils.ElementDescription(
                              inst.Symbol, true);

                    string family_name
                        = LabUtils.ElementDescription(
                              inst.Symbol.Family, true);

                    string msg =
                        "This element is a family instance, so it "
                        + "has both type and instance parameters. "
                        + "By default, the instance parameters are "
                        + "displayed. If you select 'No', the type "
                        + "parameters will be displayed instead. "
                        + "Would you like to see the instance "
                        + "parameters?";

                    if (!LabUtils.QuestionMsg(msg))
                    {
                        e        = inst.Symbol;
                        isSymbol = true;
                    }
                }
            }
#endif // CHECK_FOR_FAMILY_INSTANCE
            #endregion // Check for FamilyInstance

            #region Check for element type
#if CHECK_GET_TYPE_ID
            ElementId idType = e.GetTypeId();

            if (ElementId.InvalidElementId != idType)
            {
                // The selected element has a type; ask user
                // whether to display instance or type
                // parameters.

                ElementType typ = doc.GetElement(idType)
                                  as ElementType;

                Debug.Assert(null != typ,
                             "expected to retrieve a valid element type");

                string type_name = LabUtils.ElementDescription(
                    typ, true);

                string msg =
                    "This element has an ElementType, so it has "
                    + "both type and instance parameters. By "
                    + "default, the instance parameters are "
                    + "displayed. If you select 'No', the type "
                    + "parameters will be displayed instead. "
                    + "Would you like to see the instance "
                    + "parameters?";

                if (!LabUtils.QuestionMsg(msg))
                {
                    e        = typ;
                    isSymbol = true;
                }
            }
#endif // CHECK_GET_TYPE_ID
            #endregion // Check for element type

            SortableBindingList <ParameterData> data = new SortableBindingList <ParameterData>();
            {
                WaitCursor waitCursor = new WaitCursor();
                Array      bips       = Enum.GetValues(typeof(BuiltInParameter));
                int        n          = bips.Length;
                Parameter  p;
                foreach (BuiltInParameter a in bips)
                {
                    try
                    {
                        p = e.get_Parameter(a);

                        #region Check for external definition
#if CHECK_FOR_EXTERNAL_DEFINITION
                        Definition         d    = p.Definition;
                        ExternalDefinition e    = d as ExternalDefinition; // this is never possible
                        string             guid = (null == e) ? null : e.GUID.ToString();
#endif // CHECK_FOR_EXTERNAL_DEFINITION
                        #endregion // Check for external definition

                        if (null != p)
                        {
                            //string value = LabUtils.GetParameterValue2( p, doc );
                            string valueString = (StorageType.ElementId == p.StorageType)
                ? LabUtils.GetParameterValue2(p, doc)
                : p.AsValueString();

                            data.Add(new ParameterData(a, p, valueString));
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.Print("Exception retrieving built-in parameter {0}: {1}",
                                    a, ex);
                    }
                }
            }
            string description = LabUtils.ElementDescription(e, true)
                                 + (isSymbol
          ? " Type"
          : " Instance");

            using (BuiltInParamsCheckerForm form = new BuiltInParamsCheckerForm(description, data))
            {
                form.ShowDialog();
            }
            return(Result.Succeeded);
        }
예제 #4
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            #region 2.1.a. Access Revit doc and open output file:
            UIApplication app = commandData.Application;
            Document      doc = app.ActiveUIDocument.Document;

            // .NET exception handling should be done everywhere,
            // but will sometimes be omitted for clarity in the
            // following labs unless we expect exceptions:

            StreamWriter sw;

            try
            {
                sw = new StreamWriter(LabConstants.FilePath);
            }
            catch (Exception e)
            {
                LabUtils.ErrorMsg(string.Format("Cannot open '{0}': {1}",
                                                LabConstants.FilePath, e.Message));
                return(Result.Failed);
            }
            #endregion // 2.1.a. Access Revit doc and open output file

            try
            {
                WaitCursor waitCursor = new WaitCursor();

                #region 2.1.b. Set up element collector to retrieve all elements:
                // the Revit API does not expect an application
                // ever to need to iterate over all elements.
                // To do so, we need to use a trick: ask for all
                // elements fulfilling a specific criteria and
                // unite them with all elements NOT fulfilling
                // the same criteria:

                FilteredElementCollector collector
                    = new FilteredElementCollector(doc)
                      .WhereElementIsElementType();

                FilteredElementCollector collector2
                    = new FilteredElementCollector(doc)
                      .WhereElementIsNotElementType();

                collector.UnionWith(collector2);
                #endregion // 2.1.b. Set up element collector to retrieve all elements

                #region 2.1.c. Loop over the elements, list their data, and close the file:
                string s, line;

                foreach (Element e in collector)
                {
                    line  = "Id=" + e.Id.IntegerValue.ToString(); // element id
                    line += "; Class=" + e.GetType().Name;        // element class, i.e. System.Type

                    // The element category is not implemented for all classes,
                    // and may return null; for Family elements, one can sometimes
                    // use the FamilyCategory property instead.

                    s = string.Empty;

                    if (null != e.Category)
                    {
                        s = e.Category.Name;
                    }
                    if (0 == s.Length && e is Family && null != ((Family)e).FamilyCategory)
                    {
                        s = ((Family)e).FamilyCategory.Name;
                    }
                    if (0 == s.Length)
                    {
                        s = "?";
                    }
                    line += "; Category=" + s;

                    // The element Name has a different meaning for different classes,
                    // but is mostly implemented "logically". More precise info on elements
                    // can be obtained in class-specific ways.

                    line += "; Name=" + e.Name;
                    line += "; UniqueId=" + e.UniqueId;
                    //line += "; Guid=" + GetGuid( e.UniqueId );
                    sw.WriteLine(line);
                }
                sw.Close();

                LabUtils.InfoMsg("Element list has been written to "
                                 + LabConstants.FilePath + ".");

                #endregion // 2.1.c. Loop over the elements, list their data, and close the output file
            }
            catch (Exception e)
            {
                message = e.Message;
            }
            return(Result.Failed);
        }