Esempio n. 1
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
            Document      doc = app.ActiveUIDocument.Document;

            FilteredElementCollector rooms
                = new FilteredElementCollector(doc);

            //
            // this is one way of obtaining rooms ... but see below for a better solution:
            //
            //rooms.OfClass( typeof( Room ) ); // Input type is of an element type that exists in the API, but not in Revit's native object model. Try using Autodesk.Revit.DB.Enclosure instead, and then postprocessing the results to find the elements of interest.
            //rooms.OfClass( typeof( Enclosure ) ); // this works but returns all Enclosure elements

            RoomFilter filter = new RoomFilter();

            rooms.WherePasses(filter);

            if (0 == rooms.Count())
            {
                LabUtils.InfoMsg("There are no rooms in this model.");
            }
            else
            {
                List <string> a = new List <string>();

                /*
                 * foreach( Enclosure e in rooms ) // todo: remove this
                 * {
                 * Room room = e as Room; // todo: remove this
                 * if( null != room ) // todo: remove this
                 * {
                 */

                foreach (Room room in rooms)
                {
                    string roomName   = room.Name;
                    string roomNumber = room.Number;

                    string s = "Room Id=" + room.Id.IntegerValue.ToString()
                               + " Name=" + roomName + " Number=" + roomNumber + "\n";

                    // Loop all boundaries of this room

                    //BoundarySegmentArrayArray boundaries = room.Boundary; // 2011

                    IList <IList <BoundarySegment> > boundaries     // 2012
                        = room.GetBoundarySegments(                 // 2012
                              new SpatialElementBoundaryOptions()); // 2012; passing in a null value throws an exception

                    // Check to ensure room has boundary

                    if (null != boundaries)
                    {
                        int iB = 0;
                        //foreach( BoundarySegmentArray boundary in boundaries ) // 2011
                        foreach (IList <BoundarySegment> boundary in boundaries) // 2012
                        {
                            ++iB;
                            s += "  Boundary " + iB + ":\n";
                            int iSeg = 0;
                            foreach (BoundarySegment segment in boundary)
                            {
                                ++iSeg;

                                // Segment's curve
                                Curve crv = segment.GetCurve();

                                if (crv is Line)
                                {
                                    Line line = crv as Line;
                                    XYZ  ptS  = line.GetEndPoint(0);
                                    XYZ  ptE  = line.GetEndPoint(1);
                                    s += "    Segment " + iSeg + " is a LINE: "
                                         + LabUtils.PointString(ptS) + " ; "
                                         + LabUtils.PointString(ptE) + "\n";
                                }
                                else if (crv is Arc)
                                {
                                    Arc    arc = crv as Arc;
                                    XYZ    ptS = arc.GetEndPoint(0);
                                    XYZ    ptE = arc.GetEndPoint(1);
                                    double r   = arc.Radius;
                                    s += "    Segment " + iSeg + " is an ARC:"
                                         + LabUtils.PointString(ptS) + " ; "
                                         + LabUtils.PointString(ptE) + " ; R="
                                         + LabUtils.RealString(r) + "\n";
                                }
                            }
                        }
                        a.Add(s);
                    }
                    LabUtils.InfoMsg("{0} room{1} in the model{2}", a);
                }
            }
            return(Result.Failed);
        }
