/// <summary>
        /// Return element bounding box centre point
        /// </summary>
        public XYZ GetElementBbCenter(Element e)
        {
            BoundingBoxXYZ bb     = e.get_BoundingBox(null);
            XYZ            center = Util.Midpoint(bb.Min, bb.Max);

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

            // obtain the current selection and pick
            // out all walls from it:

            //Selection sel = uidoc.Selection; // 2014

            ICollection <ElementId> ids = uidoc.Selection
                                          .GetElementIds(); // 2015

            List <Wall> walls = new List <Wall>(2);

            //foreach( Element e in sel.Elements ) // 2014

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

                if (e is Wall)
                {
                    walls.Add(e as Wall);
                }
            }

            if (2 != walls.Count)
            {
                message = _prompt;
                return(Result.Failed);
            }

            // ensure the two selected walls are straight and
            // parallel; determine their mutual normal vector
            // and a point on each wall for distance
            // calculations:

            List <Line> lines     = new List <Line>(2);
            List <XYZ>  midpoints = new List <XYZ>(2);
            XYZ         normal    = null;

            foreach (Wall wall in walls)
            {
                LocationCurve lc    = wall.Location as LocationCurve;
                Curve         curve = lc.Curve;

                if (!(curve is Line))
                {
                    message = _prompt;
                    return(Result.Failed);
                }

                Line l = curve as Line;
                lines.Add(l);
                midpoints.Add(Util.Midpoint(l));

                if (null == normal)
                {
                    normal = Util.Normal(l);
                }
                else
                {
                    if (!Util.IsParallel(normal, Util.Normal(l)))
                    {
                        message = _prompt;
                        return(Result.Failed);
                    }
                }
            }

            // find the two closest facing faces on the walls;
            // they are vertical faces that are parallel to the
            // wall curve and closest to the other wall.

            Options opt = app.Create.NewGeometryOptions();

            opt.ComputeReferences = true;

            List <Face> faces = new List <Face>(2);

            faces.Add(GetClosestFace(walls[0], midpoints[1], normal, opt));
            faces.Add(GetClosestFace(walls[1], midpoints[0], normal, opt));

            // create the dimensioning:

            CreateDimensionElement(doc.ActiveView,
                                   midpoints[0], faces[0].Reference,
                                   midpoints[1], faces[1].Reference);

            return(Result.Succeeded);
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
            Document      doc = app.ActiveUIDocument.Document;

            Autodesk.Revit.Creation.Application createApp
                = app.Application.Create;

            Autodesk.Revit.Creation.Document createDoc
                = doc.Create;

            // Determine the wall endpoints:

            double length = 5 * MeterToFeet;

            XYZ [] pts = new XYZ[2];

            pts[0] = XYZ.Zero;
            pts[1] = new XYZ(length, 0, 0);

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

            Level levelBottom = null;
            Level levelTop    = null;

            if (!GetBottomAndTopLevels(doc,
                                       ref levelBottom, ref levelTop))
            {
                message = "Unable to determine "
                          + "wall bottom and top levels";

                return(Result.Failed);
            }

            using (Transaction t = new Transaction(doc))
            {
                t.Start("Create Wall, Door and Tag");

                // Create a wall:

                BuiltInParameter topLevelParam
                    = BuiltInParameter.WALL_HEIGHT_TYPE;

                ElementId topLevelId = levelTop.Id;

                //Line line = createApp.NewLineBound( pts[0], pts[1] ); // 2013
                Line line = Line.CreateBound(pts[0], pts[1]); // 2014

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

                Wall wall = Wall.Create( // 2013
                    doc, line, levelBottom.Id, false);

                Parameter param = wall.get_Parameter(
                    topLevelParam);

                param.Set(topLevelId);

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

                //double wallThickness = wall.WallType.CompoundStructure.Layers.get_Item( 0 ).Thickness; // 2011

                double wallThickness = wall.WallType.GetCompoundStructure().GetLayers()[0].Width; // 2012

                // Add door to wall;
                // note that the NewFamilyInstance method
                // does not automatically add a door tag,
                // like the UI command does:

                FamilySymbol doorSymbol = GetFirstFamilySymbol(
                    doc, BuiltInCategory.OST_Doors);

                if (null == doorSymbol)
                {
                    message = "No door symbol found.";
                    return(Result.Failed);
                }

                XYZ midpoint = Util.Midpoint(pts[0], pts[1]);

                FamilyInstance door = createDoc
                                      .NewFamilyInstance(
                    midpoint, doorSymbol, wall, levelBottom,
                    StructuralType.NonStructural);

                // Create door tag:

                View view = doc.ActiveView;

                double tagOffset = 3 * wallThickness;

                midpoint += tagOffset * XYZ.BasisY;

                // 2011: TagOrientation.TAG_HORIZONTAL

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

                // Create and assign new door tag type:

                FamilySymbol doorTagType
                    = GetFirstFamilySymbol(
                          doc, BuiltInCategory.OST_DoorTags);

                doorTagType = doorTagType.Duplicate(
                    "New door tag type") as FamilySymbol;

                tag.ChangeTypeId(doorTagType.Id);

                // Demonstrate changing name of
                // family instance and family symbol:

                door.Name        = door.Name + " modified";
                door.Symbol.Name = door.Symbol.Name + " modified";

                t.Commit();
            }

            return(Result.Succeeded);
        }
        ///// <summary>
        ///// Allow selection of curve elements only.
        ///// </summary>
        //class CurveElementSelectionFilter : ISelectionFilter
        //{
        //  public bool AllowElement( Element e )
        //  {
        //    return e is CurveElement;
        //  }

        //  public bool AllowReference( Reference r, XYZ p )
        //  {
        //    return true;
        //  }
        //}

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

            // Select all model curves in the entire model.

            List <CurveElement> curves = new List <CurveElement>(
                new FilteredElementCollector(doc)
                .OfClass(typeof(CurveElement))
                .ToElements()
                .Cast <CurveElement>());

            int n = curves.Count;

            // If there are less than two,
            // there is nothing we can do.

            if (2 > n)
            {
                message = _prompt;
                return(Result.Failed);
            }

            // If there are exactly two, pick those.

            if (2 < n)
            {
                // Else, check for a pre-selection.

                curves.Clear();

                Selection sel = uidoc.Selection;
                ICollection <ElementId> ids = sel.GetElementIds();
                n = ids.Count;

                Debug.Print("{0} pre-selected elements.",
                            n);

                // If two or more model curves were pre-
                // selected, use the first two encountered.

                if (1 < n)
                {
                    foreach (ElementId id in ids)
                    {
                        CurveElement c = doc.GetElement(id)
                                         as CurveElement;

                        if (null != c)
                        {
                            curves.Add(c);

                            if (2 == curves.Count)
                            {
                                Debug.Print("Found two model curves, "
                                            + "ignoring everything else.");

                                break;
                            }
                        }
                    }
                }

                // Else, prompt for an
                // interactive post-selection.

                if (2 != curves.Count)
                {
                    curves.Clear();

                    ISelectionFilter f
                        = new JtElementsOfClassSelectionFilter <CurveElement>();

                    try
                    {
                        Reference r = sel.PickObject(
                            ObjectType.Element, f,
                            "Please pick first model curve.");

                        curves.Add(doc.GetElement(r.ElementId)
                                   as CurveElement);
                    }
                    catch (Autodesk.Revit.Exceptions
                           .OperationCanceledException)
                    {
                        return(Result.Cancelled);
                    }

                    try
                    {
                        Reference r = sel.PickObject(
                            ObjectType.Element, f,
                            "Please pick second model curve.");

                        curves.Add(doc.GetElement(r.ElementId)
                                   as CurveElement);
                    }
                    catch (Autodesk.Revit.Exceptions
                           .OperationCanceledException)
                    {
                        return(Result.Cancelled);
                    }
                }
            }

            // Extract data from the two selected curves.

            Curve c0 = curves[0].GeometryCurve;
            Curve c1 = curves[1].GeometryCurve;

            double sp0   = c0.GetEndParameter(0);
            double ep0   = c0.GetEndParameter(1);
            double step0 = (ep0 - sp0) / _nSegments;

            double sp1   = c1.GetEndParameter(0);
            double ep1   = c1.GetEndParameter(1);
            double step1 = (ep1 - sp1) / _nSegments;

            Debug.Print("Two curves' step size [start, end]:"
                        + " {0} [{1},{2}] -- {3} [{4},{5}]",
                        Util.RealString(step0),
                        Util.RealString(sp0),
                        Util.RealString(ep0),
                        Util.RealString(step1),
                        Util.RealString(sp1),
                        Util.RealString(ep1));

            // Modify document within a transaction.

            using (Transaction tx = new Transaction(doc))
            {
                Creator creator = new Creator(doc);

                tx.Start("MidCurve");

                // Current segment start points.

                double t0 = sp0;
                double t1 = sp1;

                XYZ p0 = c0.GetEndPoint(0);
                XYZ p1 = c1.GetEndPoint(0);
                XYZ p  = Util.Midpoint(p0, p1);

                Debug.Assert(
                    p0.IsAlmostEqualTo(c0.Evaluate(t0, false)),
                    "expected equal start points");

                Debug.Assert(
                    p1.IsAlmostEqualTo(c1.Evaluate(t1, false)),
                    "expected equal start points");

                // Current segment end points.

                t0 += step0;
                t1 += step1;

                XYZ  q0, q1, q;
                Line line;

                for (int i = 0; i < _nSegments; ++i, t0 += step0, t1 += step1)
                {
                    q0 = c0.Evaluate(t0, false);
                    q1 = c1.Evaluate(t1, false);
                    q  = Util.Midpoint(q0, q1);

                    Debug.Print(
                        "{0} {1} {2} {3}-{4} {5}-{6} {7}-{8}",
                        i,
                        Util.RealString(t0),
                        Util.RealString(t1),
                        Util.PointString(p0),
                        Util.PointString(q0),
                        Util.PointString(p1),
                        Util.PointString(q1),
                        Util.PointString(p),
                        Util.PointString(q));

                    // Create approximating curve segment.

                    line = Line.CreateBound(p, q);
                    creator.CreateModelCurve(line);

                    p0 = q0;
                    p1 = q1;
                    p  = q;
                }
                tx.Commit();
            }
            return(Result.Succeeded);
        }