Esempio n. 2
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            //ElementSet ss = uidoc.Selection.Elements; // 2014
            ICollection <ElementId> ids = uidoc.Selection.GetElementIds();

            Wall wall = null;

            if (0 < ids.Count)
            {
                // old pre-selection handling:

                // must be one single element only:

                if (1 != ids.Count)
                {
                    message = "Please pre-select a single wall element.";
                    return(Result.Failed);
                }

                // must be a wall:

                //ElementSetIterator it = ss.ForwardIterator();
                //it.MoveNext();
                //Element e = it.Current as Element;

                ElementId id = ids.First <ElementId>();
                Element   e  = doc.GetElement(id);

                if (!(e is Wall))
                {
                    message = "Selected element is NOT a wall.";
                    return(Result.Failed);
                }
                wall = e as Wall;
            }
            else
            {
                // new prompt for filtered selection allowing only walls:

                try
                {
                    Reference r = uidoc.Selection.PickObject(
                        ObjectType.Element, new WallSelectionFilter(),
                        "Please pick a wall");

                    //wall = r.Element as Wall; // 2011
                    wall = uidoc.Document.GetElement(r) as Wall; // 2012
                }
                catch (OperationCanceledException)
                {
                    message = "Selection cancelled.";
                    return(Result.Cancelled);
                }
            }

            // wall must be constrained to a level at the top (more on parameters later):

            Level topLev = null;

            try
            {
                ElementId id = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
                topLev = doc.GetElement(id) as Level;
            }
            catch (Exception)
            {
                topLev = null;
            }

            if (null == topLev)
            {
                message = "Selected wall is not constrained to a level at the top.";
                return(Result.Failed);
            }

            // get the bottom level as well (this should never fail):

            Level botLev = null;

            try
            {
                ElementId id = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId();
                botLev = doc.GetElement(id) as Level;
            }
            catch (Exception)
            {
                botLev = null;
            }

            if (null == botLev)
            {
                message = "Selected wall is not constrained to a level at the bottom.";
                return(Result.Failed);
            }

            // Calculate the location points for the 3 columns (assuming straight wall)
            LocationCurve locCurve = wall.Location as LocationCurve;

            XYZ ptStart = locCurve.Curve.GetEndPoint(0);
            XYZ ptEnd   = locCurve.Curve.GetEndPoint(1);
            XYZ ptMid   = 0.5 * (ptStart + ptEnd);

            List <XYZ> locations = new List <XYZ>(3);

            locations.Add(ptStart);
            locations.Add(ptMid);
            locations.Add(ptEnd);

            string        s = "{0} location{1} for the new columns in raw database coordinates, e.g. feet{2}";
            List <string> a = new List <string>();

            a.Add("Start: " + LabUtils.PointString(ptStart));
            a.Add("Mid  : " + LabUtils.PointString(ptMid));
            a.Add("End  : " + LabUtils.PointString(ptEnd));
            LabUtils.InfoMsg(s, a);

            FilteredElementCollector collector = new FilteredElementCollector(doc);

            collector.OfCategory(BuiltInCategory.OST_Columns);
            collector.OfClass(typeof(FamilySymbol));

#if SEARCH_FOR_SPECIFIC_NAME
            // retrieve the family type for the new instances.
            // if needed, change the names to match a column
            // type available in the model:

            string family_name = "M_Wood Timber Column";
            string type_name   = "191 x 292mm";

            // LINQ query to find element with given name:
            //
            // ... note that this could also be achieved by
            // filtering for the element name parameter value.

            var column_types = from element in collector
                               //where ((FamilySymbol)element).Family.Name == family_name
                               where element.Name == type_name
                               select element;

            FamilySymbol symbol = null;

            try
            {
                symbol = column_types.Cast <FamilySymbol>().First <FamilySymbol>();
            }
            catch
            {
            }

            if (null == symbol)
            {
                message = string.Format(
                    "Cannot find type '{0}' in family '{1}' in the current model - please load it first.",
                    type_name, family_name);
                return(Result.Failed);
            }
#endif // SEARCH_FOR_SPECIFIC_NAME

            FamilySymbol symbol = collector.Cast <FamilySymbol>().First <FamilySymbol>();

            if (null == symbol)
            {
                message = "Cannot find a suitable column type.";
                return(Result.Failed);
            }

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Insert Columns and Move Wall");

                // insert column family instances:

                foreach (XYZ p in locations)
                {
                    try
                    {
                        // Note: Currently there is a problem.
                        // If we set the type as NonStructural, it is treated as Annotation instance,
                        // and it shows only in plan view.
                        // FamilyInstance column = doc.Create.NewFamilyInstance( p, symbol, botLev, StructuralType.NonStuctural );

                        FamilyInstance column = doc.Create.NewFamilyInstance(
                            p, symbol, botLev, StructuralType.Column);

                        Parameter paramTopLevel = column.get_Parameter(
                            BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);

                        ElementId id = topLev.Id;

                        paramTopLevel.Set(id);
                    }
                    catch (Exception)
                    {
                        LabUtils.ErrorMsg("Failed to create or adjust column.");
                    }
                }

                // Finally, move the wall so the columns are visible.
                // We move the wall perpendicularly to its location
                // curve by one tenth of its length:

                XYZ v = new XYZ(
                    -0.1 * (ptEnd.Y - ptStart.Y),
                    0.1 * (ptEnd.X - ptStart.X),
                    0);

                if (!wall.Location.Move(v))
                {
                    LabUtils.ErrorMsg("Failed to move the wall.");
                }
                tx.Commit();
            }
            return(Result.Succeeded);
        }